feat(教师表单): 实现批量选择课程章节并设置时间功能
添加批量选择章节功能,支持多选章节并为每个章节设置开始和结束时间 优化章节选择器UI,增加时间设置区域 添加时间验证逻辑,确保开始时间不晚于结束时间
Showing
1 changed file
with
350 additions
and
33 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-23 09:49:16 | 5 | + * @LastEditTime: 2025-06-23 11:38:17 |
| 6 | * @FilePath: /mlaj/src/views/teacher/formPage.vue | 6 | * @FilePath: /mlaj/src/views/teacher/formPage.vue |
| 7 | * @Description: 教师作业新增表单页面 | 7 | * @Description: 教师作业新增表单页面 |
| 8 | --> | 8 | --> |
| ... | @@ -122,11 +122,13 @@ | ... | @@ -122,11 +122,13 @@ |
| 122 | <van-icon name="arrow" class="arrow-icon" @click="showCoursePicker = true" /> | 122 | <van-icon name="arrow" class="arrow-icon" @click="showCoursePicker = true" /> |
| 123 | </div> | 123 | </div> |
| 124 | </div> | 124 | </div> |
| 125 | - <div class="select-row"> | 125 | + <div class="select-row" v-if="formData.course"> |
| 126 | <div class="select-item"> | 126 | <div class="select-item"> |
| 127 | <van-icon name="bookmark-o" class="select-icon" /> | 127 | <van-icon name="bookmark-o" class="select-icon" /> |
| 128 | <span class="select-label">课程章节:</span> | 128 | <span class="select-label">课程章节:</span> |
| 129 | - <span class="select-value" @click="showChapterPicker = true">{{ formData.chapter || '请选择章节' }}</span> | 129 | + <span class="select-value" @click="showChapterPicker = true"> |
| 130 | + {{ selectedChaptersDisplay || '请选择章节' }} | ||
| 131 | + </span> | ||
| 130 | <van-icon name="arrow" class="arrow-icon" @click="showChapterPicker = true" /> | 132 | <van-icon name="arrow" class="arrow-icon" @click="showChapterPicker = true" /> |
| 131 | </div> | 133 | </div> |
| 132 | </div> | 134 | </div> |
| ... | @@ -202,16 +204,70 @@ | ... | @@ -202,16 +204,70 @@ |
| 202 | </van-popup> | 204 | </van-popup> |
| 203 | 205 | ||
| 204 | <!-- 课程章节选择器 --> | 206 | <!-- 课程章节选择器 --> |
| 205 | - <van-popup v-model:show="showChapterPicker" position="bottom"> | 207 | + <van-popup v-model:show="showChapterPicker" position="bottom" class="chapter-picker-popup"> |
| 206 | - <div class="p-4"> | 208 | + <div class="chapter-picker-container"> |
| 207 | - <van-search v-model="chapterSearchValue" placeholder="搜索章节" @search="searchChapter" /> | 209 | + <div class="picker-header"> |
| 208 | - <van-list> | 210 | + <h3>批量设置课程章节</h3> |
| 209 | - <van-cell v-for="chapter in filteredChapters" :key="chapter.id" :title="chapter.name" is-link :border="false" | 211 | + <van-search v-model="chapterSearchValue" placeholder="搜索章节" @search="searchChapter" /> |
| 210 | - @click="onChapterSelect(chapter)" /> | 212 | + </div> |
| 211 | - </van-list> | 213 | + |
| 214 | + <div class="chapter-list"> | ||
| 215 | + <div v-for="chapter in filteredAvailableChapters" :key="chapter.id" class="chapter-item"> | ||
| 216 | + <van-checkbox | ||
| 217 | + v-model="chapter.selected" | ||
| 218 | + @change="onChapterToggle(chapter)" | ||
| 219 | + class="chapter-checkbox" | ||
| 220 | + > | ||
| 221 | + {{ chapter.name }} | ||
| 222 | + </van-checkbox> | ||
| 223 | + | ||
| 224 | + <!-- 时间设置区域 --> | ||
| 225 | + <div v-if="chapter.selected" class="time-settings"> | ||
| 226 | + <div class="time-row"> | ||
| 227 | + <span class="time-label">开始时间:</span> | ||
| 228 | + <van-field | ||
| 229 | + v-model="chapter.startTime" | ||
| 230 | + readonly | ||
| 231 | + placeholder="请选择开始时间" | ||
| 232 | + @click="openTimePicker(chapter, 'start')" | ||
| 233 | + class="time-field" | ||
| 234 | + /> | ||
| 235 | + </div> | ||
| 236 | + <div class="time-row"> | ||
| 237 | + <span class="time-label">结束时间:</span> | ||
| 238 | + <van-field | ||
| 239 | + v-model="chapter.endTime" | ||
| 240 | + readonly | ||
| 241 | + placeholder="请选择结束时间" | ||
| 242 | + @click="openTimePicker(chapter, 'end')" | ||
| 243 | + class="time-field" | ||
| 244 | + /> | ||
| 245 | + </div> | ||
| 246 | + </div> | ||
| 247 | + </div> | ||
| 248 | + </div> | ||
| 249 | + | ||
| 250 | + <div class="picker-footer"> | ||
| 251 | + <van-button @click="cancelChapterSelection" class="cancel-btn">取消</van-button> | ||
| 252 | + <van-button type="primary" @click="confirmChapterSelection" class="confirm-btn"> | ||
| 253 | + 确认选择 ({{ selectedChaptersCount }}个章节) | ||
| 254 | + </van-button> | ||
| 255 | + </div> | ||
| 212 | </div> | 256 | </div> |
| 213 | </van-popup> | 257 | </van-popup> |
| 214 | 258 | ||
| 259 | + <!-- 时间选择器 --> | ||
| 260 | + <van-popup v-model:show="showChapterTimePicker" position="bottom"> | ||
| 261 | + <van-date-picker | ||
| 262 | + v-model="currentChapterTime" | ||
| 263 | + title="选择时间" | ||
| 264 | + :min-date="minDate" | ||
| 265 | + :max-date="maxDate" | ||
| 266 | + @confirm="onChapterTimeConfirm" | ||
| 267 | + @cancel="showChapterTimePicker = false" | ||
| 268 | + /> | ||
| 269 | + </van-popup> | ||
| 270 | + | ||
| 215 | <!-- 活动选择器 --> | 271 | <!-- 活动选择器 --> |
| 216 | <van-popup v-model:show="showActivityPicker" position="bottom"> | 272 | <van-popup v-model:show="showActivityPicker" position="bottom"> |
| 217 | <div class="p-4"> | 273 | <div class="p-4"> |
| ... | @@ -299,6 +355,7 @@ const showStartTimePicker = ref(false); | ... | @@ -299,6 +355,7 @@ const showStartTimePicker = ref(false); |
| 299 | const showEndTimePicker = ref(false); | 355 | const showEndTimePicker = ref(false); |
| 300 | const showCoursePicker = ref(false); | 356 | const showCoursePicker = ref(false); |
| 301 | const showChapterPicker = ref(false); | 357 | const showChapterPicker = ref(false); |
| 358 | +const showChapterTimePicker = ref(false); | ||
| 302 | const showActivityPicker = ref(false); | 359 | const showActivityPicker = ref(false); |
| 303 | const showGradePicker = ref(false); | 360 | const showGradePicker = ref(false); |
| 304 | const showClassPicker = ref(false); | 361 | const showClassPicker = ref(false); |
| ... | @@ -341,25 +398,44 @@ const courses = ref([ | ... | @@ -341,25 +398,44 @@ const courses = ref([ |
| 341 | { id: 4, name: '物理课程' } | 398 | { id: 4, name: '物理课程' } |
| 342 | ]); | 399 | ]); |
| 343 | 400 | ||
| 344 | -// 章节数据 - 独立的章节列表,不与课程关联 | 401 | +// 章节数据 - 根据课程动态变化 |
| 345 | -const chapters = ref([ | 402 | +const chapters = ref([]); |
| 346 | - { id: 1, name: '第一章 数与代数' }, | 403 | + |
| 347 | - { id: 2, name: '第二章 几何图形' }, | 404 | +// 各课程对应的章节数据 |
| 348 | - { id: 3, name: '第三章 统计与概率' }, | 405 | +const courseChapters = { |
| 349 | - { id: 4, name: '第四章 函数与方程' }, | 406 | + '数学课程': [ |
| 350 | - { id: 5, name: '第一单元 现代文阅读' }, | 407 | + { id: 1, name: '第一章 数与代数', selected: false, startTime: '', endTime: '' }, |
| 351 | - { id: 6, name: '第二单元 古诗文阅读' }, | 408 | + { id: 2, name: '第二章 几何图形', selected: false, startTime: '', endTime: '' }, |
| 352 | - { id: 7, name: '第三单元 写作训练' }, | 409 | + { id: 3, name: '第三章 统计与概率', selected: false, startTime: '', endTime: '' }, |
| 353 | - { id: 8, name: '第四单元 口语交际' }, | 410 | + { id: 4, name: '第四章 函数与方程', selected: false, startTime: '', endTime: '' } |
| 354 | - { id: 9, name: 'Unit 1 Hello World' }, | 411 | + ], |
| 355 | - { id: 10, name: 'Unit 2 My Family' }, | 412 | + '语文课程': [ |
| 356 | - { id: 11, name: 'Unit 3 School Life' }, | 413 | + { id: 5, name: '第一单元 现代文阅读', selected: false, startTime: '', endTime: '' }, |
| 357 | - { id: 12, name: 'Unit 4 Hobbies' }, | 414 | + { id: 6, name: '第二单元 古诗文阅读', selected: false, startTime: '', endTime: '' }, |
| 358 | - { id: 13, name: '第一章 力学基础' }, | 415 | + { id: 7, name: '第三单元 写作训练', selected: false, startTime: '', endTime: '' }, |
| 359 | - { id: 14, name: '第二章 热学原理' }, | 416 | + { id: 8, name: '第四单元 口语交际', selected: false, startTime: '', endTime: '' } |
| 360 | - { id: 15, name: '第三章 电磁学' }, | 417 | + ], |
| 361 | - { id: 16, name: '第四章 光学现象' } | 418 | + '英语课程': [ |
| 362 | -]); | 419 | + { id: 9, name: 'Unit 1 Hello World', selected: false, startTime: '', endTime: '' }, |
| 420 | + { id: 10, name: 'Unit 2 My Family', selected: false, startTime: '', endTime: '' }, | ||
| 421 | + { id: 11, name: 'Unit 3 School Life', selected: false, startTime: '', endTime: '' }, | ||
| 422 | + { id: 12, name: 'Unit 4 Hobbies', selected: false, startTime: '', endTime: '' } | ||
| 423 | + ], | ||
| 424 | + '物理课程': [ | ||
| 425 | + { id: 13, name: '第一章 力学基础', selected: false, startTime: '', endTime: '' }, | ||
| 426 | + { id: 14, name: '第二章 热学原理', selected: false, startTime: '', endTime: '' }, | ||
| 427 | + { id: 15, name: '第三章 电磁学', selected: false, startTime: '', endTime: '' }, | ||
| 428 | + { id: 16, name: '第四章 光学现象', selected: false, startTime: '', endTime: '' } | ||
| 429 | + ] | ||
| 430 | +}; | ||
| 431 | + | ||
| 432 | +// 已选择的章节列表 | ||
| 433 | +const selectedChapters = ref([]); | ||
| 434 | + | ||
| 435 | +// 当前时间选择相关 | ||
| 436 | +const currentChapterTime = ref(['2024', '01', '01']); | ||
| 437 | +const currentChapter = ref(null); | ||
| 438 | +const currentTimeType = ref(''); // 'start' or 'end' | ||
| 363 | 439 | ||
| 364 | const activities = ref([ | 440 | const activities = ref([ |
| 365 | { id: 1, name: '春游活动' }, | 441 | { id: 1, name: '春游活动' }, |
| ... | @@ -415,6 +491,27 @@ const filteredChapters = computed(() => { | ... | @@ -415,6 +491,27 @@ const filteredChapters = computed(() => { |
| 415 | ); | 491 | ); |
| 416 | }); | 492 | }); |
| 417 | 493 | ||
| 494 | +// 可选择的章节列表(根据当前课程) | ||
| 495 | +const filteredAvailableChapters = computed(() => { | ||
| 496 | + if (!chapterSearchValue.value) return chapters.value; | ||
| 497 | + return chapters.value.filter(chapter => | ||
| 498 | + chapter.name.toLowerCase().includes(chapterSearchValue.value.toLowerCase()) | ||
| 499 | + ); | ||
| 500 | +}); | ||
| 501 | + | ||
| 502 | +// 已选择章节的显示文本 | ||
| 503 | +const selectedChaptersDisplay = computed(() => { | ||
| 504 | + const count = selectedChapters.value.length; | ||
| 505 | + if (count === 0) return ''; | ||
| 506 | + if (count === 1) return selectedChapters.value[0].name; | ||
| 507 | + return `已选择 ${count} 个章节`; | ||
| 508 | +}); | ||
| 509 | + | ||
| 510 | +// 已选择章节数量 | ||
| 511 | +const selectedChaptersCount = computed(() => { | ||
| 512 | + return chapters.value.filter(chapter => chapter.selected).length; | ||
| 513 | +}); | ||
| 514 | + | ||
| 418 | const filteredActivities = computed(() => { | 515 | const filteredActivities = computed(() => { |
| 419 | if (!activitySearchValue.value) return activities.value; | 516 | if (!activitySearchValue.value) return activities.value; |
| 420 | return activities.value.filter(activity => | 517 | return activities.value.filter(activity => |
| ... | @@ -499,21 +596,122 @@ const onEndTimeConfirm = () => { | ... | @@ -499,21 +596,122 @@ const onEndTimeConfirm = () => { |
| 499 | */ | 596 | */ |
| 500 | const onCourseSelect = (course) => { | 597 | const onCourseSelect = (course) => { |
| 501 | formData.value.course = course.name; | 598 | formData.value.course = course.name; |
| 599 | + // 清空之前选择的章节 | ||
| 600 | + selectedChapters.value = []; | ||
| 601 | + // 根据选择的课程更新章节数据 | ||
| 602 | + chapters.value = courseChapters[course.name] ? JSON.parse(JSON.stringify(courseChapters[course.name])) : []; | ||
| 502 | showCoursePicker.value = false; | 603 | showCoursePicker.value = false; |
| 503 | courseSearchValue.value = ''; | 604 | courseSearchValue.value = ''; |
| 504 | }; | 605 | }; |
| 505 | 606 | ||
| 506 | /** | 607 | /** |
| 507 | - * 章节选择 | 608 | + * 章节切换选择状态 |
| 508 | - * @param {Object} chapter - 选中的章节 | 609 | + * @param {Object} chapter - 章节对象 |
| 610 | + */ | ||
| 611 | +const onChapterToggle = (chapter) => { | ||
| 612 | + // 切换选择状态的逻辑已经由 v-model 处理 | ||
| 613 | + console.log('章节选择状态变更:', chapter.name, chapter.selected); | ||
| 614 | +}; | ||
| 615 | + | ||
| 616 | +/** | ||
| 617 | + * 打开时间选择器 | ||
| 618 | + * @param {Object} chapter - 章节对象 | ||
| 619 | + * @param {string} type - 时间类型 'start' 或 'end' | ||
| 620 | + */ | ||
| 621 | +const openTimePicker = (chapter, type) => { | ||
| 622 | + currentChapter.value = chapter; | ||
| 623 | + currentTimeType.value = type; | ||
| 624 | + | ||
| 625 | + // 设置当前时间 | ||
| 626 | + const timeValue = type === 'start' ? chapter.startTime : chapter.endTime; | ||
| 627 | + if (timeValue) { | ||
| 628 | + const date = new Date(timeValue); | ||
| 629 | + currentChapterTime.value = [ | ||
| 630 | + date.getFullYear().toString(), | ||
| 631 | + (date.getMonth() + 1).toString().padStart(2, '0'), | ||
| 632 | + date.getDate().toString().padStart(2, '0') | ||
| 633 | + ]; | ||
| 634 | + } else { | ||
| 635 | + currentChapterTime.value = ['2024', '01', '01']; | ||
| 636 | + } | ||
| 637 | + | ||
| 638 | + showChapterTimePicker.value = true; | ||
| 639 | +}; | ||
| 640 | + | ||
| 641 | +/** | ||
| 642 | + * 确认章节时间选择 | ||
| 643 | + */ | ||
| 644 | +const onChapterTimeConfirm = () => { | ||
| 645 | + const [year, month, day] = currentChapterTime.value; | ||
| 646 | + const dateStr = `${year}-${month}-${day}`; | ||
| 647 | + | ||
| 648 | + if (currentChapter.value && currentTimeType.value) { | ||
| 649 | + // 时间验证逻辑 | ||
| 650 | + if (currentTimeType.value === 'start') { | ||
| 651 | + // 设置开始时间时,检查是否晚于结束时间 | ||
| 652 | + if (currentChapter.value.endTime && dateStr > currentChapter.value.endTime) { | ||
| 653 | + showToast('开始时间不能晚于结束时间'); | ||
| 654 | + return; | ||
| 655 | + } | ||
| 656 | + currentChapter.value.startTime = dateStr; | ||
| 657 | + } else { | ||
| 658 | + // 设置结束时间时,检查是否早于开始时间 | ||
| 659 | + if (currentChapter.value.startTime && dateStr < currentChapter.value.startTime) { | ||
| 660 | + showToast('结束时间不能早于开始时间'); | ||
| 661 | + return; | ||
| 662 | + } | ||
| 663 | + currentChapter.value.endTime = dateStr; | ||
| 664 | + } | ||
| 665 | + } | ||
| 666 | + | ||
| 667 | + showChapterTimePicker.value = false; | ||
| 668 | + currentChapter.value = null; | ||
| 669 | + currentTimeType.value = ''; | ||
| 670 | +}; | ||
| 671 | + | ||
| 672 | +/** | ||
| 673 | + * 取消章节选择 | ||
| 509 | */ | 674 | */ |
| 510 | -const onChapterSelect = (chapter) => { | 675 | +const cancelChapterSelection = () => { |
| 511 | - formData.value.chapter = chapter.name; | 676 | + // 重置所有章节的选择状态 |
| 677 | + chapters.value.forEach(chapter => { | ||
| 678 | + chapter.selected = false; | ||
| 679 | + chapter.startTime = ''; | ||
| 680 | + chapter.endTime = ''; | ||
| 681 | + }); | ||
| 512 | showChapterPicker.value = false; | 682 | showChapterPicker.value = false; |
| 513 | chapterSearchValue.value = ''; | 683 | chapterSearchValue.value = ''; |
| 514 | }; | 684 | }; |
| 515 | 685 | ||
| 516 | /** | 686 | /** |
| 687 | + * 确认章节选择 | ||
| 688 | + */ | ||
| 689 | +const confirmChapterSelection = () => { | ||
| 690 | + // 更新已选择的章节列表 | ||
| 691 | + selectedChapters.value = chapters.value.filter(chapter => chapter.selected); | ||
| 692 | + | ||
| 693 | + // 验证已选择章节的时间设置 | ||
| 694 | + const invalidChapters = selectedChapters.value.filter(chapter => !chapter.startTime || !chapter.endTime); | ||
| 695 | + if (invalidChapters.length > 0) { | ||
| 696 | + showToast('请为所有选中的章节设置开始和结束时间'); | ||
| 697 | + return; | ||
| 698 | + } | ||
| 699 | + | ||
| 700 | + // 验证时间逻辑:结束时间不能早于开始时间 | ||
| 701 | + const timeInvalidChapters = selectedChapters.value.filter(chapter => | ||
| 702 | + chapter.startTime && chapter.endTime && chapter.endTime < chapter.startTime | ||
| 703 | + ); | ||
| 704 | + if (timeInvalidChapters.length > 0) { | ||
| 705 | + showToast('存在结束时间早于开始时间的章节,请重新设置'); | ||
| 706 | + return; | ||
| 707 | + } | ||
| 708 | + | ||
| 709 | + showChapterPicker.value = false; | ||
| 710 | + chapterSearchValue.value = ''; | ||
| 711 | + showToast(`已选择 ${selectedChapters.value.length} 个章节`); | ||
| 712 | +}; | ||
| 713 | + | ||
| 714 | +/** | ||
| 517 | * 活动选择 | 715 | * 活动选择 |
| 518 | * @param {Object} activity - 选中的活动 | 716 | * @param {Object} activity - 选中的活动 |
| 519 | */ | 717 | */ |
| ... | @@ -833,6 +1031,111 @@ onMounted(() => { | ... | @@ -833,6 +1031,111 @@ onMounted(() => { |
| 833 | border-radius: 16px 16px 0 0; | 1031 | border-radius: 16px 16px 0 0; |
| 834 | } | 1032 | } |
| 835 | 1033 | ||
| 1034 | +/* 章节选择器样式 */ | ||
| 1035 | +/* .chapter-picker-popup { | ||
| 1036 | + :deep(.van-popup) { | ||
| 1037 | + max-height: 80vh; | ||
| 1038 | + } | ||
| 1039 | +} */ | ||
| 1040 | + | ||
| 1041 | +.chapter-picker-container { | ||
| 1042 | + display: flex; | ||
| 1043 | + flex-direction: column; | ||
| 1044 | + height: 80vh; | ||
| 1045 | + background: white; | ||
| 1046 | +} | ||
| 1047 | + | ||
| 1048 | +.picker-header { | ||
| 1049 | + padding: 16px; | ||
| 1050 | + border-bottom: 1px solid #eee; | ||
| 1051 | +} | ||
| 1052 | + | ||
| 1053 | +.picker-header h3 { | ||
| 1054 | + margin: 0 0 12px 0; | ||
| 1055 | + font-size: 18px; | ||
| 1056 | + font-weight: 600; | ||
| 1057 | + color: #333; | ||
| 1058 | + text-align: center; | ||
| 1059 | +} | ||
| 1060 | + | ||
| 1061 | +.chapter-list { | ||
| 1062 | + flex: 1; | ||
| 1063 | + overflow-y: auto; | ||
| 1064 | + padding: 16px; | ||
| 1065 | +} | ||
| 1066 | + | ||
| 1067 | +.chapter-item { | ||
| 1068 | + margin-bottom: 16px; | ||
| 1069 | + padding: 12px; | ||
| 1070 | + background: #f8f9fa; | ||
| 1071 | + border-radius: 8px; | ||
| 1072 | + border: 1px solid #e9ecef; | ||
| 1073 | +} | ||
| 1074 | + | ||
| 1075 | +.chapter-checkbox { | ||
| 1076 | + margin-bottom: 8px; | ||
| 1077 | +} | ||
| 1078 | + | ||
| 1079 | +:deep(.chapter-checkbox .van-checkbox__label) { | ||
| 1080 | + font-size: 16px; | ||
| 1081 | + font-weight: 500; | ||
| 1082 | + color: #333; | ||
| 1083 | +} | ||
| 1084 | + | ||
| 1085 | +.time-settings { | ||
| 1086 | + margin-top: 12px; | ||
| 1087 | + padding-top: 12px; | ||
| 1088 | + border-top: 1px solid #dee2e6; | ||
| 1089 | +} | ||
| 1090 | + | ||
| 1091 | +.time-settings .time-row { | ||
| 1092 | + display: flex; | ||
| 1093 | + align-items: center; | ||
| 1094 | + margin-bottom: 8px; | ||
| 1095 | +} | ||
| 1096 | + | ||
| 1097 | +.time-settings .time-label { | ||
| 1098 | + font-size: 14px; | ||
| 1099 | + color: #666; | ||
| 1100 | + margin-right: 12px; | ||
| 1101 | + min-width: 80px; | ||
| 1102 | +} | ||
| 1103 | + | ||
| 1104 | +.time-field { | ||
| 1105 | + flex: 1; | ||
| 1106 | + background: white; | ||
| 1107 | + border-radius: 6px; | ||
| 1108 | +} | ||
| 1109 | + | ||
| 1110 | +:deep(.time-field .van-field__control) { | ||
| 1111 | + padding: 8px 12px; | ||
| 1112 | + font-size: 14px; | ||
| 1113 | +} | ||
| 1114 | + | ||
| 1115 | +.picker-footer { | ||
| 1116 | + display: flex; | ||
| 1117 | + gap: 12px; | ||
| 1118 | + padding: 16px; | ||
| 1119 | + border-top: 1px solid #eee; | ||
| 1120 | + background: #f8f9fa; | ||
| 1121 | +} | ||
| 1122 | + | ||
| 1123 | +.cancel-btn { | ||
| 1124 | + flex: 1; | ||
| 1125 | + height: 44px; | ||
| 1126 | + border: 1px solid #ddd; | ||
| 1127 | + background: white; | ||
| 1128 | + color: #666; | ||
| 1129 | +} | ||
| 1130 | + | ||
| 1131 | +.confirm-btn { | ||
| 1132 | + flex: 2; | ||
| 1133 | + height: 44px; | ||
| 1134 | + background: linear-gradient(135deg, #4ade80 0%, #22c55e 100%); | ||
| 1135 | + border: none; | ||
| 1136 | + font-weight: 600; | ||
| 1137 | +} | ||
| 1138 | + | ||
| 836 | /* 响应式设计 */ | 1139 | /* 响应式设计 */ |
| 837 | @media (max-width: 480px) { | 1140 | @media (max-width: 480px) { |
| 838 | .setting-row { | 1141 | .setting-row { |
| ... | @@ -844,5 +1147,19 @@ onMounted(() => { | ... | @@ -844,5 +1147,19 @@ onMounted(() => { |
| 844 | .select-item { | 1147 | .select-item { |
| 845 | padding: 10px 12px; | 1148 | padding: 10px 12px; |
| 846 | } | 1149 | } |
| 1150 | + | ||
| 1151 | + .chapter-picker-container { | ||
| 1152 | + height: 85vh; | ||
| 1153 | + } | ||
| 1154 | + | ||
| 1155 | + .time-settings .time-row { | ||
| 1156 | + flex-direction: column; | ||
| 1157 | + align-items: flex-start; | ||
| 1158 | + gap: 4px; | ||
| 1159 | + } | ||
| 1160 | + | ||
| 1161 | + .time-settings .time-label { | ||
| 1162 | + min-width: auto; | ||
| 1163 | + } | ||
| 847 | } | 1164 | } |
| 848 | </style> | 1165 | </style> | ... | ... |
-
Please register or login to post a comment