feat: 增强课程搜索功能,添加分类筛选
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
yuliang_guo
2026-01-30 16:27:34 +08:00
parent 920c6a64c8
commit b2e1ed02d1

View File

@@ -252,17 +252,6 @@
<div class="course-config-panel">
<div class="panel-header">
<h3>课程配置</h3>
<el-input
v-model="courseSearch"
placeholder="搜索课程"
clearable
style="width: 200px"
@input="handleCourseSearch"
>
<template #prefix>
<el-icon><Search /></el-icon>
</template>
</el-input>
</div>
<!-- 课程库 -->
@@ -271,6 +260,33 @@
<span>可选课程</span>
<el-tag size="small">{{ filteredCourses.length }} </el-tag>
</div>
<!-- 搜索和筛选 -->
<div class="course-filter">
<el-input
v-model="courseSearch"
placeholder="搜索课程名称..."
clearable
size="small"
>
<template #prefix>
<el-icon><Search /></el-icon>
</template>
</el-input>
<el-select
v-model="courseCategory"
placeholder="分类筛选"
clearable
size="small"
style="width: 120px"
>
<el-option
v-for="cat in courseCategories"
:key="cat"
:label="cat"
:value="cat"
/>
</el-select>
</div>
<div class="library-content" v-loading="coursesLoading">
<div
v-for="course in filteredCourses"
@@ -463,6 +479,7 @@ const filters = ref<{
// 编辑状态
const editingPath = ref<EditingPath | null>(null)
const courseSearch = ref('')
const courseCategory = ref('')
const isDragging = ref(false)
const isDraggingOver = ref(false)
@@ -471,13 +488,33 @@ const positions = ref<Position[]>([])
const courses = ref<Course[]>([])
// ========== 计算属性 ==========
// 获取所有课程分类
const courseCategories = computed(() => {
const categories = new Set<string>()
courses.value.forEach(c => {
if (c.category) categories.add(c.category)
})
return Array.from(categories).sort()
})
const filteredCourses = computed(() => {
if (!courseSearch.value) return courses.value
let result = courses.value
// 按分类筛选
if (courseCategory.value) {
result = result.filter(c => c.category === courseCategory.value)
}
// 按关键词搜索
if (courseSearch.value) {
const keyword = courseSearch.value.toLowerCase()
return courses.value.filter(c =>
result = result.filter(c =>
(c.name || c.title || '').toLowerCase().includes(keyword) ||
(c.category || '').toLowerCase().includes(keyword)
)
}
return result
})
const requiredCount = computed(() => {
@@ -1083,6 +1120,18 @@ onMounted(() => {
font-weight: 500;
}
.course-filter {
display: flex;
gap: 8px;
padding: 12px 16px;
background: #f5f7fa;
border-bottom: 1px solid #ebeef5;
.el-input {
flex: 1;
}
}
.library-content,
.selected-content {
flex: 1;