style: 章节,作业部分页面
This commit is contained in:
parent
1193c017ee
commit
8ce7c66fea
BIN
public/images/teacher/发布人.png
Normal file
BIN
public/images/teacher/发布人.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 831 B |
BIN
public/images/teacher/起点时间.png
Normal file
BIN
public/images/teacher/起点时间.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 668 B |
@ -43,7 +43,6 @@ import CourseCreate from '@/components/admin/CourseComponents/CourseCreate.vue'
|
||||
import CourseEditor from '@/views/teacher/course/CourseEditor.vue'
|
||||
import CoursewareManagement from '@/views/teacher/course/CoursewareManagement.vue'
|
||||
import ChapterManagement from '@/views/teacher/course/ChapterManagement.vue'
|
||||
import HomeworkManagement from '@/views/teacher/course/HomeworkManagement.vue'
|
||||
import PracticeManagement from '@/views/teacher/course/PracticeManagement.vue'
|
||||
import QuestionBankManagement from '@/views/teacher/course/QuestionBankManagement.vue'
|
||||
import CertificateManagement from '@/views/teacher/course/CertificateManagement.vue'
|
||||
@ -52,6 +51,10 @@ import StatisticsManagement from '@/views/teacher/course/StatisticsManagement.vu
|
||||
import NotificationManagement from '@/views/teacher/course/NotificationManagement.vue'
|
||||
import GeneralManagement from '@/views/teacher/course/GeneralManagement.vue'
|
||||
|
||||
// 作业管理子组件
|
||||
import HomeworkLibrary from '@/views/teacher/course/HomeworkLibrary.vue'
|
||||
import HomeworkReview from '@/views/teacher/course/HomeworkReview.vue'
|
||||
|
||||
// ========== 路由配置 ==========
|
||||
const routes: RouteRecordRaw[] = [
|
||||
// 管理后台路由
|
||||
@ -125,8 +128,21 @@ const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: 'homework',
|
||||
name: 'HomeworkManagement',
|
||||
component: HomeworkManagement,
|
||||
meta: { title: '作业管理' }
|
||||
redirect: (to) => `/teacher/course-editor/${to.params.id}/homework/library`,
|
||||
children: [
|
||||
{
|
||||
path: 'library',
|
||||
name: 'HomeworkLibrary',
|
||||
component: HomeworkLibrary,
|
||||
meta: { title: '作业库' }
|
||||
},
|
||||
{
|
||||
path: 'review',
|
||||
name: 'HomeworkReview',
|
||||
component: HomeworkReview,
|
||||
meta: { title: '批阅作业' }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'practice',
|
||||
|
@ -129,13 +129,13 @@ const navigateToTeacherDetail = (teacherId: number) => {
|
||||
}
|
||||
|
||||
// 处理箭头点击
|
||||
const toggleCourseInfo = (teacherId: number) => {
|
||||
if (expandedTeacherId.value === teacherId) {
|
||||
expandedTeacherId.value = null
|
||||
} else {
|
||||
expandedTeacherId.value = teacherId
|
||||
}
|
||||
}
|
||||
// const toggleCourseInfo = (teacherId: number) => {
|
||||
// if (expandedTeacherId.value === teacherId) {
|
||||
// expandedTeacherId.value = null
|
||||
// } else {
|
||||
// expandedTeacherId.value = teacherId
|
||||
// }
|
||||
// }
|
||||
|
||||
// 鼠标悬停显示课程信息
|
||||
const showCourseInfo = (teacherId: number) => {
|
||||
@ -143,7 +143,7 @@ const showCourseInfo = (teacherId: number) => {
|
||||
}
|
||||
|
||||
// 鼠标离开隐藏课程信息
|
||||
const hideCourseInfo = (teacherId: number) => {
|
||||
const hideCourseInfo = (_: number) => {
|
||||
expandedTeacherId.value = null
|
||||
}
|
||||
|
||||
|
@ -1,36 +1,786 @@
|
||||
<template>
|
||||
<div class="chapter-management">
|
||||
<div class="content-placeholder">
|
||||
<h2>章节管理</h2>
|
||||
<p>章节管理功能正在开发中...</p>
|
||||
<!-- 顶部操作栏 -->
|
||||
<div class="toolbar">
|
||||
<h2>全部章节</h2>
|
||||
<div class="toolbar-actions">
|
||||
<button class="btn btn-primary" @click="addChapter">添加章节</button>
|
||||
<button class="btn btn-new" @click="importChapters">导入</button>
|
||||
<button class="btn btn-new" @click="exportChapters">导出</button>
|
||||
<button class="btn btn-danger" @click="deleteSelected" :disabled="selectedChapters.length === 0">删除</button>
|
||||
<div class="search-box">
|
||||
<input type="text" placeholder="请输入想要搜索的内容" v-model="searchKeyword" />
|
||||
<button class="btn btn-search" @click="searchChapters">搜索</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 章节列表表格 -->
|
||||
<div class="table-box">
|
||||
<n-config-provider :locale="zhCN" :date-locale="dateZhCN">
|
||||
<n-data-table :columns="columns" :data="paginatedChapters" :row-key="rowKey"
|
||||
:checked-row-keys="selectedChapters" @update:checked-row-keys="handleCheck" :bordered="false"
|
||||
:single-line="false" size="medium" class="chapter-data-table" :row-class-name="rowClassName" />
|
||||
</n-config-provider>
|
||||
|
||||
<!-- 自定义分页器 -->
|
||||
<div class="custom-pagination">
|
||||
<div class="pagination-content">
|
||||
<div class="page-numbers">
|
||||
<span class="page-number nav-button" :class="{ disabled: currentPage === 1 }" @click="goToPage('first')">
|
||||
首页
|
||||
</span>
|
||||
<span class="page-number nav-button" :class="{ disabled: currentPage === 1 }" @click="goToPage('prev')">
|
||||
上一页
|
||||
</span>
|
||||
|
||||
<span v-for="page in visiblePages" :key="page" class="page-number page-number-bordered"
|
||||
:class="{ active: page === currentPage }" @click="goToPage(page)">
|
||||
{{ page }}
|
||||
</span>
|
||||
|
||||
<span v-if="showRightEllipsis" class="page-number">...</span>
|
||||
<span v-if="totalPages > 1" class="page-number page-number-bordered" @click="goToPage(totalPages)">
|
||||
{{ totalPages }}
|
||||
</span>
|
||||
|
||||
<span class="page-number nav-button" :class="{ disabled: currentPage === totalPages }"
|
||||
@click="goToPage('next')">
|
||||
下一页
|
||||
</span>
|
||||
<span class="page-number nav-button" :class="{ disabled: currentPage === totalPages }"
|
||||
@click="goToPage('last')">
|
||||
尾页
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 章节管理逻辑
|
||||
import { ref, computed, h } from 'vue'
|
||||
import { NButton, useMessage, NDataTable, NConfigProvider, zhCN, dateZhCN } from 'naive-ui'
|
||||
import type { DataTableColumns } from 'naive-ui'
|
||||
|
||||
const message = useMessage()
|
||||
|
||||
// 章节类型定义
|
||||
interface Chapter {
|
||||
id: number
|
||||
name: string
|
||||
type: string
|
||||
sort: string | number
|
||||
createTime: string
|
||||
isParent: boolean
|
||||
children?: Chapter[]
|
||||
expanded?: boolean
|
||||
}
|
||||
|
||||
// 搜索关键词
|
||||
const searchKeyword = ref('')
|
||||
|
||||
// 选中的章节
|
||||
const selectedChapters = ref<number[]>([])
|
||||
|
||||
// 章节列表数据
|
||||
const chapterList = ref<Chapter[]>([
|
||||
{
|
||||
id: 1,
|
||||
name: '第一章 课前准备',
|
||||
type: '-',
|
||||
sort: '-',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: true,
|
||||
expanded: false,
|
||||
children: [
|
||||
{
|
||||
id: 2,
|
||||
name: '开课彩蛋:新开始新征程',
|
||||
type: '视频',
|
||||
sort: 1,
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: false
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '课件准备PPT',
|
||||
type: '课件',
|
||||
sort: 2,
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '第一节 课程定位与目标',
|
||||
type: '视频',
|
||||
sort: 3,
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: false
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '第二节 教学安排及学习建议',
|
||||
type: '作业',
|
||||
sort: 4,
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: false
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: '第三节 教学安排及学习建议',
|
||||
type: '考试',
|
||||
sort: 5,
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: '第二章 课前准备',
|
||||
type: '-',
|
||||
sort: '-',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: true,
|
||||
expanded: false,
|
||||
children: [
|
||||
{
|
||||
id: 8,
|
||||
name: '第一节 新开始新征程',
|
||||
type: '视频',
|
||||
sort: 1,
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: false
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: '第二节 教学安排及学习建议',
|
||||
type: '课件',
|
||||
sort: 2,
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: '第三章 课前准备',
|
||||
type: '-',
|
||||
sort: '-',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: true,
|
||||
expanded: false,
|
||||
children: [
|
||||
{
|
||||
id: 12,
|
||||
name: '第一节 新开始新征程',
|
||||
type: '视频',
|
||||
sort: 1,
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: false
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
name: '第二节 教学安排及学习建议',
|
||||
type: '课件',
|
||||
sort: 2,
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
name: '第四章 课前准备',
|
||||
type: '-',
|
||||
sort: '-',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isParent: true,
|
||||
expanded: false,
|
||||
children: []
|
||||
}
|
||||
])
|
||||
|
||||
// 扁平化章节列表(用于显示和分页)
|
||||
const flattenedChapters = computed(() => {
|
||||
const result: Chapter[] = []
|
||||
|
||||
const flatten = (chapters: Chapter[]) => {
|
||||
chapters.forEach(chapter => {
|
||||
result.push(chapter)
|
||||
if (chapter.children && chapter.expanded) {
|
||||
flatten(chapter.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
flatten(chapterList.value)
|
||||
return result
|
||||
})
|
||||
|
||||
// 过滤后的章节列表
|
||||
const filteredChapters = computed(() => {
|
||||
if (!searchKeyword.value) {
|
||||
return flattenedChapters.value
|
||||
}
|
||||
return flattenedChapters.value.filter((chapter: Chapter) =>
|
||||
chapter.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||
)
|
||||
})
|
||||
|
||||
// 分页相关状态
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const totalPages = computed(() => Math.ceil(filteredChapters.value.length / pageSize.value))
|
||||
|
||||
// 可见的页码范围
|
||||
const visiblePages = computed(() => {
|
||||
const pages = []
|
||||
const current = currentPage.value
|
||||
const total = totalPages.value
|
||||
|
||||
if (total <= 7) {
|
||||
// 如果总页数小于等于7,显示所有页码
|
||||
for (let i = 1; i <= total; i++) {
|
||||
pages.push(i)
|
||||
}
|
||||
} else {
|
||||
// 显示当前页附近的页码
|
||||
const start = Math.max(1, current - 2)
|
||||
const end = Math.min(total, current + 2)
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i)
|
||||
}
|
||||
}
|
||||
|
||||
return pages
|
||||
})
|
||||
|
||||
// 是否显示右侧省略号
|
||||
const showRightEllipsis = computed(() => {
|
||||
return currentPage.value < totalPages.value - 3
|
||||
})
|
||||
|
||||
// 分页后的数据
|
||||
const paginatedChapters = computed(() => {
|
||||
const start = (currentPage.value - 1) * pageSize.value
|
||||
const end = start + pageSize.value
|
||||
return filteredChapters.value.slice(start, end)
|
||||
})
|
||||
|
||||
// 表格行键
|
||||
const rowKey = (row: Chapter) => row.id
|
||||
|
||||
// 表格选择处理
|
||||
const handleCheck = (rowKeys: number[]) => {
|
||||
selectedChapters.value = rowKeys
|
||||
}
|
||||
|
||||
// 行样式名称
|
||||
const rowClassName = () => {
|
||||
return 'chapter-table-row'
|
||||
}
|
||||
|
||||
// 获取章节图标
|
||||
// const getChapterIcon = (type: string) => {
|
||||
// return '/images/teacher/章节.png'
|
||||
// }
|
||||
|
||||
// 获取类型图标
|
||||
// const getTypeIcon = (type: string) => {
|
||||
// const iconMap: { [key: string]: string } = {
|
||||
// '视频': '/images/teacher/视频.png',
|
||||
// '课件': '/images/teacher/课件.png',
|
||||
// '作业': '/images/teacher/作业.png',
|
||||
// '考试': '/images/teacher/考试.png'
|
||||
// }
|
||||
// return iconMap[type] || '/images/teacher/默认.png'
|
||||
// }
|
||||
|
||||
// 分页方法
|
||||
const goToPage = (page: string | number) => {
|
||||
if (typeof page === 'string') {
|
||||
switch (page) {
|
||||
case 'first':
|
||||
currentPage.value = 1
|
||||
break
|
||||
case 'prev':
|
||||
if (currentPage.value > 1) currentPage.value--
|
||||
break
|
||||
case 'next':
|
||||
if (currentPage.value < totalPages.value) currentPage.value++
|
||||
break
|
||||
case 'last':
|
||||
currentPage.value = totalPages.value
|
||||
break
|
||||
}
|
||||
} else {
|
||||
currentPage.value = page
|
||||
}
|
||||
}
|
||||
|
||||
// 展开/收起章节
|
||||
const toggleChapter = (chapter: Chapter) => {
|
||||
if (chapter.isParent && chapter.children) {
|
||||
chapter.expanded = !chapter.expanded
|
||||
}
|
||||
}
|
||||
|
||||
// 章节操作方法
|
||||
const addChapter = () => {
|
||||
message.info('添加章节功能')
|
||||
}
|
||||
|
||||
const importChapters = () => {
|
||||
message.info('导入章节功能')
|
||||
}
|
||||
|
||||
const exportChapters = () => {
|
||||
message.info('导出章节功能')
|
||||
}
|
||||
|
||||
const deleteSelected = () => {
|
||||
if (selectedChapters.value.length === 0) return
|
||||
if (confirm(`确定要删除选中的 ${selectedChapters.value.length} 个章节吗?`)) {
|
||||
selectedChapters.value.forEach((id: number) => {
|
||||
const index = chapterList.value.findIndex((c: Chapter) => c.id === id)
|
||||
if (index > -1) {
|
||||
chapterList.value.splice(index, 1)
|
||||
}
|
||||
})
|
||||
selectedChapters.value = []
|
||||
message.success('删除成功')
|
||||
}
|
||||
}
|
||||
|
||||
const searchChapters = () => {
|
||||
message.info('搜索章节: ' + searchKeyword.value)
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
const editChapter = (chapter: Chapter) => {
|
||||
message.info('编辑章节: ' + chapter.name)
|
||||
}
|
||||
|
||||
const deleteChapter = (chapter: Chapter) => {
|
||||
if (confirm('确定要删除这个章节吗?')) {
|
||||
const index = chapterList.value.findIndex((c: Chapter) => c.id === chapter.id)
|
||||
if (index > -1) {
|
||||
chapterList.value.splice(index, 1)
|
||||
message.success('删除成功')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格列配置
|
||||
const columns: DataTableColumns<Chapter> = [
|
||||
{
|
||||
type: 'selection'
|
||||
},
|
||||
{
|
||||
title: '章节名称',
|
||||
key: 'name',
|
||||
minWidth: 350,
|
||||
render: (row: Chapter) => {
|
||||
return h('div', {
|
||||
style: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '20px',
|
||||
cursor: row.isParent ? 'pointer' : 'default',
|
||||
marginLeft: row.isParent ? '40px' : '12px'
|
||||
},
|
||||
onClick: row.isParent ? () => toggleChapter(row) : undefined
|
||||
}, [
|
||||
row.isParent ? h('i', {
|
||||
class: 'n-base-icon',
|
||||
style: {
|
||||
transition: 'transform 0.2s',
|
||||
transform: row.expanded ? 'rotate(90deg)' : 'rotate(0deg)',
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}, [
|
||||
h('svg', {
|
||||
viewBox: '0 0 16 16',
|
||||
fill: 'none',
|
||||
xmlns: 'http://www.w3.org/2000/svg'
|
||||
}, [
|
||||
h('path', {
|
||||
d: 'M5.64645 3.14645C5.45118 3.34171 5.45118 3.65829 5.64645 3.85355L9.79289 8L5.64645 12.1464C5.45118 12.3417 5.45118 12.6583 5.64645 12.8536C5.84171 13.0488 6.15829 13.0488 6.35355 12.8536L10.8536 8.35355C11.0488 8.15829 11.0488 7.84171 10.8536 7.64645L6.35355 3.14645C6.15829 2.95118 5.84171 2.95118 5.64645 3.14645Z',
|
||||
fill: 'currentColor'
|
||||
})
|
||||
])
|
||||
]) : h('div', { style: { width: '16px' } }),
|
||||
h('span', {
|
||||
style: {
|
||||
color: row.isParent ? '#062333' : '#666666',
|
||||
fontSize: '14px',
|
||||
fontWeight: row.isParent ? '500' : 'normal',
|
||||
marginLeft: row.isParent ? '0' : '24px'
|
||||
}
|
||||
}, row.name)
|
||||
])
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
key: 'type',
|
||||
width: 156,
|
||||
render: (row: Chapter) => {
|
||||
if (row.type === '-') {
|
||||
return h('span', { style: { color: '#BABABA' } }, '-')
|
||||
}
|
||||
return h('div', {
|
||||
style: {
|
||||
display: 'inline-block',
|
||||
padding: '4px 8px',
|
||||
backgroundColor: 'transparent',
|
||||
border: '1px solid #BABABA',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
color: '#BABABA'
|
||||
}
|
||||
}, row.type)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
key: 'sort',
|
||||
width: 120,
|
||||
render: (row: Chapter) => {
|
||||
return h('span', { style: { color: '#062333', fontSize: '12px' } }, row.sort)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime',
|
||||
width: 235,
|
||||
render: (row: Chapter) => {
|
||||
return h('span', { style: { color: '#062333', fontSize: '12px' } }, row.createTime)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'actions',
|
||||
width: 200,
|
||||
render: (row: Chapter) => {
|
||||
return h('div', { style: { display: 'flex', gap: '16px', alignItems: 'center', justifyContent: 'center' } }, [
|
||||
h(NButton, {
|
||||
size: 'small',
|
||||
type: 'info',
|
||||
secondary: true,
|
||||
onClick: () => editChapter(row)
|
||||
}, { default: () => '编辑' }),
|
||||
h(NButton, {
|
||||
size: 'small',
|
||||
type: 'error',
|
||||
secondary: true,
|
||||
onClick: () => deleteChapter(row)
|
||||
}, { default: () => '删除' })
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.chapter-management {
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
width: 1293px;
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* 顶部工具栏 */
|
||||
.toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-right: 25px;
|
||||
background: #fff;
|
||||
padding: 30px 0 20px 30px;
|
||||
border-bottom: 2px solid #F6F6F6;
|
||||
}
|
||||
|
||||
.toolbar h2 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.toolbar-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 7px 16px;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #0288D1;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #40a9ff;
|
||||
}
|
||||
|
||||
.btn-new {
|
||||
background-color: #fff;
|
||||
border: 1px solid #0288D1;
|
||||
color: #0288D1;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
background: white;
|
||||
color: #999999;
|
||||
border: 1px solid #999999;
|
||||
}
|
||||
|
||||
.btn-default:hover {
|
||||
border-color: #1890ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: white;
|
||||
color: #FF4D4F;
|
||||
border: 1px solid #FF4D4F;
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
background: #ff7875;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid #F1F3F4;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.search-box input {
|
||||
border: none;
|
||||
padding: 6px 12px;
|
||||
outline: none;
|
||||
width: 200px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.btn-search {
|
||||
background: #0288D1;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 6px 16px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.btn-search:hover {
|
||||
background: #0277bd;
|
||||
}
|
||||
|
||||
.table-box {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Naive UI 表格样式定制 */
|
||||
:deep(.chapter-data-table) {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 40px;
|
||||
height: 100%;
|
||||
min-height: 500px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 表格头部样式 */
|
||||
:deep(.chapter-data-table .n-data-table-thead) {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
:deep(.chapter-data-table .n-data-table-th) {
|
||||
background: #fafafa;
|
||||
font-weight: 500;
|
||||
color: #062333;
|
||||
font-size: 14px;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
padding: 12px 8px;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
|
||||
/* 表格行样式 */
|
||||
:deep(.chapter-data-table .n-data-table-td) {
|
||||
font-size: 13px;
|
||||
color: #062333;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 12px 8px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 所有列居中对齐 */
|
||||
:deep(.chapter-data-table .n-data-table-td) {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
:deep(.chapter-data-table .n-data-table-th) {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
:deep(.chapter-data-table .n-data-table-tr:hover) {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
/* 复选框样式 */
|
||||
:deep(.chapter-data-table .n-checkbox) {
|
||||
--n-size: 16px;
|
||||
}
|
||||
|
||||
/* 隐藏Naive UI默认的展开触发器 */
|
||||
:deep(.chapter-data-table .n-data-table-expand-trigger) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 隐藏Naive UI默认的展开占位符 */
|
||||
:deep(.chapter-data-table .n-data-table-expand-placeholder) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 按钮组样式调整 */
|
||||
:deep(.chapter-data-table .n-button) {
|
||||
font-size: 12px;
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
/* 操作按钮样式 - 只有边框和文字颜色,无背景色 */
|
||||
:deep(.chapter-data-table .n-button--info-type.n-button--secondary) {
|
||||
background-color: transparent !important;
|
||||
border: 1px solid #0288D1;
|
||||
color: #0288D1;
|
||||
}
|
||||
|
||||
:deep(.chapter-data-table .n-button--info-type.n-button--secondary:hover) {
|
||||
background-color: rgba(32, 128, 240, 0.05) !important;
|
||||
border: 1px solid #0288D1;
|
||||
color: #248DD3;
|
||||
}
|
||||
|
||||
:deep(.chapter-data-table .n-button--error-type.n-button--secondary) {
|
||||
background-color: transparent !important;
|
||||
border: 1px solid #FF4D4F;
|
||||
color: #FD8485;
|
||||
}
|
||||
|
||||
:deep(.chapter-data-table .n-button--error-type.n-button--secondary:hover) {
|
||||
background-color: rgba(208, 48, 80, 0.05) !important;
|
||||
border: 1px solid #FF4D4F;
|
||||
color: #FD8485;
|
||||
}
|
||||
|
||||
/* 表格行样式 */
|
||||
:deep(.chapter-table-row) {
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
:deep(.chapter-table-row:hover) {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
/* 自定义分页器样式 */
|
||||
.custom-pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background: #fff;
|
||||
padding: 20px 0;
|
||||
margin-top: auto;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.pagination-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0 auto;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.page-numbers {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
display: inline-block;
|
||||
min-width: 38px;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
padding: 0 5px;
|
||||
margin: 0 4px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.page-number-bordered {
|
||||
border: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
.page-number.active {
|
||||
background-color: #0088D1;
|
||||
color: white;
|
||||
border-color: #0088D1;
|
||||
}
|
||||
|
||||
.page-number:hover:not(.disabled) {
|
||||
color: #0088D1;
|
||||
border-color: #0088D1;
|
||||
}
|
||||
|
||||
.page-number.disabled {
|
||||
color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.page-number.disabled:hover {
|
||||
color: #ccc;
|
||||
border-color: #d9d9d9;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
padding: 0 8px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.content-placeholder {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
}
|
||||
|
||||
.content-placeholder h2 {
|
||||
font-size: 24px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.content-placeholder p {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
.nav-button:hover:not(.disabled) {
|
||||
color: #0088D1;
|
||||
}
|
||||
</style>
|
||||
|
@ -2,114 +2,83 @@
|
||||
<div class="course-editor">
|
||||
<!-- 左侧导航菜单 -->
|
||||
<div class="sidebar">
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/courseware`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('courseware') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('courseware') ? '/images/teacher/课件-选中.png' : '/images/teacher/课件.png'"
|
||||
alt="课件"
|
||||
/>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/courseware`" class="menu-item"
|
||||
:class="{ active: $route.path.includes('courseware') }">
|
||||
<img :src="$route.path.includes('courseware') ? '/images/teacher/课件-选中.png' : '/images/teacher/课件.png'"
|
||||
alt="课件" />
|
||||
<span>课件</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/chapters`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('chapters') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('chapters') ? '/images/teacher/章节-选中.png' : '/images/teacher/章节.png'"
|
||||
alt="章节"
|
||||
/>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/chapters`" class="menu-item"
|
||||
:class="{ active: $route.path.includes('chapters') }">
|
||||
<img :src="$route.path.includes('chapters') ? '/images/teacher/章节-选中.png' : '/images/teacher/章节.png'"
|
||||
alt="章节" />
|
||||
<span>章节</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/homework`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('homework') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('homework') ? '/images/teacher/作业-选中.png' : '/images/teacher/作业.png'"
|
||||
alt="作业"
|
||||
/>
|
||||
<span>作业</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/practice`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('practice') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('practice') ? '/images/teacher/练考通-选中.png' : '/images/teacher/练考通.png'"
|
||||
alt="练考通"
|
||||
/>
|
||||
<!-- 作业二级导航 -->
|
||||
<div class="menu-group">
|
||||
<div class="menu-header" @click="toggleHomework">
|
||||
<img :src="$route.path.includes('homework') ? '/images/teacher/作业-选中.png' : '/images/teacher/作业.png'"
|
||||
alt="作业" />
|
||||
<span>作业</span>
|
||||
<i class="n-base-icon" :class="{ 'expanded': homeworkExpanded }">
|
||||
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M5.64645 3.14645C5.45118 3.34171 5.45118 3.65829 5.64645 3.85355L9.79289 8L5.64645 12.1464C5.45118 12.3417 5.45118 12.6583 5.64645 12.8536C5.84171 13.0488 6.15829 13.0488 6.35355 12.8536L10.8536 8.35355C11.0488 8.15829 11.0488 7.84171 10.8536 7.64645L6.35355 3.14645C6.15829 2.95118 5.84171 2.95118 5.64645 3.14645Z"
|
||||
fill="#C2C2C2"></path>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
<div class="submenu" v-show="homeworkExpanded">
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/homework/library`" class="submenu-item"
|
||||
:class="{ active: $route.path.includes('homework/library') }">
|
||||
<span>作业库</span>
|
||||
</router-link>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/homework/review`" class="submenu-item"
|
||||
:class="{ active: $route.path.includes('homework/review') }">
|
||||
<span>批阅作业</span>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/practice`" class="menu-item"
|
||||
:class="{ active: $route.path.includes('practice') }">
|
||||
<img :src="$route.path.includes('practice') ? '/images/teacher/练考通-选中.png' : '/images/teacher/练考通.png'"
|
||||
alt="练考通" />
|
||||
<span>练考通</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/question-bank`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('question-bank') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('question-bank') ? '/images/teacher/题库-选中.png' : '/images/teacher/题库.png'"
|
||||
alt="题库"
|
||||
/>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/question-bank`" class="menu-item"
|
||||
:class="{ active: $route.path.includes('question-bank') }">
|
||||
<img :src="$route.path.includes('question-bank') ? '/images/teacher/题库-选中.png' : '/images/teacher/题库.png'"
|
||||
alt="题库" />
|
||||
<span>题库</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/certificate`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('certificate') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('certificate') ? '/images/teacher/证书-选中.png' : '/images/teacher/证书.png'"
|
||||
alt="证书"
|
||||
/>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/certificate`" class="menu-item"
|
||||
:class="{ active: $route.path.includes('certificate') }">
|
||||
<img :src="$route.path.includes('certificate') ? '/images/teacher/证书-选中.png' : '/images/teacher/证书.png'"
|
||||
alt="证书" />
|
||||
<span>证书</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/discussion`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('discussion') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('discussion') ? '/images/teacher/讨论-选中.png' : '/images/teacher/讨论.png'"
|
||||
alt="讨论"
|
||||
/>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/discussion`" class="menu-item"
|
||||
:class="{ active: $route.path.includes('discussion') }">
|
||||
<img :src="$route.path.includes('discussion') ? '/images/teacher/讨论-选中.png' : '/images/teacher/讨论.png'"
|
||||
alt="讨论" />
|
||||
<span>讨论</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/statistics`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('statistics') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('statistics') ? '/images/teacher/统计-选中.png' : '/images/teacher/统计.png'"
|
||||
alt="统计"
|
||||
/>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/statistics`" class="menu-item"
|
||||
:class="{ active: $route.path.includes('statistics') }">
|
||||
<img :src="$route.path.includes('statistics') ? '/images/teacher/统计-选中.png' : '/images/teacher/统计.png'"
|
||||
alt="统计" />
|
||||
<span>统计</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/notification`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('notification') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('notification') ? '/images/teacher/通知-选中.png' : '/images/teacher/通知.png'"
|
||||
alt="通知"
|
||||
/>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/notification`" class="menu-item"
|
||||
:class="{ active: $route.path.includes('notification') }">
|
||||
<img :src="$route.path.includes('notification') ? '/images/teacher/通知-选中.png' : '/images/teacher/通知.png'"
|
||||
alt="通知" />
|
||||
<span>通知</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="`/teacher/course-editor/${courseId}/management`"
|
||||
class="menu-item"
|
||||
:class="{ active: $route.path.includes('management') }"
|
||||
>
|
||||
<img
|
||||
:src="$route.path.includes('management') ? '/images/teacher/管理-选中.png' : '/images/teacher/管理.png'"
|
||||
alt="管理"
|
||||
/>
|
||||
<router-link :to="`/teacher/course-editor/${courseId}/management`" class="menu-item"
|
||||
:class="{ active: $route.path.includes('management') }">
|
||||
<img :src="$route.path.includes('management') ? '/images/teacher/管理-选中.png' : '/images/teacher/管理.png'"
|
||||
alt="管理" />
|
||||
<span>管理</span>
|
||||
</router-link>
|
||||
</div>
|
||||
@ -123,11 +92,20 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
// 获取课程ID
|
||||
const courseId = route.params.id
|
||||
|
||||
// 作业菜单展开状态
|
||||
const homeworkExpanded = ref(false)
|
||||
|
||||
// 切换作业菜单展开/收起
|
||||
const toggleHomework = () => {
|
||||
homeworkExpanded.value = !homeworkExpanded.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -178,16 +156,108 @@ const courseId = route.params.id
|
||||
.menu-item img {
|
||||
margin-left: 40px;
|
||||
margin-top: 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.menu-item span {
|
||||
font-size: 16px;
|
||||
font-size: 18px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 作业二级导航样式 */
|
||||
.menu-group {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.menu-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 15px 20px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border-left: 3px solid transparent;
|
||||
font-size: 18px;
|
||||
color: #666;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.menu-header:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.menu-header img {
|
||||
margin-left: 40px;
|
||||
margin-top: 1px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.menu-header span {
|
||||
font-size: 18px;
|
||||
color: #666;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.menu-header .n-base-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transition: transform 0.2s ease;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.menu-header .n-base-icon.expanded {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.submenu {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.submenu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 20px;
|
||||
margin-bottom: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border-left: 3px solid transparent;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.submenu-item::before {
|
||||
content: '';
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-left: 40px;
|
||||
margin-right: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.submenu-item:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.submenu-item.active {
|
||||
background: #F5F8FB;
|
||||
color: #0288D1;
|
||||
}
|
||||
|
||||
.submenu-item.active span {
|
||||
color: #0288D1;
|
||||
}
|
||||
|
||||
.submenu-item span {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
}
|
||||
/* 右侧内容区域 */
|
||||
.content-area {
|
||||
flex: 1;
|
||||
|
720
src/views/teacher/course/HomeworkLibrary.vue
Normal file
720
src/views/teacher/course/HomeworkLibrary.vue
Normal file
@ -0,0 +1,720 @@
|
||||
<template>
|
||||
<div class="homework-library">
|
||||
<div class="toolbar">
|
||||
<h2>作业库</h2>
|
||||
<div class="toolbar-actions">
|
||||
<button class="btn btn-primary">添加作业</button>
|
||||
<button class="btn btn-new">导入</button>
|
||||
<button class="btn btn-new">导出</button>
|
||||
<button class="btn btn-danger">删除</button>
|
||||
<div class="search-box">
|
||||
<input type="text" placeholder="请输入想要搜索的内容" />
|
||||
<button class="btn btn-search">搜索</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-area">
|
||||
<div class="table-container">
|
||||
<n-config-provider :locale="zhCN" :date-locale="dateZhCN">
|
||||
<n-data-table :columns="columns" :data="homeworkList" :row-key="rowKey" :checked-row-keys="selectedHomework"
|
||||
@update:checked-row-keys="handleCheck" :bordered="false" :single-line="false" size="medium"
|
||||
class="homework-data-table" />
|
||||
</n-config-provider>
|
||||
</div>
|
||||
|
||||
<div class="pagination-container">
|
||||
<!-- 自定义分页器 -->
|
||||
<div class="custom-pagination">
|
||||
<div class="pagination-content">
|
||||
<div class="page-numbers">
|
||||
<span class="page-number nav-button" :class="{ disabled: currentPage === 1 }" @click="goToPage('first')">
|
||||
首页
|
||||
</span>
|
||||
<span class="page-number nav-button" :class="{ disabled: currentPage === 1 }" @click="goToPage('prev')">
|
||||
上一页
|
||||
</span>
|
||||
|
||||
<span v-for="page in visiblePages" :key="page" class="page-number page-number-bordered"
|
||||
:class="{ active: page === currentPage }" @click="goToPage(page)">
|
||||
{{ page }}
|
||||
</span>
|
||||
|
||||
<span v-if="showRightEllipsis" class="page-number">...</span>
|
||||
<span v-if="totalPages > 1" class="page-number page-number-bordered" @click="goToPage(totalPages)">
|
||||
{{ totalPages }}
|
||||
</span>
|
||||
|
||||
<span class="page-number nav-button" :class="{ disabled: currentPage === totalPages }"
|
||||
@click="goToPage('next')">
|
||||
下一页
|
||||
</span>
|
||||
<span class="page-number nav-button" :class="{ disabled: currentPage === totalPages }"
|
||||
@click="goToPage('last')">
|
||||
尾页
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, h, computed } from 'vue'
|
||||
import { NButton, NDropdown, NDataTable, NConfigProvider, zhCN, dateZhCN } from 'naive-ui'
|
||||
import type { DataTableColumns } from 'naive-ui'
|
||||
|
||||
// 作业类型定义
|
||||
interface HomeworkItem {
|
||||
id: number
|
||||
name: string
|
||||
chapter: string
|
||||
class: string
|
||||
creator: string
|
||||
createTime: string
|
||||
isTop: boolean
|
||||
}
|
||||
|
||||
// 选中的作业行
|
||||
const selectedHomework = ref<number[]>([])
|
||||
|
||||
// 分页相关
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const totalCount = ref(6)
|
||||
|
||||
// 计算总页数
|
||||
const totalPages = computed(() => Math.ceil(totalCount.value / pageSize.value))
|
||||
|
||||
// 计算可见页码
|
||||
const visiblePages = computed(() => {
|
||||
const pages = []
|
||||
const maxVisible = 5
|
||||
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2))
|
||||
let end = Math.min(totalPages.value, start + maxVisible - 1)
|
||||
|
||||
if (end - start + 1 < maxVisible) {
|
||||
start = Math.max(1, end - maxVisible + 1)
|
||||
}
|
||||
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i)
|
||||
}
|
||||
return pages
|
||||
})
|
||||
|
||||
// 计算是否显示右侧省略号
|
||||
const showRightEllipsis = computed(() => {
|
||||
return totalPages.value > 5 && currentPage.value < totalPages.value - 2
|
||||
})
|
||||
|
||||
// 分页导航函数
|
||||
const goToPage = (target: number | string) => {
|
||||
if (typeof target === 'string') {
|
||||
switch (target) {
|
||||
case 'first':
|
||||
currentPage.value = 1
|
||||
break
|
||||
case 'prev':
|
||||
if (currentPage.value > 1) currentPage.value--
|
||||
break
|
||||
case 'next':
|
||||
if (currentPage.value < totalPages.value) currentPage.value++
|
||||
break
|
||||
case 'last':
|
||||
currentPage.value = totalPages.value
|
||||
break
|
||||
}
|
||||
} else {
|
||||
currentPage.value = target
|
||||
}
|
||||
}
|
||||
|
||||
// 作业列表数据
|
||||
const homeworkList = ref<HomeworkItem[]>([
|
||||
{
|
||||
id: 1,
|
||||
name: '作业名称作业名称作业名称',
|
||||
chapter: '第一节 开课彩蛋新开始',
|
||||
class: '班级一、班级二',
|
||||
creator: '王建国',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isTop: true
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '作业名称作业名称作业名称',
|
||||
chapter: '第一节 开课彩蛋新开始',
|
||||
class: '班级一、班级二',
|
||||
creator: '王建国',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isTop: false
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '作业名称作业名称作业名称',
|
||||
chapter: '第一节 开课彩蛋新开始',
|
||||
class: '班级一、班级二',
|
||||
creator: '王建国',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isTop: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '作业名称作业名称作业名称',
|
||||
chapter: '-',
|
||||
class: '班级一、班级二',
|
||||
creator: '王建国',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isTop: false
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '作业名称作业名称作业名称',
|
||||
chapter: '第一节 开课彩蛋新开始',
|
||||
class: '班级一、班级二',
|
||||
creator: '王建国',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isTop: false
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: '作业名称作业名称作业名称',
|
||||
chapter: '第一节 开课彩蛋新开始',
|
||||
class: '班级一、班级二',
|
||||
creator: '王建国',
|
||||
createTime: '2025.07.25 09:20',
|
||||
isTop: false
|
||||
}
|
||||
])
|
||||
|
||||
// 行键
|
||||
const rowKey = (row: HomeworkItem) => row.id
|
||||
|
||||
// 处理复选框选择
|
||||
const handleCheck = (keys: number[]) => {
|
||||
selectedHomework.value = keys
|
||||
}
|
||||
|
||||
// 表格列定义
|
||||
const columns: DataTableColumns<HomeworkItem> = [
|
||||
{
|
||||
type: 'selection',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '序号',
|
||||
key: 'index',
|
||||
width: 80,
|
||||
render: (_, index) => index + 1
|
||||
},
|
||||
{
|
||||
title: '作业名称',
|
||||
key: 'name',
|
||||
render: (row) => {
|
||||
return h('div', { style: 'display: flex; align-items: center; gap: 8px;' }, [
|
||||
h('span', { class: 'homework-name' }, row.name),
|
||||
row.isTop ? h('span', { class: 'tag tag-pinned' }, '置顶') : null
|
||||
])
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '所属章节',
|
||||
key: 'chapter'
|
||||
},
|
||||
{
|
||||
title: '绑定班级',
|
||||
key: 'class'
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
key: 'creator'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'actions',
|
||||
width: 200,
|
||||
render: (row) => {
|
||||
return h('div', { style: 'display: flex; gap: 8px; align-items: center;' }, [
|
||||
h(NButton, {
|
||||
size: 'small',
|
||||
type: 'info',
|
||||
secondary: true,
|
||||
onClick: () => editHomework(row.id)
|
||||
}, { default: () => '编辑' }),
|
||||
h(NButton, {
|
||||
size: 'small',
|
||||
type: 'error',
|
||||
secondary: true,
|
||||
onClick: () => deleteHomework(row.id)
|
||||
}, { default: () => '删除' }),
|
||||
h(NDropdown, {
|
||||
trigger: 'click',
|
||||
options: [
|
||||
{
|
||||
label: '重命名',
|
||||
key: 'rename',
|
||||
icon: () => h('img', { src: '/public/images/teacher/重命名.png', style: 'width: 10px; height: 10px;' })
|
||||
},
|
||||
{
|
||||
label: row.isTop ? '取消置顶' : '置顶',
|
||||
key: 'toggleTop',
|
||||
icon: () => h('img', { src: '/public/images/teacher/置顶.png', style: 'width: 10px; height: 10px;' })
|
||||
},
|
||||
{
|
||||
label: '权限设置',
|
||||
key: 'permissions',
|
||||
icon: () => h('img', { src: '/public/images/teacher/权限设置.png', style: 'width: 10px; height: 10px;' })
|
||||
},
|
||||
{
|
||||
label: '下载',
|
||||
key: 'download',
|
||||
icon: () => h('img', { src: '/public/images/teacher/下载.png', style: 'width: 10px; height: 10px;' })
|
||||
}
|
||||
],
|
||||
onSelect: (key) => handleAction(key, row)
|
||||
}, {
|
||||
default: () => h(NButton, {
|
||||
size: 'small',
|
||||
type: 'info',
|
||||
secondary: true
|
||||
}, { default: () => '更多' })
|
||||
})
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
// 编辑作业
|
||||
const editHomework = (id: number) => {
|
||||
console.log('编辑作业:', id)
|
||||
}
|
||||
|
||||
// 删除作业
|
||||
const deleteHomework = (id: number) => {
|
||||
console.log('删除作业:', id)
|
||||
}
|
||||
|
||||
// 处理下拉菜单操作
|
||||
const handleAction = (key: string, row: HomeworkItem) => {
|
||||
console.log('操作:', key, row)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.homework-library {
|
||||
width: 1293px;
|
||||
padding: 10px 20px 20px 0;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
border-bottom: 2px solid #F6F6F6;
|
||||
}
|
||||
|
||||
.toolbar h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.toolbar-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.content-area {
|
||||
height: calc(100% - 80px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 7px 16px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
background: #fff;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: #40a9ff;
|
||||
color: #40a9ff;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #0288D1;
|
||||
border-color: #0288D1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
}
|
||||
|
||||
.btn-new {
|
||||
background: #fff;
|
||||
border-color: #0288D1;
|
||||
color: #0288D1;
|
||||
}
|
||||
|
||||
.btn-new:hover {
|
||||
background: #0288D1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
background: #fff;
|
||||
border-color: #0288D1;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.btn-default:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
border-color: #FF4D4F;
|
||||
color: #FF4D4F;
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
background: #FF4D4F;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-danger:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.btn-small {
|
||||
padding: 4px 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.btn-info {
|
||||
border-color: #0288D1;
|
||||
color: #0288D1;
|
||||
}
|
||||
|
||||
.btn-more {
|
||||
border-color: #0288D1;
|
||||
color: #0288D1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid #F1F3F4;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.search-box input {
|
||||
border: none;
|
||||
padding: 6px 12px;
|
||||
outline: none;
|
||||
width: 200px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.search-box input::placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.btn-search {
|
||||
background: #0288D1;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 6px 16px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.btn-search:hover {
|
||||
background: #0288D1;
|
||||
}
|
||||
|
||||
/* Naive UI 表格样式定制 */
|
||||
:deep(.homework-data-table) {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
:deep(.n-data-table-table) {
|
||||
border: 1px solid #F1F3F4;
|
||||
}
|
||||
|
||||
/* 表格头部样式 */
|
||||
:deep(.homework-data-table .n-data-table-thead) {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
:deep(.homework-data-table .n-data-table-th) {
|
||||
background: #fafafa;
|
||||
font-weight: 500;
|
||||
color: #062333;
|
||||
font-size: 14px;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
padding: 12px 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 表格行样式 */
|
||||
:deep(.homework-data-table .n-data-table-td) {
|
||||
font-size: 12px;
|
||||
color: #062333;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 12px 8px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 名称列也居中 */
|
||||
:deep(.homework-data-table .n-data-table-td[data-col-key="name"]) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
:deep(.homework-data-table .n-data-table-th[data-col-key="name"]) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
:deep(.homework-data-table .n-data-table-tr:hover) {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
/* 复选框样式 */
|
||||
:deep(.homework-data-table .n-checkbox) {
|
||||
--n-size: 16px;
|
||||
}
|
||||
|
||||
/* 按钮组样式调整 */
|
||||
:deep(.homework-data-table .n-button) {
|
||||
font-size: 12px;
|
||||
height: 28px;
|
||||
padding: 0 12px;
|
||||
margin: 2px;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/* 编辑按钮样式 */
|
||||
:deep(.homework-data-table .n-button--info-type) {
|
||||
border: 1px solid #0288D1 !important;
|
||||
color: #0288D1 !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
:deep(.homework-data-table .n-button--info-type:hover) {
|
||||
border-color: #0288D1 !important;
|
||||
color: #0288D1 !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/* 删除按钮样式 */
|
||||
:deep(.homework-data-table .n-button--error-type) {
|
||||
border: 1px solid #FF4D4F !important;
|
||||
color: #FF4D4F !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
:deep(.homework-data-table .n-button--error-type:hover) {
|
||||
border-color: #FF4D4F !important;
|
||||
color: #FF4D4F !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/* 更多按钮样式 */
|
||||
:deep(.homework-data-table .n-button--info-type:last-child) {
|
||||
border: 1px solid #4165D7 !important;
|
||||
color: #4165D7 !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
:deep(.homework-data-table .n-button--info-type:last-child:hover) {
|
||||
border-color: #4165D7 !important;
|
||||
color: #4165D7 !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/* 下拉菜单样式 */
|
||||
:deep(.n-dropdown-option) {
|
||||
padding: 8px 12px;
|
||||
font-size: 12px;
|
||||
color: #062333;
|
||||
}
|
||||
|
||||
/* 分页器容器 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 自定义分页器样式 */
|
||||
.custom-pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background: #fff;
|
||||
padding: 20px 0;
|
||||
margin-top: auto;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.pagination-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0 auto;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.page-numbers {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
display: inline-block;
|
||||
min-width: 38px;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
padding: 0 5px;
|
||||
margin: 0 4px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.page-number-bordered {
|
||||
border: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
.page-number.active {
|
||||
background-color: #0088D1;
|
||||
color: white;
|
||||
border-color: #0088D1;
|
||||
}
|
||||
|
||||
.page-number:hover:not(.disabled) {
|
||||
color: #0088D1;
|
||||
border-color: #0088D1;
|
||||
}
|
||||
|
||||
.page-number.disabled {
|
||||
color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.page-number.disabled:hover {
|
||||
color: #ccc;
|
||||
border-color: #d9d9d9;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
padding: 0 8px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.nav-button:hover:not(.disabled) {
|
||||
color: #0088D1;
|
||||
}
|
||||
|
||||
/* 表格内所有文字颜色统一 */
|
||||
:deep(.homework-data-table .n-data-table-th__title) {
|
||||
color: #062333;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
:deep(.homework-data-table .n-data-table-td) {
|
||||
color: #062333;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 作业名称和标签样式 */
|
||||
.homework-name {
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
color: #062333;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 10px;
|
||||
color: #9ac1d6;
|
||||
background: transparent;
|
||||
border: 1px solid #9ac1d6;
|
||||
}
|
||||
|
||||
.tag-pinned {
|
||||
color: #9ac1d6;
|
||||
border-color: #9ac1d6;
|
||||
}
|
||||
|
||||
/* 确保在Naive UI表格中标签样式正确显示 */
|
||||
:deep(.homework-data-table .tag) {
|
||||
display: inline-block !important;
|
||||
padding: 2px 6px !important;
|
||||
border-radius: 4px !important;
|
||||
font-size: 10px !important;
|
||||
color: #9ac1d6 !important;
|
||||
background: transparent !important;
|
||||
border: 1px solid #9ac1d6 !important;
|
||||
}
|
||||
|
||||
:deep(.homework-data-table .tag-pinned) {
|
||||
color: #9ac1d6 !important;
|
||||
border-color: #9ac1d6 !important;
|
||||
font-size: 10px !important;
|
||||
}
|
||||
</style>
|
409
src/views/teacher/course/HomeworkReview.vue
Normal file
409
src/views/teacher/course/HomeworkReview.vue
Normal file
@ -0,0 +1,409 @@
|
||||
<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-dropdown">
|
||||
<span class="dropdown-text">班级名称</span>
|
||||
<svg class="dropdown-arrow" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M3.14645 5.64645C3.34171 5.45118 3.65829 5.45118 3.85355 5.64645L8 9.79289L12.1464 5.64645C12.3417 5.45118 12.6583 5.45118 12.8536 5.64645C13.0488 5.84171 13.0488 6.15829 12.8536 6.35355L8.35355 10.8536C8.15829 11.0488 7.84171 11.0488 7.64645 10.8536L3.14645 6.35355C2.95118 6.15829 2.95118 5.84171 3.14645 5.64645Z"
|
||||
fill="#C2C2C2"></path>
|
||||
</svg>
|
||||
</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">
|
||||
<a class="delete-link" @click="deleteHomework(homework.id)">删除</a>
|
||||
<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>
|
||||
<button class="action-button review" @click="reviewHomework(homework.id)">批阅</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 发布中作业 -->
|
||||
<div v-if="homework.status === 'publishing'" class="homework-card publishing">
|
||||
<a class="delete-link" @click="deleteHomework(homework.id)">删除</a>
|
||||
|
||||
|
||||
<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>
|
||||
<button class="action-button view" @click="viewHomework(homework.id)">查看</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
interface HomeworkItem {
|
||||
id: number
|
||||
title: string
|
||||
content: string
|
||||
publisher: string
|
||||
timeRange: string
|
||||
status: 'publishing' | 'ended'
|
||||
pendingCount: number
|
||||
submittedCount: number
|
||||
unsubmittedCount: number
|
||||
}
|
||||
|
||||
const activeTab = ref<'all' | 'publishing' | 'ended'>('all')
|
||||
|
||||
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 filteredHomeworks = computed(() => {
|
||||
if (activeTab.value === 'all') {
|
||||
return homeworks.value
|
||||
}
|
||||
return homeworks.value.filter(homework => homework.status === activeTab.value)
|
||||
})
|
||||
|
||||
const reviewHomework = (id: number) => {
|
||||
console.log('批阅作业:', id)
|
||||
}
|
||||
|
||||
const viewHomework = (id: number) => {
|
||||
console.log('查看作业:', id)
|
||||
}
|
||||
|
||||
const deleteHomework = (id: number) => {
|
||||
console.log('删除作业:', id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.homework-review {
|
||||
width: 1293px;
|
||||
background: #fff;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 顶部筛选区域 */
|
||||
.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-dropdown {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 16px;
|
||||
background: #fff;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 20px;
|
||||
cursor: pointer;
|
||||
width: 276px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.dropdown-text {
|
||||
font-size: 14px;
|
||||
color: #062333;
|
||||
}
|
||||
|
||||
.dropdown-arrow {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* 作业列表 */
|
||||
.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;
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user