feat(teacher/form): 添加课程章节选择功能并优化表单字段显示
- 在作业表单中新增课程章节选择器及相关逻辑 - 将日历图标替换为更符合语义的图标 - 为必填字段添加提示标识 - 优化选择字段的显示样式,增加选中值展示区域
Showing
1 changed file
with
115 additions
and
5 deletions
| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | * @Author: hookehuyr hookehuyr@gmail.com | 2 | * @Author: hookehuyr hookehuyr@gmail.com |
| 3 | * @Date: 2025-01-20 10:00:00 | 3 | * @Date: 2025-01-20 10:00:00 |
| 4 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 4 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 5 | - * @LastEditTime: 2025-06-20 15:43:37 | 5 | + * @LastEditTime: 2025-06-20 16:01:50 |
| 6 | * @FilePath: /mlaj/src/views/teacher/formPage.vue | 6 | * @FilePath: /mlaj/src/views/teacher/formPage.vue |
| 7 | * @Description: 教师作业新增表单页面 | 7 | * @Description: 教师作业新增表单页面 |
| 8 | --> | 8 | --> |
| ... | @@ -18,7 +18,7 @@ | ... | @@ -18,7 +18,7 @@ |
| 18 | <van-field | 18 | <van-field |
| 19 | v-model="formData.homework_name" | 19 | v-model="formData.homework_name" |
| 20 | name="homework_name" | 20 | name="homework_name" |
| 21 | - placeholder="请输入作业名称" | 21 | + placeholder="请输入作业名称(必填)" |
| 22 | required | 22 | required |
| 23 | :border="false" | 23 | :border="false" |
| 24 | class="homework-name-field" | 24 | class="homework-name-field" |
| ... | @@ -100,25 +100,52 @@ | ... | @@ -100,25 +100,52 @@ |
| 100 | <div class="mb-6"> | 100 | <div class="mb-6"> |
| 101 | <div class="select-row"> | 101 | <div class="select-row"> |
| 102 | <div class="select-item"> | 102 | <div class="select-item"> |
| 103 | - <van-icon name="calendar-o" class="select-icon" /> | 103 | + <van-icon name="friends-o" class="select-icon" /> |
| 104 | <span class="select-label">所在年级:</span> | 104 | <span class="select-label">所在年级:</span> |
| 105 | + <span class="select-value" @click="showGradePicker = true">{{ formData.grade || '请选择年级' }}</span> | ||
| 105 | <van-icon name="arrow" class="arrow-icon" @click="showGradePicker = true" /> | 106 | <van-icon name="arrow" class="arrow-icon" @click="showGradePicker = true" /> |
| 106 | </div> | 107 | </div> |
| 107 | </div> | 108 | </div> |
| 108 | <div class="select-row"> | 109 | <div class="select-row"> |
| 109 | <div class="select-item"> | 110 | <div class="select-item"> |
| 110 | - <van-icon name="calendar-o" class="select-icon" /> | 111 | + <van-icon name="friends-o" class="select-icon" /> |
| 111 | <span class="select-label">所在班级:</span> | 112 | <span class="select-label">所在班级:</span> |
| 113 | + <span class="select-value" @click="showClassPicker = true">{{ formData.class_name || '请选择班级' }}</span> | ||
| 112 | <van-icon name="arrow" class="arrow-icon" @click="showClassPicker = true" /> | 114 | <van-icon name="arrow" class="arrow-icon" @click="showClassPicker = true" /> |
| 113 | </div> | 115 | </div> |
| 114 | </div> | 116 | </div> |
| 115 | <div class="select-row"> | 117 | <div class="select-row"> |
| 116 | <div class="select-item"> | 118 | <div class="select-item"> |
| 117 | - <van-icon name="calendar-o" class="select-icon" /> | 119 | + <van-icon name="friends-o" class="select-icon" /> |
| 118 | <span class="select-label">所在课程:</span> | 120 | <span class="select-label">所在课程:</span> |
| 121 | + <span class="select-value" @click="showCoursePicker = true">{{ formData.course || '请选择课程' }}</span> | ||
| 119 | <van-icon name="arrow" class="arrow-icon" @click="showCoursePicker = true" /> | 122 | <van-icon name="arrow" class="arrow-icon" @click="showCoursePicker = true" /> |
| 120 | </div> | 123 | </div> |
| 121 | </div> | 124 | </div> |
| 125 | + <div class="select-row" v-if="formData.course"> | ||
| 126 | + <div class="select-item"> | ||
| 127 | + <van-icon name="bookmark-o" class="select-icon" /> | ||
| 128 | + <span class="select-label">课程章节:</span> | ||
| 129 | + <span class="select-value" @click="showChapterPicker = true">{{ formData.chapter || '请选择章节' }}</span> | ||
| 130 | + <van-icon name="arrow" class="arrow-icon" @click="showChapterPicker = true" /> | ||
| 131 | + </div> | ||
| 132 | + </div> | ||
| 133 | + <div class="select-row"> | ||
| 134 | + <div class="select-item"> | ||
| 135 | + <van-icon name="fire-o" class="select-icon" /> | ||
| 136 | + <span class="select-label">所在活动:</span> | ||
| 137 | + <span class="select-value" @click="showActivityPicker = true">{{ formData.activity || '请选择活动' }}</span> | ||
| 138 | + <van-icon name="arrow" class="arrow-icon" @click="showActivityPicker = true" /> | ||
| 139 | + </div> | ||
| 140 | + </div> | ||
| 141 | + <div class="select-row"> | ||
| 142 | + <div class="select-item"> | ||
| 143 | + <van-icon name="friends-o" class="select-icon" /> | ||
| 144 | + <span class="select-label">所在小组:</span> | ||
| 145 | + <span class="select-value" @click="showGroupPicker = true">{{ formData.group_name || '请选择小组' }}</span> | ||
| 146 | + <van-icon name="arrow" class="arrow-icon" @click="showGroupPicker = true" /> | ||
| 147 | + </div> | ||
| 148 | + </div> | ||
| 122 | </div> | 149 | </div> |
| 123 | 150 | ||
| 124 | <!-- 提交按钮 --> | 151 | <!-- 提交按钮 --> |
| ... | @@ -174,6 +201,17 @@ | ... | @@ -174,6 +201,17 @@ |
| 174 | </div> | 201 | </div> |
| 175 | </van-popup> | 202 | </van-popup> |
| 176 | 203 | ||
| 204 | + <!-- 课程章节选择器 --> | ||
| 205 | + <van-popup v-model:show="showChapterPicker" position="bottom"> | ||
| 206 | + <div class="p-4"> | ||
| 207 | + <van-search v-model="chapterSearchValue" placeholder="搜索章节" @search="searchChapter" /> | ||
| 208 | + <van-list> | ||
| 209 | + <van-cell v-for="chapter in filteredChapters" :key="chapter.id" :title="chapter.name" is-link :border="false" | ||
| 210 | + @click="onChapterSelect(chapter)" /> | ||
| 211 | + </van-list> | ||
| 212 | + </div> | ||
| 213 | + </van-popup> | ||
| 214 | + | ||
| 177 | <!-- 活动选择器 --> | 215 | <!-- 活动选择器 --> |
| 178 | <van-popup v-model:show="showActivityPicker" position="bottom"> | 216 | <van-popup v-model:show="showActivityPicker" position="bottom"> |
| 179 | <div class="p-4"> | 217 | <div class="p-4"> |
| ... | @@ -244,6 +282,7 @@ const formData = ref({ | ... | @@ -244,6 +282,7 @@ const formData = ref({ |
| 244 | start_time: new Date(), | 282 | start_time: new Date(), |
| 245 | end_time: new Date(), | 283 | end_time: new Date(), |
| 246 | course: '', | 284 | course: '', |
| 285 | + chapter: '', | ||
| 247 | activity: '', | 286 | activity: '', |
| 248 | grade: '', | 287 | grade: '', |
| 249 | class_name: '', | 288 | class_name: '', |
| ... | @@ -259,6 +298,7 @@ const showFrequencyPicker = ref(false); | ... | @@ -259,6 +298,7 @@ const showFrequencyPicker = ref(false); |
| 259 | const showStartTimePicker = ref(false); | 298 | const showStartTimePicker = ref(false); |
| 260 | const showEndTimePicker = ref(false); | 299 | const showEndTimePicker = ref(false); |
| 261 | const showCoursePicker = ref(false); | 300 | const showCoursePicker = ref(false); |
| 301 | +const showChapterPicker = ref(false); | ||
| 262 | const showActivityPicker = ref(false); | 302 | const showActivityPicker = ref(false); |
| 263 | const showGradePicker = ref(false); | 303 | const showGradePicker = ref(false); |
| 264 | const showClassPicker = ref(false); | 304 | const showClassPicker = ref(false); |
| ... | @@ -287,6 +327,7 @@ const frequencyOptions = ref([ | ... | @@ -287,6 +327,7 @@ const frequencyOptions = ref([ |
| 287 | 327 | ||
| 288 | // 搜索值 | 328 | // 搜索值 |
| 289 | const courseSearchValue = ref(''); | 329 | const courseSearchValue = ref(''); |
| 330 | +const chapterSearchValue = ref(''); | ||
| 290 | const activitySearchValue = ref(''); | 331 | const activitySearchValue = ref(''); |
| 291 | const gradeSearchValue = ref(''); | 332 | const gradeSearchValue = ref(''); |
| 292 | const classSearchValue = ref(''); | 333 | const classSearchValue = ref(''); |
| ... | @@ -300,6 +341,37 @@ const courses = ref([ | ... | @@ -300,6 +341,37 @@ const courses = ref([ |
| 300 | { id: 4, name: '物理课程' } | 341 | { id: 4, name: '物理课程' } |
| 301 | ]); | 342 | ]); |
| 302 | 343 | ||
| 344 | +// 章节数据 - 根据课程动态变化 | ||
| 345 | +const chapters = ref([]); | ||
| 346 | + | ||
| 347 | +// 各课程对应的章节数据 | ||
| 348 | +const courseChapters = { | ||
| 349 | + '数学课程': [ | ||
| 350 | + { id: 1, name: '第一章 数与代数' }, | ||
| 351 | + { id: 2, name: '第二章 几何图形' }, | ||
| 352 | + { id: 3, name: '第三章 统计与概率' }, | ||
| 353 | + { id: 4, name: '第四章 函数与方程' } | ||
| 354 | + ], | ||
| 355 | + '语文课程': [ | ||
| 356 | + { id: 1, name: '第一单元 现代文阅读' }, | ||
| 357 | + { id: 2, name: '第二单元 古诗文阅读' }, | ||
| 358 | + { id: 3, name: '第三单元 写作训练' }, | ||
| 359 | + { id: 4, name: '第四单元 口语交际' } | ||
| 360 | + ], | ||
| 361 | + '英语课程': [ | ||
| 362 | + { id: 1, name: 'Unit 1 Hello World' }, | ||
| 363 | + { id: 2, name: 'Unit 2 My Family' }, | ||
| 364 | + { id: 3, name: 'Unit 3 School Life' }, | ||
| 365 | + { id: 4, name: 'Unit 4 Hobbies' } | ||
| 366 | + ], | ||
| 367 | + '物理课程': [ | ||
| 368 | + { id: 1, name: '第一章 力学基础' }, | ||
| 369 | + { id: 2, name: '第二章 热学原理' }, | ||
| 370 | + { id: 3, name: '第三章 电磁学' }, | ||
| 371 | + { id: 4, name: '第四章 光学现象' } | ||
| 372 | + ] | ||
| 373 | +}; | ||
| 374 | + | ||
| 303 | const activities = ref([ | 375 | const activities = ref([ |
| 304 | { id: 1, name: '春游活动' }, | 376 | { id: 1, name: '春游活动' }, |
| 305 | { id: 2, name: '运动会' }, | 377 | { id: 2, name: '运动会' }, |
| ... | @@ -347,6 +419,13 @@ const filteredCourses = computed(() => { | ... | @@ -347,6 +419,13 @@ const filteredCourses = computed(() => { |
| 347 | ); | 419 | ); |
| 348 | }); | 420 | }); |
| 349 | 421 | ||
| 422 | +const filteredChapters = computed(() => { | ||
| 423 | + if (!chapterSearchValue.value) return chapters.value; | ||
| 424 | + return chapters.value.filter(chapter => | ||
| 425 | + chapter.name.toLowerCase().includes(chapterSearchValue.value.toLowerCase()) | ||
| 426 | + ); | ||
| 427 | +}); | ||
| 428 | + | ||
| 350 | const filteredActivities = computed(() => { | 429 | const filteredActivities = computed(() => { |
| 351 | if (!activitySearchValue.value) return activities.value; | 430 | if (!activitySearchValue.value) return activities.value; |
| 352 | return activities.value.filter(activity => | 431 | return activities.value.filter(activity => |
| ... | @@ -431,11 +510,25 @@ const onEndTimeConfirm = () => { | ... | @@ -431,11 +510,25 @@ const onEndTimeConfirm = () => { |
| 431 | */ | 510 | */ |
| 432 | const onCourseSelect = (course) => { | 511 | const onCourseSelect = (course) => { |
| 433 | formData.value.course = course.name; | 512 | formData.value.course = course.name; |
| 513 | + // 清空之前选择的章节 | ||
| 514 | + formData.value.chapter = ''; | ||
| 515 | + // 根据选择的课程更新章节数据 | ||
| 516 | + chapters.value = courseChapters[course.name] || []; | ||
| 434 | showCoursePicker.value = false; | 517 | showCoursePicker.value = false; |
| 435 | courseSearchValue.value = ''; | 518 | courseSearchValue.value = ''; |
| 436 | }; | 519 | }; |
| 437 | 520 | ||
| 438 | /** | 521 | /** |
| 522 | + * 章节选择 | ||
| 523 | + * @param {Object} chapter - 选中的章节 | ||
| 524 | + */ | ||
| 525 | +const onChapterSelect = (chapter) => { | ||
| 526 | + formData.value.chapter = chapter.name; | ||
| 527 | + showChapterPicker.value = false; | ||
| 528 | + chapterSearchValue.value = ''; | ||
| 529 | +}; | ||
| 530 | + | ||
| 531 | +/** | ||
| 439 | * 活动选择 | 532 | * 活动选择 |
| 440 | * @param {Object} activity - 选中的活动 | 533 | * @param {Object} activity - 选中的活动 |
| 441 | */ | 534 | */ |
| ... | @@ -484,6 +577,14 @@ const searchCourse = (value) => { | ... | @@ -484,6 +577,14 @@ const searchCourse = (value) => { |
| 484 | }; | 577 | }; |
| 485 | 578 | ||
| 486 | /** | 579 | /** |
| 580 | + * 搜索章节 | ||
| 581 | + * @param {string} value - 搜索值 | ||
| 582 | + */ | ||
| 583 | +const searchChapter = (value) => { | ||
| 584 | + chapterSearchValue.value = value; | ||
| 585 | +}; | ||
| 586 | + | ||
| 587 | +/** | ||
| 487 | * 搜索活动 | 588 | * 搜索活动 |
| 488 | * @param {string} value - 搜索值 | 589 | * @param {string} value - 搜索值 |
| 489 | */ | 590 | */ |
| ... | @@ -700,7 +801,16 @@ onMounted(() => { | ... | @@ -700,7 +801,16 @@ onMounted(() => { |
| 700 | .select-label { | 801 | .select-label { |
| 701 | font-size: 14px; | 802 | font-size: 14px; |
| 702 | color: #333; | 803 | color: #333; |
| 804 | + margin-right: 12px; | ||
| 805 | + min-width: 80px; | ||
| 806 | +} | ||
| 807 | + | ||
| 808 | +.select-value { | ||
| 809 | + font-size: 14px; | ||
| 810 | + color: #666; | ||
| 703 | margin-right: auto; | 811 | margin-right: auto; |
| 812 | + flex: 1; | ||
| 813 | + text-align: right; | ||
| 704 | } | 814 | } |
| 705 | 815 | ||
| 706 | /* 提交按钮 */ | 816 | /* 提交按钮 */ | ... | ... |
-
Please register or login to post a comment