hookehuyr

feat(teacher/form): 添加课程章节选择功能并优化表单字段显示

- 在作业表单中新增课程章节选择器及相关逻辑
- 将日历图标替换为更符合语义的图标
- 为必填字段添加提示标识
- 优化选择字段的显示样式,增加选中值展示区域
...@@ -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 /* 提交按钮 */
......