hookehuyr

feat(teacher/formPage): 添加时间选择器组件并优化表单布局

- 添加 VanDatetimePicker 和 VanTimePicker 组件声明
- 将日期选择器改为日期时间选择器组合
- 调整表单布局,合并作业频次和每周期提交数量到同一行
- 优化目标总数输入框宽度和样式
...@@ -44,6 +44,7 @@ declare module 'vue' { ...@@ -44,6 +44,7 @@ declare module 'vue' {
44 VanCol: typeof import('vant/es')['Col'] 44 VanCol: typeof import('vant/es')['Col']
45 VanConfigProvider: typeof import('vant/es')['ConfigProvider'] 45 VanConfigProvider: typeof import('vant/es')['ConfigProvider']
46 VanDatePicker: typeof import('vant/es')['DatePicker'] 46 VanDatePicker: typeof import('vant/es')['DatePicker']
47 + VanDatetimePicker: typeof import('vant/es')['DatetimePicker']
47 VanDialog: typeof import('vant/es')['Dialog'] 48 VanDialog: typeof import('vant/es')['Dialog']
48 VanDivider: typeof import('vant/es')['Divider'] 49 VanDivider: typeof import('vant/es')['Divider']
49 VanDropdownItem: typeof import('vant/es')['DropdownItem'] 50 VanDropdownItem: typeof import('vant/es')['DropdownItem']
...@@ -74,6 +75,7 @@ declare module 'vue' { ...@@ -74,6 +75,7 @@ declare module 'vue' {
74 VanTabbarItem: typeof import('vant/es')['TabbarItem'] 75 VanTabbarItem: typeof import('vant/es')['TabbarItem']
75 VanTabs: typeof import('vant/es')['Tabs'] 76 VanTabs: typeof import('vant/es')['Tabs']
76 VanTag: typeof import('vant/es')['Tag'] 77 VanTag: typeof import('vant/es')['Tag']
78 + VanTimePicker: typeof import('vant/es')['TimePicker']
77 VanUploader: typeof import('vant/es')['Uploader'] 79 VanUploader: typeof import('vant/es')['Uploader']
78 VideoPlayer: typeof import('./components/ui/VideoPlayer.vue')['default'] 80 VideoPlayer: typeof import('./components/ui/VideoPlayer.vue')['default']
79 WechatPayment: typeof import('./components/payment/WechatPayment.vue')['default'] 81 WechatPayment: typeof import('./components/payment/WechatPayment.vue')['default']
......
...@@ -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-09-30 16:22:57 5 + * @LastEditTime: 2025-10-14 11:32:42
6 * @FilePath: /mlaj/src/views/teacher/formPage.vue 6 * @FilePath: /mlaj/src/views/teacher/formPage.vue
7 * @Description: 教师作业新增表单页面 7 * @Description: 教师作业新增表单页面
8 --> 8 -->
...@@ -57,9 +57,9 @@ ...@@ -57,9 +57,9 @@
57 </van-checkbox-group> 57 </van-checkbox-group>
58 </div> 58 </div>
59 59
60 - <!-- 作业周期 --> 60 + <!-- 作业频次和每周期提交数量 -->
61 <van-row gutter="10" class="mb-4"> 61 <van-row gutter="10" class="mb-4">
62 - <van-col span="24"> 62 + <van-col span="12">
63 <label class="setting-label">{{ pageTitle === '设置作业' ? '作业' : '打卡' }}频次</label> 63 <label class="setting-label">{{ pageTitle === '设置作业' ? '作业' : '打卡' }}频次</label>
64 <van-field 64 <van-field
65 v-model="formData.cycle_text" 65 v-model="formData.cycle_text"
...@@ -72,10 +72,6 @@ ...@@ -72,10 +72,6 @@
72 class="cycle-field" 72 class="cycle-field"
73 /> 73 />
74 </van-col> 74 </van-col>
75 - </van-row>
76 -
77 - <!-- 每周期提交数量和目标总数 -->
78 - <van-row gutter="10">
79 <van-col span="12"> 75 <van-col span="12">
80 <label class="setting-label">每周期提交数量</label> 76 <label class="setting-label">每周期提交数量</label>
81 <div class="target-count-container"> 77 <div class="target-count-container">
...@@ -90,7 +86,11 @@ ...@@ -90,7 +86,11 @@
90 <span class="target-unit">次</span> 86 <span class="target-unit">次</span>
91 </div> 87 </div>
92 </van-col> 88 </van-col>
93 - <van-col span="12"> 89 + </van-row>
90 +
91 + <!-- 目标总数 -->
92 + <van-row gutter="10" class="mb-4">
93 + <van-col span="24">
94 <label class="setting-label">目标总数</label> 94 <label class="setting-label">目标总数</label>
95 <div class="target-count-container"> 95 <div class="target-count-container">
96 <van-stepper 96 <van-stepper
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
99 max="100" 99 max="100"
100 integer 100 integer
101 button-size="24px" 101 button-size="24px"
102 - input-width="50%" 102 + input-width="80%"
103 /> 103 />
104 <span class="target-unit">次</span> 104 <span class="target-unit">次</span>
105 </div> 105 </div>
...@@ -212,14 +212,44 @@ ...@@ -212,14 +212,44 @@
212 212
213 <!-- 开始时间选择器 --> 213 <!-- 开始时间选择器 -->
214 <van-popup v-model:show="showStartTimePicker" position="bottom"> 214 <van-popup v-model:show="showStartTimePicker" position="bottom">
215 - <van-date-picker v-model="startDate" title="选择开始时间" :min-date="minDate" :max-date="maxDate" 215 + <van-picker-group
216 - @confirm="onStartTimeConfirm" @cancel="showStartTimePicker = false" /> 216 + title="选择开始时间"
217 + :tabs="['选择日期', '选择时间']"
218 + next-step-text="下一步"
219 + @confirm="onStartTimeConfirm"
220 + @cancel="showStartTimePicker = false"
221 + >
222 + <van-date-picker
223 + v-model="startDate"
224 + :min-date="minDate"
225 + :max-date="maxDate"
226 + />
227 + <van-time-picker
228 + v-model="startTime"
229 + :columns-type="['hour', 'minute', 'second']"
230 + />
231 + </van-picker-group>
217 </van-popup> 232 </van-popup>
218 233
219 <!-- 结束时间选择器 --> 234 <!-- 结束时间选择器 -->
220 <van-popup v-model:show="showEndTimePicker" position="bottom"> 235 <van-popup v-model:show="showEndTimePicker" position="bottom">
221 - <van-date-picker v-model="endDate" title="选择结束时间" :min-date="minDate" :max-date="maxDate" 236 + <van-picker-group
222 - @confirm="onEndTimeConfirm" @cancel="showEndTimePicker = false" /> 237 + title="选择结束时间"
238 + :tabs="['选择日期', '选择时间']"
239 + next-step-text="下一步"
240 + @confirm="onEndTimeConfirm"
241 + @cancel="showEndTimePicker = false"
242 + >
243 + <van-date-picker
244 + v-model="endDate"
245 + :min-date="minDate"
246 + :max-date="maxDate"
247 + />
248 + <van-time-picker
249 + v-model="endTime"
250 + :columns-type="['hour', 'minute', 'second']"
251 + />
252 + </van-picker-group>
223 </van-popup> 253 </van-popup>
224 254
225 <!-- 课程选择器 --> 255 <!-- 课程选择器 -->
...@@ -404,6 +434,8 @@ const showClassPicker = ref(false); ...@@ -404,6 +434,8 @@ const showClassPicker = ref(false);
404 // 日期选择器相关 434 // 日期选择器相关
405 const startDate = ref(['2024', '01', '01']); 435 const startDate = ref(['2024', '01', '01']);
406 const endDate = ref(['2024', '12', '31']); 436 const endDate = ref(['2024', '12', '31']);
437 +const startTime = ref(['00', '00', '00']);
438 +const endTime = ref(['23', '59', '59']);
407 const minDate = new Date(2020, 0, 1); 439 const minDate = new Date(2020, 0, 1);
408 const maxDate = new Date(2035, 11, 31); 440 const maxDate = new Date(2035, 11, 31);
409 441
...@@ -541,7 +573,10 @@ const formatDateTime = (date) => { ...@@ -541,7 +573,10 @@ const formatDateTime = (date) => {
541 const year = d.getFullYear(); 573 const year = d.getFullYear();
542 const month = String(d.getMonth() + 1).padStart(2, '0'); 574 const month = String(d.getMonth() + 1).padStart(2, '0');
543 const day = String(d.getDate()).padStart(2, '0'); 575 const day = String(d.getDate()).padStart(2, '0');
544 - return `${year}-${month}-${day}`; 576 + const hour = String(d.getHours()).padStart(2, '0');
577 + const minute = String(d.getMinutes()).padStart(2, '0');
578 + const second = String(d.getSeconds()).padStart(2, '0');
579 + return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
545 }; 580 };
546 581
547 /** 582 /**
...@@ -566,6 +601,11 @@ const openStartTimePicker = () => { ...@@ -566,6 +601,11 @@ const openStartTimePicker = () => {
566 (date.getMonth() + 1).toString().padStart(2, '0'), 601 (date.getMonth() + 1).toString().padStart(2, '0'),
567 date.getDate().toString().padStart(2, '0') 602 date.getDate().toString().padStart(2, '0')
568 ]; 603 ];
604 + startTime.value = [
605 + date.getHours().toString().padStart(2, '0'),
606 + date.getMinutes().toString().padStart(2, '0'),
607 + date.getSeconds().toString().padStart(2, '0')
608 + ];
569 } 609 }
570 showStartTimePicker.value = true; 610 showStartTimePicker.value = true;
571 }; 611 };
...@@ -575,7 +615,15 @@ const openStartTimePicker = () => { ...@@ -575,7 +615,15 @@ const openStartTimePicker = () => {
575 */ 615 */
576 const onStartTimeConfirm = () => { 616 const onStartTimeConfirm = () => {
577 const [year, month, day] = startDate.value; 617 const [year, month, day] = startDate.value;
578 - formData.value.start_time = new Date(parseInt(year), parseInt(month) - 1, parseInt(day)); 618 + const [hour, minute, second] = startTime.value;
619 + formData.value.start_time = new Date(
620 + parseInt(year),
621 + parseInt(month) - 1,
622 + parseInt(day),
623 + parseInt(hour),
624 + parseInt(minute),
625 + parseInt(second)
626 + );
579 showStartTimePicker.value = false; 627 showStartTimePicker.value = false;
580 }; 628 };
581 629
...@@ -591,6 +639,11 @@ const openEndTimePicker = () => { ...@@ -591,6 +639,11 @@ const openEndTimePicker = () => {
591 (date.getMonth() + 1).toString().padStart(2, '0'), 639 (date.getMonth() + 1).toString().padStart(2, '0'),
592 date.getDate().toString().padStart(2, '0') 640 date.getDate().toString().padStart(2, '0')
593 ]; 641 ];
642 + endTime.value = [
643 + date.getHours().toString().padStart(2, '0'),
644 + date.getMinutes().toString().padStart(2, '0'),
645 + date.getSeconds().toString().padStart(2, '0')
646 + ];
594 } 647 }
595 showEndTimePicker.value = true; 648 showEndTimePicker.value = true;
596 }; 649 };
...@@ -600,7 +653,15 @@ const openEndTimePicker = () => { ...@@ -600,7 +653,15 @@ const openEndTimePicker = () => {
600 */ 653 */
601 const onEndTimeConfirm = () => { 654 const onEndTimeConfirm = () => {
602 const [year, month, day] = endDate.value; 655 const [year, month, day] = endDate.value;
603 - formData.value.end_time = new Date(parseInt(year), parseInt(month) - 1, parseInt(day)); 656 + const [hour, minute, second] = endTime.value;
657 + formData.value.end_time = new Date(
658 + parseInt(year),
659 + parseInt(month) - 1,
660 + parseInt(day),
661 + parseInt(hour),
662 + parseInt(minute),
663 + parseInt(second)
664 + );
604 showEndTimePicker.value = false; 665 showEndTimePicker.value = false;
605 }; 666 };
606 667
...@@ -985,18 +1046,19 @@ onMounted(async () => { ...@@ -985,18 +1046,19 @@ onMounted(async () => {
985 .target-count-container { 1046 .target-count-container {
986 display: flex; 1047 display: flex;
987 align-items: center; 1048 align-items: center;
988 - justify-content: space-around;
989 gap: 8px; 1049 gap: 8px;
990 } 1050 }
991 1051
992 .target-unit { 1052 .target-unit {
993 font-size: 14px; 1053 font-size: 14px;
994 color: #666; 1054 color: #666;
1055 + flex-shrink: 0;
995 } 1056 }
996 1057
997 :deep(.van-stepper) { 1058 :deep(.van-stepper) {
998 background: #f5f5f5; 1059 background: #f5f5f5;
999 border-radius: 8px; 1060 border-radius: 8px;
1061 + flex: 1;
1000 } 1062 }
1001 1063
1002 /* 时间设置 */ 1064 /* 时间设置 */
......