1998 lines
51 KiB
Vue
Raw Normal View History

2025-08-22 19:52:05 +08:00
<template>
2025-08-23 19:20:14 +08:00
<n-config-provider :theme-overrides="themeOverrides">
<div class="block_3 flex-row justify-between" :class="{
'mobile-layout': isMobile,
'tablet-layout': isTablet,
'sidebar-collapsed': sidebarCollapsed
}">
2025-08-23 19:20:14 +08:00
<!-- 移动端菜单按钮 -->
<n-button v-if="isMobile" class="mobile-menu-toggle" quaternary @click="toggleSidebar">
<span class="menu-icon"></span>
</n-button>
<div class="chapter-editor flex-col" :class="{
'mobile-sidebar': isMobile,
'collapsed': sidebarCollapsed && isMobile
}">
<!-- 移动端关闭按钮 -->
<n-button v-if="isMobile" class="mobile-close" quaternary @click="toggleSidebar">
<span class="close-icon">×</span>
</n-button>
<n-button quaternary circle size="large" @click="goBack" class="back-button">
<template #icon>
<n-icon>
<ArrowBackOutline />
</n-icon>
</template>
</n-button>
2025-09-11 14:34:30 +08:00
<n-button class="header-section flex-row justify-between" type="primary" @click="addChapter">
2025-08-23 19:20:14 +08:00
<template #icon>
<img class="chapter-icon" referrerpolicy="no-referrer" src="/images/teacher/加号_4.png" />
</template>
<span class="section-title">添加章节</span>
</n-button>
2025-09-11 14:34:30 +08:00
<template v-for="(chapter, chapterIndex) in chapters" :key="chapter.id">
<div class="chapter-item flex-row" @click="toggleChapterExpansion(chapterIndex)" :class="{ 'collapsed': !chapter.expanded }">
<img class="chapter-arrow-icon" :class="{ 'rotated': !chapter.expanded }" referrerpolicy="no-referrer"
:src="chapter.expanded ? '/images/teacher/路径18.png' : '/images/teacher/collapse.png'" />
<span class="chapter-title">{{ chapterIndex + 1 }}&nbsp;{{ chapter.name }}</span>
<n-dropdown v-show="chapter.expanded" :options="chapterMenuOptions" @select="(key: string) => handleChapterMenuSelect(key, chapterIndex)">
<img class="chapter-options-icon" :class="{ 'transparent': !chapter.expanded }"
referrerpolicy="no-referrer" src="/images/teacher/分组76.png" />
</n-dropdown>
2025-08-25 18:28:46 +08:00
</div>
2025-09-11 14:34:30 +08:00
<div v-show="chapter.expanded" v-for="section in chapter.sections" :key="section.id" class="chapter-content-item flex-row">
<div class="content-text-group flex-col justify-between justify-between">
<span class="content-title">{{ section.contentTitle }}</span>
<span class="content-description">{{ section.contentDescription }}</span>
</div>
<div class="action-menu flex-col" :class="{ 'visible': isMenuVisible }">
<span class="action-rename">重命名</span>
<span class="action-delete" @click="openDeleteModal">删除</span>
</div>
2025-08-25 18:28:46 +08:00
</div>
2025-09-11 14:34:30 +08:00
</template>
2025-08-25 18:28:46 +08:00
2025-08-23 19:20:14 +08:00
</div>
2025-08-22 19:52:05 +08:00
2025-08-23 19:20:14 +08:00
<div class="chapter-detail-container flex-col" :class="{
'mobile-content': isMobile,
'tablet-content': isTablet,
'sidebar-collapsed-content': sidebarCollapsed && isMobile
}">
2025-09-11 14:34:30 +08:00
<div class="chapter-container" v-if="chapters.length">
2025-08-23 19:20:14 +08:00
<div class="chapter-header flex-row justify-between2">
2025-09-11 14:34:30 +08:00
<span class="chapter-title-text">{{ currentChapterIndex + 1 }}</span>
<n-button class="collapse-button flex-row justify-between" quaternary @click="toggleChapterExpansion()">
<span class="collapse-text">{{ chapters[currentChapterIndex].expanded ? '收起' : '展开' }}</span>
<img class="collapse-icon" :class="{ 'rotated': !chapters[currentChapterIndex].expanded }" referrerpolicy="no-referrer"
2025-08-23 19:20:14 +08:00
src="/images/teacher/箭头-灰.png" />
</n-button>
2025-08-22 19:52:05 +08:00
</div>
2025-08-23 19:20:14 +08:00
<div class="chapter-name-section flex-row justify-between">
<div class="chapter-name-label">
<span class="required-mark">*</span>
<span class="label-text">本章名称</span>
2025-08-22 19:52:05 +08:00
</div>
2025-08-23 19:20:14 +08:00
<div class="chapter-name-input-container flex-row">
2025-09-11 14:34:30 +08:00
<n-input ref="chapterInputRef" v-model:value="chapters[currentChapterIndex].name" class="chapter-name-input"
2025-08-23 19:20:14 +08:00
placeholder="请输入本章名称" @blur="handleChapterNameBlur" @focus="handleChapterNameFocus" />
2025-08-22 19:52:05 +08:00
</div>
</div>
2025-09-11 14:34:30 +08:00
<div v-show="chapters[currentChapterIndex].expanded" v-for="(section, index) in chapters[currentChapterIndex].sections" :key="section.id"
2025-08-23 19:20:14 +08:00
class="chapter-content-container">
<n-divider class="chapter-divider" />
2025-08-22 19:52:05 +08:00
2025-08-23 19:20:14 +08:00
<div class="lesson-section flex-row justify-end">
<div class="lesson-label-wrapper">
<span class="lesson-required-mark">*</span>
<span class="lesson-label-text">{{ ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'][index] || (index
+ 1) }}</span>
</div>
<div class="lesson-input-container">
2025-09-11 14:34:30 +08:00
<n-input v-model:value="section.lessonName" class="lesson-input" placeholder="请输入章节"
2025-08-23 19:20:14 +08:00
@blur="handleLessonBlur" @focus="handleLessonFocus">
<template #suffix>
<n-button quaternary size="small" @click="() => removeLessonSection(section.id)">
<template #icon>
2025-08-25 18:28:46 +08:00
<img src="/images/teacher/关闭-灰.png" alt="关闭" style="width: 10px; height: 10px; padding: 0;" />
2025-08-23 19:20:14 +08:00
</template>
</n-button>
</template>
</n-input>
</div>
2025-08-22 19:52:05 +08:00
</div>
2025-08-23 19:20:14 +08:00
<div class="courseware-section flex-row justify-end">
<span class="courseware-label">添加课件</span>
<div class="courseware-input-container">
<n-select v-model:value="section.coursewareName" class="courseware-input" placeholder="课件准备PPT"
:options="coursewareOptions" filterable tag />
2025-08-22 19:52:05 +08:00
</div>
</div>
2025-08-23 19:20:14 +08:00
2025-09-11 14:34:30 +08:00
<!-- 如果选择了课件类型显示上传选项 -->
<div v-if="section.coursewareName" class="courseware-upload-section flex-row justify-end">
<span class="courseware-upload-label">选择文件</span>
<div class="courseware-upload-container">
<CustomDropdown v-model="section.coursewareUploadOption" :options="coursewareUploadOptions" placeholder="请选择文件来源"
@change="(value: any) => handleCoursewareUploadOptionChange(section, value)" />
<!-- 隐藏的课件文件输入框 -->
<input type="file" :id="`courseware-file-upload-${section.id}`" class="file-input"
accept=".pdf,.doc,.docx,.ppt,.pptx,.mp4,.avi,.mov,.wmv"
@change="handleCoursewareFileUpload($event, section)" multiple />
</div>
</div>
<!-- 显示已上传的课件文件列表 -->
<div v-if="section.coursewareFiles && section.coursewareFiles.length > 0"
class="uploaded-courseware-files-section flex-row justify-end">
<span class="uploaded-courseware-files-label">已选择课件</span>
<div class="uploaded-files-container">
<div v-for="(file, fileIndex) in section.coursewareFiles" :key="fileIndex" class="file-item">
<span class="file-name">{{ file.name }}</span>
<button class="remove-file-btn" @click="removeCoursewareFile(section, fileIndex)">
<img src="/images/teacher/关闭-灰.png" alt="删除" style="width: 12px; height: 12px;" />
</button>
</div>
</div>
</div>
2025-08-23 19:20:14 +08:00
<div class="exam-section flex-row justify-end">
<span class="exam-label">添加考试/练习</span>
<div class="exam-dropdown-container">
2025-08-25 18:28:46 +08:00
<CustomDropdown v-model="section.selectedExamOption" :options="examOptions" placeholder="请添加考试/练习"
@change="(value: any) => handleExamOptionChange(section, value)" />
<!-- 隐藏的文件输入框 -->
<input type="file" :id="`file-upload-${section.id}`" class="file-input"
accept=".pdf,.doc,.docx,.ppt,.pptx,.xls,.xlsx,.txt,.zip,.rar"
@change="handleFileUpload($event, section)" multiple ref="fileInputRef" />
</div>
</div>
<!-- 显示已上传的文件列表 -->
<div v-if="section.uploadedFiles && section.uploadedFiles.length > 0"
class="uploaded-files-section flex-row justify-end">
<span class="uploaded-files-label">已上传文件</span>
<div class="uploaded-files-container">
<div v-for="(file, fileIndex) in section.uploadedFiles" :key="fileIndex" class="file-item">
<span class="file-name">{{ file.name }}</span>
<button class="remove-file-btn" @click="removeFile(section, fileIndex)">
<img src="/images/teacher/关闭-灰.png" alt="删除" style="width: 12px; height: 12px;" />
</button>
</div>
2025-08-22 19:52:05 +08:00
</div>
</div>
2025-08-23 19:20:14 +08:00
<div class="homework-section flex-row justify-end">
<span class="homework-label">添加作业</span>
<div class="homework-input-container">
2025-08-25 18:28:46 +08:00
<HomeworkDropdown v-model="section.homeworkName" :options="homeworkOptions" placeholder="请添加作业"
@change="(value: any) => handleHomeworkOptionChange(section, value)" />
<!-- 隐藏的文件输入框用于作业上传 -->
<input type="file" :id="`homework-file-upload-${section.id}`" style="display: none;" multiple
accept=".pdf,.doc,.docx,.txt" @change="(event: any) => handleHomeworkFileUpload(event, section)" />
2025-08-22 19:52:05 +08:00
</div>
</div>
</div>
</div>
2025-09-11 14:34:30 +08:00
<n-button v-show="chapters[currentChapterIndex].expanded" class="add-section-btn flex-row justify-between" quaternary
2025-08-23 19:20:14 +08:00
@click="addSection">
<template #icon>
<img class="add-section-icon" referrerpolicy="no-referrer" src="/images/teacher/加号(2).png" />
</template>
<span class="add-section-text">添加小节</span>
</n-button>
2025-08-22 19:52:05 +08:00
</div>
2025-08-23 19:20:14 +08:00
<n-modal v-model:show="showDeleteModal" preset="dialog" title="确认删除" content="确定要删除这个章节吗?" positive-text="确认"
negative-text="取消" @positive-click="handleDeleteConfirm" @negative-click="handleDeleteCancel" />
2025-08-25 18:28:46 +08:00
<!-- 试卷库模态框 -->
<ExamPaperLibraryModal v-model:show="showExamLibraryModal" @confirm="handleExamLibraryConfirm" />
<!-- 作业库模态框 -->
<HomeworkLibraryModal v-model:show="showHomeworkLibraryModal" @confirm="handleHomeworkLibraryConfirm" />
2025-09-11 14:34:30 +08:00
<!-- 资源库模态框 -->
<ResourceLibraryModal v-model:show="showResourceLibraryModal" @confirm="handleResourceLibraryConfirm" />
2025-08-22 19:52:05 +08:00
</div>
2025-08-23 19:20:14 +08:00
</n-config-provider>
2025-08-22 19:52:05 +08:00
</template>
<script setup lang="ts">
2025-08-23 19:20:14 +08:00
import { ref, onMounted, onUnmounted } from 'vue';
import type { GlobalThemeOverrides } from 'naive-ui';
2025-08-25 18:28:46 +08:00
import CustomDropdown from '@/components/CustomDropdown.vue';
import HomeworkDropdown from '@/components/HomeworkDropdown.vue';
import ExamPaperLibraryModal from '@/components/ExamPaperLibraryModal.vue';
import HomeworkLibraryModal from '@/components/HomeworkLibraryModal.vue';
2025-09-11 14:34:30 +08:00
import ResourceLibraryModal from '@/components/ResourceLibraryModal.vue';
import { ArrowBackOutline } from '@vicons/ionicons5';
import { useRouter } from 'vue-router';
const router = useRouter();
2025-08-22 19:52:05 +08:00
// 控制菜单显示状态的响应式变量
const isMenuVisible = ref(false);
// 控制删除确认模态框的显示状态
const showDeleteModal = ref(false);
2025-08-25 18:28:46 +08:00
// 控制试卷库模态框的显示状态
const showExamLibraryModal = ref(false);
// 控制作业库模态框的显示状态
const showHomeworkLibraryModal = ref(false);
2025-09-11 14:34:30 +08:00
// 控制资源库模态框的显示状态
const showResourceLibraryModal = ref(false);
2025-08-23 19:20:14 +08:00
// 响应式相关状态
const isMobile = ref(false);
const isTablet = ref(false);
const sidebarCollapsed = ref(false);
2025-08-25 18:28:46 +08:00
// 定义section的类型
interface Section {
id: number;
lessonName: string;
coursewareName: string;
2025-09-11 14:34:30 +08:00
coursewareUploadOption: string;
coursewareFiles: File[];
2025-08-25 18:28:46 +08:00
selectedExamOption: string;
homeworkName: string;
uploadedFiles: File[];
homeworkFiles: File[];
2025-09-11 14:34:30 +08:00
contentTitle: string;
contentDescription: string;
}
// 定义章节的类型
interface Chapter {
id: number;
name: string;
expanded: boolean;
sections: Section[];
2025-08-25 18:28:46 +08:00
}
2025-09-11 14:34:30 +08:00
// 章节数据结构
const chapters = ref<Chapter[]>([
2025-08-23 19:20:14 +08:00
{
id: 1,
2025-09-11 14:34:30 +08:00
name: '课前准备',
expanded: true,
sections: [
{
id: 1,
lessonName: '开课彩蛋新开始',
coursewareName: '课件准备PPT',
coursewareUploadOption: '',
coursewareFiles: [],
selectedExamOption: '',
homeworkName: '请添加作业',
uploadedFiles: [],
homeworkFiles: [],
contentTitle: '1.开课彩蛋:新开始',
contentDescription: '第一节课程定位程定位与目标'
},
{
id: 2,
lessonName: '开课彩蛋新开始',
coursewareName: '课件准备PPT',
coursewareUploadOption: '',
coursewareFiles: [],
selectedExamOption: '',
homeworkName: '请添加作业',
uploadedFiles: [],
homeworkFiles: [],
contentTitle: '2.课程内容:扩展知识',
contentDescription: '第二节课程扩展内容'
}
]
2025-08-23 19:20:14 +08:00
},
{
id: 2,
2025-09-11 14:34:30 +08:00
name: '课前准备',
expanded: false,
sections: [
{
id: 1,
lessonName: '课程导入基础知识',
coursewareName: '课件准备PPT',
coursewareUploadOption: '',
coursewareFiles: [],
selectedExamOption: '',
homeworkName: '请添加作业',
uploadedFiles: [],
homeworkFiles: [],
contentTitle: '2.课程导入:基础知识',
contentDescription: '第二节课程基础知识讲解'
}
]
},
{
id: 3,
name: '课前准备',
expanded: false,
sections: [
{
id: 1,
lessonName: '实践操作技能训练',
coursewareName: '课件准备PPT',
coursewareUploadOption: '',
coursewareFiles: [],
selectedExamOption: '',
homeworkName: '请添加作业',
uploadedFiles: [],
homeworkFiles: [],
contentTitle: '3.实践操作:技能训练',
contentDescription: '第三节实践操作技能训练'
}
]
2025-08-23 19:20:14 +08:00
}
]);
2025-09-11 14:34:30 +08:00
// 当前选中的章节索引
const currentChapterIndex = ref(0);
// 下一个章节的ID
const nextChapterId = ref(4);
2025-08-23 19:20:14 +08:00
// 课件选项
const coursewareOptions = [
{ label: '课件准备PPT', value: '课件准备PPT' },
{ label: '视频课件', value: '视频课件' },
2025-09-11 14:34:30 +08:00
];
// 课件上传选项
const coursewareUploadOptions = [
{ label: '本地上传', value: '本地上传' },
{ label: '从资源库选择', value: '从资源库选择' }
2025-08-23 19:20:14 +08:00
];
// 作业选项
const homeworkOptions = [
2025-08-25 18:28:46 +08:00
{ label: '从作业库选择', value: '从作业库选择' },
{ label: '本地上传', value: '本地上传' }
2025-08-23 19:20:14 +08:00
];
2025-08-22 19:52:05 +08:00
// 输入框引用
2025-08-23 19:20:14 +08:00
const chapterInputRef = ref();
// Naive UI 主题配置
const themeOverrides: GlobalThemeOverrides = {
common: {
primaryColor: '#0288D1',
primaryColorHover: '#0277BD',
primaryColorPressed: '#01579B',
},
Button: {
textColorGhostPrimary: '#0288D1',
borderPrimary: '1px solid #0288D1',
},
Input: {
borderHover: '#0288D1',
borderFocus: '#0288D1',
},
Select: {
peers: {
InternalSelection: {
borderHover: '#0288D1',
borderFocus: '#0288D1',
}
}
}
};
2025-08-22 19:52:05 +08:00
2025-08-23 19:20:14 +08:00
// 章节菜单选项
const chapterMenuOptions = [
{
label: '重命名',
key: 'rename'
},
{
label: '删除',
key: 'delete'
}
];
// 考试选项
const examOptions = [
{
label: '从考试/练习选择',
value: '从考试/练习选择'
},
{
label: '本地上传',
value: '本地上传'
}
];
// 处理章节菜单选择
2025-09-11 14:34:30 +08:00
const handleChapterMenuSelect = (key: string, chapterIndex?: number) => {
const targetIndex = chapterIndex !== undefined ? chapterIndex : currentChapterIndex.value;
2025-08-23 19:20:14 +08:00
if (key === 'delete') {
2025-09-11 14:34:30 +08:00
deleteChapter(targetIndex);
2025-08-23 19:20:14 +08:00
} else if (key === 'rename') {
// 处理重命名逻辑
2025-09-11 14:34:30 +08:00
console.log('重命名章节', targetIndex);
2025-08-23 19:20:14 +08:00
}
};
2025-08-22 19:52:05 +08:00
// 处理章节名称失去焦点
const handleChapterNameBlur = () => {
// 可以在这里添加保存逻辑
2025-09-11 14:34:30 +08:00
console.log('章节名称已更新:', chapters.value[currentChapterIndex.value].name);
2025-08-23 19:20:14 +08:00
};
2025-08-22 19:52:05 +08:00
// 处理章节名称获得焦点
const handleChapterNameFocus = () => {
// 可以在这里添加获得焦点时的逻辑
console.log('开始编辑章节名称');
2025-08-23 19:20:14 +08:00
};
2025-08-22 19:52:05 +08:00
2025-09-11 14:34:30 +08:00
// 添加章节
const addChapter = () => {
// 先关闭所有现有章节
chapters.value.forEach((chapter) => {
chapter.expanded = false;
});
const newChapter: Chapter = {
id: nextChapterId.value,
name: `新章节${nextChapterId.value}`,
expanded: true,
sections: [
{
id: 1,
lessonName: '新小节',
coursewareName: '课件准备PPT',
coursewareUploadOption: '',
coursewareFiles: [],
selectedExamOption: '',
homeworkName: '请添加作业',
uploadedFiles: [],
homeworkFiles: [],
contentTitle: '1.新小节',
contentDescription: '新小节描述'
}
]
};
chapters.value.push(newChapter);
currentChapterIndex.value = chapters.value.length - 1;
nextChapterId.value++;
};
// 删除章节
const deleteChapter = (chapterIndex: number) => {
if (chapters.value.length > 1) {
chapters.value.splice(chapterIndex, 1);
// 调整当前章节索引
if (currentChapterIndex.value >= chapters.value.length) {
currentChapterIndex.value = chapters.value.length - 1;
} else if (currentChapterIndex.value > chapterIndex) {
currentChapterIndex.value--;
}
// 确保至少有一个章节是展开的
const hasExpandedChapter = chapters.value.some(chapter => chapter.expanded);
if (!hasExpandedChapter && chapters.value.length > 0) {
chapters.value[currentChapterIndex.value].expanded = true;
}
}
};
2025-08-22 19:52:05 +08:00
// 打开删除确认模态框
const openDeleteModal = () => {
showDeleteModal.value = true;
isMenuVisible.value = false; // 关闭操作菜单
2025-08-23 19:20:14 +08:00
};
2025-08-22 19:52:05 +08:00
// 处理删除确认
const handleDeleteConfirm = () => {
console.log('确认删除章节');
// 这里添加实际的删除逻辑
showDeleteModal.value = false;
2025-08-23 19:20:14 +08:00
};
2025-08-22 19:52:05 +08:00
// 处理删除取消
const handleDeleteCancel = () => {
console.log('取消删除章节');
showDeleteModal.value = false;
2025-08-23 19:20:14 +08:00
};
2025-08-22 19:52:05 +08:00
2025-08-23 19:20:14 +08:00
// 删除不再需要的课件相关方法,现在使用下拉框
2025-08-22 19:52:05 +08:00
// 检查屏幕尺寸
const checkScreenSize = () => {
const width = window.innerWidth;
isMobile.value = width <= 768;
isTablet.value = width > 768 && width <= 1024;
// 移动端自动收起侧边栏
if (isMobile.value) {
sidebarCollapsed.value = true;
}
};
// 切换侧边栏
const toggleSidebar = () => {
sidebarCollapsed.value = !sidebarCollapsed.value;
};
2025-08-23 19:20:14 +08:00
// 切换章节展开/收起状态
2025-09-11 14:34:30 +08:00
const toggleChapterExpansion = (chapterIndex?: number) => {
if (chapterIndex !== undefined) {
// 如果点击的章节已经展开,则关闭它
if (chapters.value[chapterIndex].expanded) {
chapters.value[chapterIndex].expanded = false;
} else {
// 关闭所有章节
chapters.value.forEach((chapter) => {
chapter.expanded = false;
});
// 展开点击的章节
chapters.value[chapterIndex].expanded = true;
currentChapterIndex.value = chapterIndex;
}
} else {
// 如果没有传递索引,则切换当前选中章节的状态
const currentExpanded = chapters.value[currentChapterIndex.value].expanded;
if (currentExpanded) {
chapters.value[currentChapterIndex.value].expanded = false;
} else {
// 关闭所有章节
chapters.value.forEach((chapter) => {
chapter.expanded = false;
});
// 展开当前章节
chapters.value[currentChapterIndex.value].expanded = true;
}
}
2025-08-25 18:28:46 +08:00
};
2025-08-22 19:52:05 +08:00
// 生命周期钩子
onMounted(() => {
checkScreenSize();
window.addEventListener('resize', checkScreenSize);
2025-08-22 19:52:05 +08:00
});
onUnmounted(() => {
window.removeEventListener('resize', checkScreenSize);
2025-08-22 19:52:05 +08:00
});
2025-08-23 19:20:14 +08:00
// 删除不再需要的作业相关方法,现在使用下拉框
// 课节相关方法
const handleLessonBlur = () => {
console.log('课节名称已更新');
};
const handleLessonFocus = () => {
console.log('开始编辑课节名称');
};
// 添加小节
const addSection = () => {
2025-09-11 14:34:30 +08:00
const currentChapter = chapters.value[currentChapterIndex.value];
const newSectionId = Math.max(...currentChapter.sections.map(s => s.id), 0) + 1;
const newSection: Section = {
id: newSectionId,
lessonName: '新小节',
2025-08-23 19:20:14 +08:00
coursewareName: '课件准备PPT',
2025-09-11 14:34:30 +08:00
coursewareUploadOption: '',
coursewareFiles: [],
2025-08-23 19:20:14 +08:00
selectedExamOption: '',
2025-08-25 18:28:46 +08:00
homeworkName: '请添加作业',
uploadedFiles: [],
2025-09-11 14:34:30 +08:00
homeworkFiles: [],
contentTitle: `${newSectionId}.新小节`,
contentDescription: '新小节描述'
2025-08-23 19:20:14 +08:00
};
2025-09-11 14:34:30 +08:00
currentChapter.sections.push(newSection);
2025-08-23 19:20:14 +08:00
};
2025-08-25 18:28:46 +08:00
// 处理考试选项变化
const handleExamOptionChange = (section: Section, value: any) => {
console.log('选项变化:', value, 'section id:', section.id);
// 如果选择的是"本地上传",直接触发文件选择
if (value === '本地上传') {
console.log('触发文件选择');
const fileInput = document.getElementById(`file-upload-${section.id}`) as HTMLInputElement;
if (fileInput) {
fileInput.click();
} else {
console.error('找不到文件输入框:', `file-upload-${section.id}`);
}
} else if (value === '从考试/练习选择') {
// 如果选择的是"从考试/练习选择",显示试卷库模态框
console.log('准备显示试卷库模态框');
showExamLibraryModal.value = true;
console.log('showExamLibraryModal.value:', showExamLibraryModal.value);
}
};
2025-09-11 14:34:30 +08:00
// 处理课件上传选项变化
const handleCoursewareUploadOptionChange = (section: Section, value: any) => {
console.log('课件上传选项变化:', value, 'section id:', section.id);
// 如果选择的是"本地上传",直接触发文件选择
if (value === '本地上传') {
console.log('触发课件文件选择');
const fileInput = document.getElementById(`courseware-file-upload-${section.id}`) as HTMLInputElement;
if (fileInput) {
fileInput.click();
} else {
console.error('找不到课件文件输入框:', `courseware-file-upload-${section.id}`);
}
} else if (value === '从资源库选择') {
// 如果选择的是"从资源库选择",显示资源库模态框
console.log('准备显示资源库模态框');
showResourceLibraryModal.value = true;
console.log('showResourceLibraryModal.value:', showResourceLibraryModal.value);
}
};
2025-08-25 18:28:46 +08:00
// 处理作业选项变化
const handleHomeworkOptionChange = (section: Section, value: any) => {
console.log('作业选项变化:', value, 'section id:', section.id);
// 如果选择的是"本地上传",直接触发文件选择
if (value === '本地上传') {
console.log('触发作业文件选择');
const fileInput = document.getElementById(`homework-file-upload-${section.id}`) as HTMLInputElement;
if (fileInput) {
fileInput.click();
} else {
console.error('找不到作业文件输入框:', `homework-file-upload-${section.id}`);
}
} else if (value === '从作业库选择') {
// 如果选择的是"从作业库选择",显示作业库模态框
console.log('准备显示作业库模态框');
showHomeworkLibraryModal.value = true;
console.log('showHomeworkLibraryModal.value:', showHomeworkLibraryModal.value);
showHomeworkLibraryModal.value = true;
console.log('showHomeworkLibraryModal.value:', showHomeworkLibraryModal.value);
}
};
// 处理文件上传
const handleFileUpload = (event: Event, section: Section) => {
const target = event.target as HTMLInputElement;
if (target.files) {
const files = Array.from(target.files);
section.uploadedFiles = files;
console.log('文件已上传:', files);
}
};
2025-09-11 14:34:30 +08:00
// 处理课件文件上传
const handleCoursewareFileUpload = (event: Event, section: Section) => {
const target = event.target as HTMLInputElement;
if (target.files) {
const files = Array.from(target.files);
section.coursewareFiles = files;
console.log('课件文件已上传:', files);
}
};
2025-08-25 18:28:46 +08:00
// 处理作业文件上传
const handleHomeworkFileUpload = (event: any, section: Section) => {
const target = event.target as HTMLInputElement;
if (target.files) {
const files = Array.from(target.files);
section.homeworkFiles = files;
console.log('作业文件已上传:', files);
}
};
// 删除文件
const removeFile = (section: Section, fileIndex: number) => {
section.uploadedFiles.splice(fileIndex, 1);
};
2025-09-11 14:34:30 +08:00
// 删除课件文件
const removeCoursewareFile = (section: Section, fileIndex: number) => {
section.coursewareFiles.splice(fileIndex, 1);
};
2025-08-25 18:28:46 +08:00
// 处理试卷库选择确认
const handleExamLibraryConfirm = (selectedExams: any[]) => {
console.log('选择的试卷:', selectedExams);
// 这里可以处理选择的试卷比如更新当前section的数据
// 暂时只是关闭模态框
showExamLibraryModal.value = false;
};
// 处理作业库选择确认
const handleHomeworkLibraryConfirm = (selectedHomework: any[]) => {
console.log('选择的作业:', selectedHomework);
// 这里可以处理选择的作业比如更新当前section的数据
// 暂时只是关闭模态框
showHomeworkLibraryModal.value = false;
};
2025-09-11 14:34:30 +08:00
// 处理资源库选择确认
const handleResourceLibraryConfirm = (selectedResources: any[]) => {
console.log('选择的资源:', selectedResources);
// 这里可以处理选择的资源比如更新当前section的数据
// 暂时只是关闭模态框
showResourceLibraryModal.value = false;
};
2025-08-23 19:20:14 +08:00
// 删除课节
2025-09-11 14:34:30 +08:00
const removeLessonSection = (sectionId: number, chapterIndex?: number) => {
const targetChapterIndex = chapterIndex !== undefined ? chapterIndex : currentChapterIndex.value;
const chapter = chapters.value[targetChapterIndex];
const index = chapter.sections.findIndex((section: Section) => section.id === sectionId);
if (index > -1 && chapter.sections.length > 1) {
chapter.sections.splice(index, 1);
2025-08-23 19:20:14 +08:00
}
};
const goBack = () => {
router.back();
}
2025-08-23 19:20:14 +08:00
// 删除未使用的方法
</script>
<style scoped>
/* Naive UI 组件样式覆盖 */
:deep(.n-button.mobile-menu-toggle) {
position: fixed;
top: 20px;
left: 20px;
z-index: 1001;
background: #0288D1 !important;
color: white !important;
border: none !important;
border-radius: 4px !important;
padding: 10px !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;
width: auto !important;
height: auto !important;
2025-08-22 19:52:05 +08:00
}
.back-button{
margin: 10px 0 0 10px;
}
2025-08-23 19:20:14 +08:00
:deep(.n-button.mobile-close) {
position: absolute;
top: 15px;
right: 15px;
background: #f5f5f5 !important;
border: none !important;
border-radius: 50% !important;
width: 30px !important;
height: 30px !important;
z-index: 1002;
color: #666 !important;
2025-08-22 19:52:05 +08:00
}
2025-08-23 19:20:14 +08:00
:deep(.n-button.header-section) {
background-color: #0288D1 !important;
border-radius: 4px !important;
margin: 31px 0 0 40px !important;
border: none !important;
padding: 0 !important;
2025-08-22 19:52:05 +08:00
}
2025-08-23 19:20:14 +08:00
:deep(.n-button.collapse-button) {
width: 54px !important;
height: 22px !important;
background: transparent !important;
border: none !important;
padding: 0 !important;
color: rgba(102, 102, 102, 1) !important;
}
2025-08-22 19:52:05 +08:00
2025-08-23 19:20:14 +08:00
:deep(.n-button.collapse-button .n-button__content) {
display: flex !important;
align-items: center !important;
gap: 10px !important;
2025-08-22 19:52:05 +08:00
}
2025-08-23 19:20:14 +08:00
/* 全局输入框样式重置 */
:deep(.n-input) {
box-sizing: border-box !important;
2025-08-22 19:52:05 +08:00
}
2025-08-23 19:20:14 +08:00
:deep(.n-input .n-input-wrapper) {
box-sizing: border-box !important;
display: flex !important;
align-items: center !important;
min-height: 40px !important;
}
2025-08-22 19:52:05 +08:00
2025-08-23 19:20:14 +08:00
:deep(.n-input .n-input__input-el) {
box-sizing: border-box !important;
vertical-align: middle !important;
}
:deep(.n-input .n-input__suffix) {
box-sizing: border-box !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 100% !important;
}
:deep(.n-select .n-base-selection) {
box-sizing: border-box !important;
display: flex !important;
align-items: center !important;
}
:deep(.n-select .n-base-selection-input) {
box-sizing: border-box !important;
display: flex !important;
align-items: center !important;
}
:deep(.n-select .n-base-suffix) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 100% !important;
}
:deep(.n-input.chapter-name-input) {
width: 100% !important;
height: 42px !important;
border: 1px solid #e0e0e0 !important;
border-radius: 4px !important;
}
:deep(.n-input.chapter-name-input .n-input-wrapper) {
padding: 0 12px !important;
}
:deep(.n-input.chapter-name-input .n-input__input-el) {
line-height: 40px !important;
font-size: 14px !important;
color: #333 !important;
}
:deep(.n-input.chapter-name-input .n-input__suffix) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 100% !important;
min-width: 24px !important;
}
:deep(.n-input.lesson-input) {
width: 100% !important;
height: 42px !important;
border: 1px solid #e0e0e0 !important;
border-radius: 4px !important;
}
:deep(.n-input.lesson-input .n-input-wrapper) {
padding: 0 12px !important;
}
:deep(.n-input.lesson-input .n-input__input-el) {
line-height: 40px !important;
font-size: 14px !important;
color: #333 !important;
}
:deep(.n-input.lesson-input .n-input__suffix) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 100% !important;
min-width: 24px !important;
}
:deep(.n-input.courseware-input) {
width: 100% !important;
height: 42px !important;
border: 1px solid #e0e0e0 !important;
border-radius: 4px !important;
}
:deep(.n-input.courseware-input .n-input-wrapper) {
padding: 0 12px !important;
}
:deep(.n-input.courseware-input .n-input__input-el) {
line-height: 40px !important;
font-size: 14px !important;
color: #333 !important;
}
:deep(.n-input.courseware-input .n-input__suffix) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 100% !important;
min-width: 24px !important;
}
:deep(.n-input.homework-input) {
width: 100% !important;
height: 42px !important;
border: 1px solid #e0e0e0 !important;
border-radius: 4px !important;
}
:deep(.n-input.homework-input .n-input-wrapper) {
padding: 0 12px !important;
}
:deep(.n-input.homework-input .n-input__input-el) {
line-height: 40px !important;
font-size: 14px !important;
color: #333 !important;
}
:deep(.n-input.homework-input .n-input__suffix) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 100% !important;
min-width: 24px !important;
}
:deep(.n-select.exam-dropdown-display) {
width: 100% !important;
height: 42px !important;
border: 1px solid #e0e0e0 !important;
border-radius: 4px !important;
}
:deep(.n-select.exam-dropdown-display .n-base-selection) {
height: 42px !important;
border: none !important;
}
:deep(.n-select.exam-dropdown-display .n-base-selection-input) {
height: 40px !important;
line-height: 40px !important;
padding: 0 12px !important;
}
:deep(.n-select.exam-dropdown-display .n-base-selection-input__content) {
font-size: 14px !important;
color: #333 !important;
}
:deep(.n-select.exam-dropdown-display .n-base-suffix) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 100% !important;
padding-right: 12px !important;
min-width: 24px !important;
}
/* 课件下拉框样式 */
:deep(.n-select.courseware-input) {
width: 100% !important;
height: 42px !important;
}
:deep(.n-select.courseware-input .n-base-selection) {
height: 42px !important;
border: 1px solid #e0e0e0 !important;
border-radius: 4px !important;
box-shadow: none !important;
background: #ffffff !important;
}
:deep(.n-select.courseware-input .n-base-selection-label) {
border: none !important;
box-shadow: none !important;
background: transparent !important;
}
:deep(.n-select.courseware-input .n-base-selection-input) {
height: 40px !important;
line-height: 40px !important;
padding: 0 12px !important;
border: none !important;
box-shadow: none !important;
}
:deep(.n-select.courseware-input .n-base-selection-input__content) {
font-size: 14px !important;
color: #333 !important;
}
:deep(.n-select.courseware-input .n-base-suffix) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 100% !important;
padding-right: 12px !important;
min-width: 24px !important;
}
/* 作业下拉框样式 */
:deep(.n-select.homework-input) {
width: 100% !important;
height: 42px !important;
}
:deep(.n-select.homework-input .n-base-selection) {
height: 42px !important;
border: 1px solid #e0e0e0 !important;
border-radius: 4px !important;
box-shadow: none !important;
background: #ffffff !important;
}
:deep(.n-select.homework-input .n-base-selection-label) {
border: none !important;
box-shadow: none !important;
background: transparent !important;
}
:deep(.n-select.homework-input .n-base-selection-input) {
height: 40px !important;
line-height: 40px !important;
padding: 0 12px !important;
border: none !important;
box-shadow: none !important;
}
:deep(.n-select.homework-input .n-base-selection-input__content) {
font-size: 14px !important;
color: #333 !important;
}
:deep(.n-select.homework-input .n-base-suffix) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
height: 100% !important;
padding-right: 12px !important;
min-width: 24px !important;
}
:deep(.n-divider.chapter-divider) {
margin: 31px auto 0 !important;
width: 100% !important;
max-width: 1420px !important;
height: 1px !important;
background: #fff !important;
opacity: 1 !important;
padding: 0 30px;
}
:deep(.n-button.add-section-btn) {
width: 94px !important;
height: 23px !important;
margin: 49px 0 342px 65px !important;
background: transparent !important;
border: none !important;
padding: 0 !important;
color: rgba(2, 136, 209, 1) !important;
}
2025-08-22 19:52:05 +08:00
.block_3 {
width: 100%;
min-height: 100vh;
2025-08-23 19:20:14 +08:00
margin: 15px auto 0;
position: relative;
transition: all 0.3s ease;
}
/* 移动端菜单按钮 */
.mobile-menu-toggle {
display: none;
position: fixed;
top: 20px;
left: 20px;
z-index: 1001;
background: #0288D1;
color: white;
border: none;
border-radius: 4px;
padding: 10px;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
.menu-icon {
font-size: 18px;
font-style: normal;
}
/* 移动端关闭按钮 */
.mobile-close {
display: none;
position: absolute;
top: 15px;
right: 15px;
background: #f5f5f5;
border: none;
border-radius: 50%;
width: 30px;
height: 30px;
cursor: pointer;
align-items: center;
justify-content: center;
z-index: 1002;
}
.close-icon {
font-size: 20px;
font-style: normal;
color: #666;
2025-08-22 19:52:05 +08:00
}
.flex-col {
display: flex;
flex-direction: column;
}
.chapter-editor {
width: 273px;
min-height: 100vh;
2025-08-22 19:52:05 +08:00
border: none;
border-right: 1px solid #E6E6E6;
border-radius: 4px;
background: #FFFFFF 100% no-repeat;
background-size: 100% 100%;
transition: transform 0.3s ease;
position: relative;
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
.header-section {
width: 194px;
height: 48px;
background-color: #0288D1;
border-radius: 4px;
margin: 31px 0 0 40px;
2025-08-23 19:20:14 +08:00
display: flex;
justify-content: center;
gap: 4px;
align-items: center;
2025-08-22 19:52:05 +08:00
}
.chapter-icon {
width: 18px;
height: 18px;
}
.justify-between {
2025-08-23 19:20:14 +08:00
display: flex;
justify-content: center;
}
.justify-between2 {
2025-08-22 19:52:05 +08:00
display: flex;
justify-content: space-between;
}
.flex-row {
display: flex;
flex-direction: row;
}
.section-title {
width: 64px;
height: 18px;
overflow-wrap: break-word;
color: rgba(255, 255, 255, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 18px;
}
.chapter-item {
width: 240px;
height: 54px;
background: #F5F8FB 100% no-repeat;
background-size: 100% 100%;
margin: 23px 0 0 16px;
2025-08-25 18:28:46 +08:00
cursor: pointer;
transition: all 0.3s ease;
justify-content: space-around;
align-items: center;
}
.chapter-item.collapsed {
background: transparent;
}
.chapter-item:hover {
background: rgba(2, 136, 209, 0.05);
2025-08-22 19:52:05 +08:00
}
.chapter-arrow-icon {
2025-08-25 18:28:46 +08:00
margin-left: 10px;
2025-08-22 19:52:05 +08:00
width: 9px;
height: 11px;
transform: rotate(180deg);
2025-08-25 18:28:46 +08:00
transition: transform 0.3s ease;
2025-08-22 19:52:05 +08:00
/* 旋转图标180度 */
}
2025-08-25 18:28:46 +08:00
.chapter-arrow-icon.rotated {
width: 11px;
height: 9px;
transform: rotate(0deg);
}
2025-08-22 19:52:05 +08:00
.chapter-title {
width: 131px;
height: 21px;
overflow-wrap: break-word;
color: rgba(2, 136, 209, 1);
font-size: 18px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 21px;
2025-08-25 18:28:46 +08:00
transition: color 0.3s ease;
margin-right: 40px;
2025-09-11 14:34:30 +08:00
overflow: hidden;
text-overflow: ellipsis;
2025-08-25 18:28:46 +08:00
}
.chapter-item.collapsed .chapter-title {
color: rgba(51, 51, 51, 1);
2025-08-22 19:52:05 +08:00
}
.chapter-options-icon {
2025-08-25 18:28:46 +08:00
width: 6px;
2025-08-22 19:52:05 +08:00
height: 20px;
2025-08-25 18:28:46 +08:00
margin-right: 5px;
transition: opacity 0.3s ease;
}
.chapter-options-icon.transparent {
opacity: 0 !important;
}
.chapter-item:hover .chapter-options-icon.transparent {
opacity: 0.8 !important;
2025-08-22 19:52:05 +08:00
}
.chapter-content-item {
2025-09-11 14:34:30 +08:00
/* width: 234px; */
height: auto;
/* min-height: 90px; */
margin: 8px 8px 0 31px;
padding: 12px 8px;
border-radius: 6px;
transition: all 0.3s ease;
cursor: pointer;
}
.chapter-content-item:hover {
background: rgba(2, 136, 209, 0.08);
2025-08-22 19:52:05 +08:00
}
.content-text-group {
2025-09-11 14:34:30 +08:00
width: 100%;
height: auto;
margin: 0;
padding: 4px 0;
display: flex;
flex-direction: column;
gap: 6px;
2025-08-22 19:52:05 +08:00
}
.content-title {
2025-09-11 14:34:30 +08:00
height: auto;
2025-08-22 19:52:05 +08:00
overflow-wrap: break-word;
2025-09-11 14:34:30 +08:00
color: rgba(51, 51, 51, 1);
font-size: 15px;
2025-08-22 19:52:05 +08:00
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
2025-09-11 14:34:30 +08:00
font-weight: 600;
2025-08-22 19:52:05 +08:00
text-align: left;
2025-09-11 14:34:30 +08:00
line-height: 20px;
margin: 0;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
letter-spacing: 0.2px;
word-break: break-word;
2025-08-22 19:52:05 +08:00
}
.content-description {
2025-09-11 14:34:30 +08:00
height: auto;
2025-08-22 19:52:05 +08:00
overflow-wrap: break-word;
2025-09-11 14:34:30 +08:00
color: rgba(153, 153, 153, 1);
font-size: 13px;
2025-08-22 19:52:05 +08:00
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
line-height: 18px;
2025-09-11 14:34:30 +08:00
margin: 0;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
opacity: 0.75;
font-style: italic;
word-break: break-word;
2025-08-22 19:52:05 +08:00
}
.action-menu {
width: 102px;
height: 82px;
background-color: #FFFFFF;
border: 1px solid #E6E6E6;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin-left: -13px;
padding: 10px;
box-sizing: border-box;
display: none;
/* 默认隐藏菜单 */
}
/* 当菜单可见时显示 */
.action-menu.visible {
display: flex;
}
.action-rename {
width: 42px;
height: 17px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 17px;
margin: 3px 0 0 20px;
}
.action-delete {
width: 28px;
height: 17px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 17px;
margin: 14px 0 0 20px;
}
.chapter-detail-container {
position: relative;
flex: 1;
min-height: 100vh;
2025-08-23 19:20:14 +08:00
background: #ffffff;
padding: 0 20px;
box-sizing: border-box;
transition: margin-left 0.3s ease;
2025-08-23 19:20:14 +08:00
max-width: calc(100% - 273px);
2025-08-22 19:52:05 +08:00
}
.chapter-header {
height: 22px;
2025-08-23 19:20:14 +08:00
margin: 46px 0 0 20px;
2025-08-22 19:52:05 +08:00
}
.chapter-title-text {
width: 54px;
height: 21px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
2025-09-11 14:34:30 +08:00
font-size: 20px;
2025-08-22 19:52:05 +08:00
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
2025-09-11 14:34:30 +08:00
font-weight: 600;
2025-08-22 19:52:05 +08:00
text-align: left;
white-space: nowrap;
line-height: 21px;
}
.collapse-button {
width: 54px;
height: 22px;
2025-08-23 19:20:14 +08:00
position: relative;
right: 20px;
2025-08-22 19:52:05 +08:00
}
.collapse-text {
width: 32px;
height: 18px;
overflow-wrap: break-word;
color: rgba(102, 102, 102, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: center;
white-space: nowrap;
line-height: 18px;
}
.chapter-name-section {
2025-08-23 19:20:14 +08:00
width: 100%;
max-width: 540px;
2025-08-22 19:52:05 +08:00
height: 42px;
2025-08-23 19:20:14 +08:00
margin: 21px 0 0 20px;
display: flex;
justify-content: flex-end;
align-items: center;
2025-08-22 19:52:05 +08:00
}
.chapter-name-label {
2025-08-23 19:20:14 +08:00
width: 120px;
2025-08-22 19:52:05 +08:00
height: 18px;
overflow-wrap: break-word;
font-size: 0;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: right;
white-space: nowrap;
line-height: 18px;
margin-top: 9px;
2025-08-23 19:20:14 +08:00
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
.required-mark {
2025-08-23 19:20:14 +08:00
width: 120px;
2025-08-22 19:52:05 +08:00
height: 18px;
overflow-wrap: break-word;
color: rgba(255, 77, 79, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
2025-08-23 19:20:14 +08:00
text-align: right;
2025-08-22 19:52:05 +08:00
white-space: nowrap;
line-height: 18px;
2025-08-23 19:20:14 +08:00
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
.label-text {
2025-08-23 19:20:14 +08:00
width: 120px;
2025-08-22 19:52:05 +08:00
height: 18px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
2025-08-23 19:20:14 +08:00
text-align: right;
2025-08-22 19:52:05 +08:00
white-space: nowrap;
line-height: 18px;
2025-08-23 19:20:14 +08:00
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
.chapter-name-input-container {
2025-08-23 19:20:14 +08:00
width: 400px;
2025-08-22 19:52:05 +08:00
height: 42px;
}
2025-08-23 19:20:14 +08:00
/* 删除旧的章节名称输入框样式,使用 Naive UI 样式 */
2025-08-22 19:52:05 +08:00
.chapter-name-input:focus {
background: rgba(240, 248, 255, 0.5);
}
/* 编辑图标容器 */
/* 删除未使用的编辑图标相关样式 */
/* 课件输入框容器 */
.courseware-input-container {
2025-08-23 19:20:14 +08:00
width: 400px;
2025-08-22 19:52:05 +08:00
height: 42px;
margin: 1px 0 0 5px;
}
2025-09-11 14:34:30 +08:00
/* 课件上传选项部分 */
.courseware-upload-section {
width: 100%;
max-width: 540px;
height: 42px;
margin: 10px 0 0 20px;
display: flex;
justify-content: flex-end;
align-items: center;
}
.courseware-upload-label {
width: 120px;
height: 18px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: right;
white-space: nowrap;
line-height: 18px;
flex-shrink: 0;
}
.courseware-upload-container {
width: 400px;
height: 42px;
margin: 1px 0 0 5px;
position: relative;
}
/* 已上传课件文件部分 */
.uploaded-courseware-files-section {
width: 100%;
max-width: 540px;
height: auto;
margin: 10px 0 0 20px;
display: flex;
justify-content: flex-end;
align-items: flex-start;
}
.uploaded-courseware-files-label {
width: 120px;
height: 18px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: right;
white-space: nowrap;
line-height: 18px;
flex-shrink: 0;
margin-top: 12px;
}
2025-08-23 19:20:14 +08:00
/* 删除旧的课件输入框样式,使用 Naive UI 样式 */
2025-08-22 19:52:05 +08:00
.courseware-dropdown-icon {
position: absolute;
right: 2px;
top: 50%;
transform: translateY(-50%);
width: 16px;
height: 16px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
/* 删除未使用的 svg 样式 */
/* 考试/练习下拉框容器 */
.exam-dropdown-container {
2025-08-23 19:20:14 +08:00
width: 400px;
2025-08-22 19:52:05 +08:00
height: 42px;
margin: 1px 0 0 5px;
position: relative;
}
2025-08-23 19:20:14 +08:00
/* 删除多余的下拉框样式,使用 Naive UI 原生样式 */
2025-08-22 19:52:05 +08:00
.exam-dropdown-text {
color: rgba(102, 102, 102, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
line-height: 18px;
flex: 1;
}
.exam-dropdown-icon {
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.3s;
}
.exam-dropdown-icon.rotated {
transform: rotate(180deg);
}
/* 删除未使用的 svg 样式 */
.exam-dropdown-menu {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: #ffffff;
border: 1px solid #e0e0e0;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
z-index: 1000;
margin-top: 2px;
}
.exam-dropdown-option {
padding: 12px;
color: rgba(102, 102, 102, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
cursor: pointer;
transition: all 0.3s;
border-bottom: 1px solid #f0f0f0;
}
.exam-dropdown-option:last-child {
border-bottom: none;
}
.exam-dropdown-option:hover {
background: rgba(24, 144, 255, 0.1);
color: #1890ff;
}
/* 删除未使用的 text_26 和 thumbnail_16 样式 */
.collapse-icon {
width: 13px;
height: 8px;
2025-08-23 19:20:14 +08:00
transition: transform 0.3s ease;
flex-shrink: 0;
object-fit: contain;
transform: rotate(180deg);
}
.collapse-icon.rotated {
transform: rotate(0deg);
2025-08-22 19:52:05 +08:00
}
.chapter-content-container {
position: relative;
width: 100%;
margin-bottom: 40px;
padding: 0;
display: flex;
flex-direction: column;
gap: 30px;
2025-08-23 19:20:14 +08:00
transition: all 0.3s ease;
animation: fadeInUp 0.3s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
2025-08-22 19:52:05 +08:00
}
.chapter-divider {
margin: 31px auto 0;
2025-08-23 19:20:14 +08:00
width: 100%;
max-width: 540px;
2025-08-22 19:52:05 +08:00
height: 1px;
2025-08-23 19:20:14 +08:00
background: #CCCCCC;
2025-08-22 19:52:05 +08:00
display: block;
2025-08-23 19:20:14 +08:00
opacity: 1;
2025-08-22 19:52:05 +08:00
}
/* 删除未使用的 thumbnail_17 样式 */
.courseware-section {
2025-08-23 19:20:14 +08:00
width: 100%;
max-width: 540px;
2025-08-22 19:52:05 +08:00
height: 43px;
2025-08-23 19:20:14 +08:00
margin: 0 0 0 20px;
display: flex;
justify-content: flex-end;
align-items: center;
2025-08-22 19:52:05 +08:00
}
.courseware-label {
width: 120px;
height: 18px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: right;
white-space: nowrap;
line-height: 18px;
2025-08-23 19:20:14 +08:00
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
/* 删除未使用的样式 */
.exam-section {
2025-08-23 19:20:14 +08:00
width: 100%;
max-width: 540px;
2025-08-22 19:52:05 +08:00
height: 42px;
2025-08-23 19:20:14 +08:00
margin: 0 0 0 20px;
display: flex;
justify-content: flex-end;
align-items: center;
2025-08-22 19:52:05 +08:00
}
.exam-label {
width: 120px;
height: 18px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: right;
white-space: nowrap;
line-height: 18px;
2025-08-23 19:20:14 +08:00
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
/* 删除未使用的样式 */
.homework-section {
2025-08-23 19:20:14 +08:00
width: 100%;
max-width: 540px;
2025-08-22 19:52:05 +08:00
height: 42px;
2025-08-23 19:20:14 +08:00
margin: 0 0 0 20px;
2025-08-22 19:52:05 +08:00
margin-bottom: -30px;
2025-08-23 19:20:14 +08:00
display: flex;
justify-content: flex-end;
align-items: center;
2025-08-22 19:52:05 +08:00
}
.homework-label {
width: 120px;
height: 18px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: right;
white-space: nowrap;
line-height: 18px;
2025-08-23 19:20:14 +08:00
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
2025-08-25 18:28:46 +08:00
/* 文件上传相关样式 */
.file-input {
display: none;
}
.uploaded-files-section {
width: 100%;
max-width: 540px;
height: auto;
margin: 10px 0 0 20px;
display: flex;
justify-content: flex-end;
align-items: flex-start;
}
.uploaded-files-label {
width: 120px;
height: 18px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: right;
white-space: nowrap;
line-height: 18px;
flex-shrink: 0;
margin-top: 12px;
}
.uploaded-files-container {
width: 400px;
margin: 1px 0 0 5px;
display: flex;
flex-direction: column;
gap: 8px;
}
.file-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
background: #f5f5f5;
border-radius: 4px;
border: 1px solid #e0e0e0;
}
.file-name {
color: #333;
font-size: 14px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
flex: 1;
margin-right: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.remove-file-btn {
background: none;
border: none;
cursor: pointer;
padding: 2px;
border-radius: 2px;
transition: background-color 0.3s ease;
}
.remove-file-btn:hover {
background: rgba(255, 77, 79, 0.1);
}
2025-08-22 19:52:05 +08:00
/* 删除未使用的样式 */
/* 删除未使用的 text-group_9 样式 */
.lesson-section {
position: relative;
2025-08-23 19:20:14 +08:00
width: 100%;
max-width: 540px;
2025-08-22 19:52:05 +08:00
height: 42px;
2025-08-23 19:20:14 +08:00
margin: 0 0 0 20px;
display: flex;
justify-content: flex-end;
align-items: center;
2025-08-22 19:52:05 +08:00
}
.lesson-label-wrapper {
width: 120px;
height: 18px;
overflow-wrap: break-word;
font-size: 0;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: right;
white-space: nowrap;
line-height: 18px;
2025-08-23 19:20:14 +08:00
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
.lesson-required-mark {
width: 120px;
height: 18px;
overflow-wrap: break-word;
color: rgba(255, 77, 79, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
2025-08-23 19:20:14 +08:00
text-align: right;
2025-08-22 19:52:05 +08:00
white-space: nowrap;
line-height: 18px;
2025-08-23 19:20:14 +08:00
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
.lesson-label-text {
width: 120px;
height: 18px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
2025-08-23 19:20:14 +08:00
text-align: right;
2025-08-22 19:52:05 +08:00
white-space: nowrap;
line-height: 18px;
2025-08-23 19:20:14 +08:00
flex-shrink: 0;
2025-08-22 19:52:05 +08:00
}
/* 作业输入框容器 */
.homework-input-container {
2025-08-23 19:20:14 +08:00
width: 400px;
2025-08-22 19:52:05 +08:00
height: 42px;
margin: 1px 0 0 5px;
}
.homework-input {
width: calc(100% - 40px);
height: 100%;
border: none;
background: transparent;
color: rgba(102, 102, 102, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
line-height: 18px;
outline: none;
}
.homework-dropdown-icon {
position: absolute;
right: 0px;
top: 50%;
transform: translateY(-50%);
width: 16px;
height: 16px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
/* 课节输入框容器 */
.lesson-input-container {
margin-left: 4px;
2025-08-23 19:20:14 +08:00
width: 400px;
2025-08-22 19:52:05 +08:00
height: 42px;
}
/* 课节图片样式 */
.lesson-icon {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
width: 16px;
height: 16px;
}
.chapter-container {
2025-08-23 19:20:14 +08:00
margin-top: 20px;
border: 1px solid #EDEDED;
padding-bottom: 20px;
}
2025-08-23 19:20:14 +08:00
.add-section-btn {
width: 94px;
height: 23px;
margin: 49px 0 342px 65px;
}
2025-08-23 19:20:14 +08:00
.add-section-icon {
width: 22px;
height: 22px;
margin-top: 1px;
}
2025-08-23 19:20:14 +08:00
.add-section-text {
width: 64px;
height: 18px;
overflow-wrap: break-word;
color: rgba(2, 136, 209, 1);
font-size: 16px;
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 18px;
}
2025-08-22 19:52:05 +08:00
</style>