hookehuyr

feat(teacher): 添加学生详情跳转和作业点评功能

- 在班级页面添加点击学生跳转至详情页功能
- 在签到页面添加作业点评弹窗及相关逻辑
- 调整日历组件高度和显示文本
- 优化图标大小和间距
1 <!-- 1 <!--
2 * @Date: 2025-05-29 15:34:17 2 * @Date: 2025-05-29 15:34:17
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-06-19 14:49:38 4 + * @LastEditTime: 2025-06-20 10:40:58
5 * @FilePath: /mlaj/src/views/teacher/checkinPage.vue 5 * @FilePath: /mlaj/src/views/teacher/checkinPage.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
16 </van-dropdown-menu> 16 </van-dropdown-menu>
17 </van-sticky> 17 </van-sticky>
18 18
19 - <van-calendar ref="myRefCalendar" :title="taskDetail.title" :poppable="false" :show-confirm="false" :style="{ height: calendarHeight }" 19 + <van-calendar ref="myRefCalendar" :show-title="false" :poppable="false" :show-confirm="false" :style="{ height: calendarHeight }"
20 switch-mode="year-month" color="#4caf50" :formatter="formatter" row-height="50" :show-mark="false" 20 switch-mode="year-month" color="#4caf50" :formatter="formatter" row-height="50" :show-mark="false"
21 @select="onSelectDay" 21 @select="onSelectDay"
22 @click-subtitle="onClickSubtitle"> 22 @click-subtitle="onClickSubtitle">
...@@ -148,9 +148,25 @@ ...@@ -148,9 +148,25 @@
148 /> 148 />
149 </div> 149 </div>
150 </div> 150 </div>
151 - <div class="post-footer"> 151 + <div class="post-footer flex items-center justify-between">
152 - <van-icon @click="handLike(post)"name="good-job" class="like-icon" :color="post.is_liked ? 'red' : ''" /> 152 + <!-- 左侧:点赞 -->
153 - <span class="like-count">{{ post.likes }}</span> 153 + <div class="flex items-center">
154 + <van-icon @click="handLike(post)" name="good-job" class="like-icon" :color="post.is_liked ? 'red' : ''" />
155 + <span class="like-count ml-1">{{ post.likes }}</span>
156 + </div>
157 +
158 + <!-- 右侧:点评 -->
159 + <div class="flex items-center cursor-pointer" @click="openCommentPopup(post)">
160 + <van-icon
161 + name="comment-o"
162 + :color="post.is_commented ? '#10b981' : '#999'"
163 + size="18"
164 + class="mr-1"
165 + />
166 + <span class="text-sm" :class="post.is_commented ? 'text-green-600' : 'text-gray-500'">
167 + {{ post.is_commented ? '已点评' : '点评' }}
168 + </span>
169 + </div>
154 </div> 170 </div>
155 </div> 171 </div>
156 </van-list> 172 </van-list>
...@@ -161,6 +177,51 @@ ...@@ -161,6 +177,51 @@
161 <div style="height: 5rem;"></div> 177 <div style="height: 5rem;"></div>
162 </van-config-provider> 178 </van-config-provider>
163 179
180 + <!-- 点评详情弹窗 -->
181 + <van-popup v-model:show="showCommentPopup" position="bottom" round class="comment-popup">
182 + <div class="p-6 w-100">
183 + <div class="text-center text-lg font-bold mb-4">点评详情</div>
184 +
185 + <!-- 显示评分 -->
186 + <div class="mb-4">
187 + <div class="text-sm text-gray-600 mb-2">评分</div>
188 + <div class="flex justify-center">
189 + <van-rate :model-value="currentCommentPost?.comment?.rating || 0" :size="24" color="#ffd21e" void-color="#eee" readonly />
190 + <span class="ml-2 text-sm text-gray-500">({{ currentCommentPost?.comment?.rating || 0 }}/5)</span>
191 + </div>
192 + </div>
193 +
194 + <!-- 显示点评内容 -->
195 + <div class="mb-6">
196 + <div class="text-sm text-gray-600 mb-2">点评内容</div>
197 + <div class="bg-gray-50 rounded-lg p-3 min-h-[100px]">
198 + <p class="text-gray-800 text-sm leading-relaxed">
199 + {{ currentCommentPost?.comment?.content || '暂无点评内容' }}
200 + </p>
201 + </div>
202 + </div>
203 +
204 + <!-- 点评时间 -->
205 + <div class="mb-6" v-if="currentCommentPost?.comment?.created_at">
206 + <div class="text-sm text-gray-600 mb-2">点评时间</div>
207 + <div class="text-sm text-gray-500">
208 + {{ formatCommentTime(currentCommentPost.comment.created_at) }}
209 + </div>
210 + </div>
211 +
212 + <!-- 关闭按钮 -->
213 + <div class="flex justify-center">
214 + <van-button
215 + type="primary"
216 + @click="closeCommentPopup"
217 + class="w-32"
218 + >
219 + 关闭
220 + </van-button>
221 + </div>
222 + </div>
223 + </van-popup>
224 +
164 <van-dialog v-model:show="dialog_show" title="标题" show-cancel-button></van-dialog> 225 <van-dialog v-model:show="dialog_show" title="标题" show-cancel-button></van-dialog>
165 </AppLayout> 226 </AppLayout>
166 </template> 227 </template>
...@@ -182,6 +243,10 @@ const route = useRoute() ...@@ -182,6 +243,10 @@ const route = useRoute()
182 const router = useRouter() 243 const router = useRouter()
183 useTitle(route.meta.title); 244 useTitle(route.meta.title);
184 245
246 +// 点评相关
247 +const showCommentPopup = ref(false)
248 +const currentCommentPost = ref(null)
249 +
185 const value1 = ref(0); 250 const value1 = ref(0);
186 const value2 = ref('a'); 251 const value2 = ref('a');
187 const value3 = ref('v'); 252 const value3 = ref('v');
...@@ -240,7 +305,7 @@ const calendarHeight = computed(() => { ...@@ -240,7 +305,7 @@ const calendarHeight = computed(() => {
240 const maxHeight = 500; // 最大高度 305 const maxHeight = 500; // 最大高度
241 306
242 // 根据屏幕宽度调整高度比例 307 // 根据屏幕宽度调整高度比例
243 - let heightRatio = 0.6; // 默认占可用高度的55% 308 + let heightRatio = 0.5; // 默认占可用高度的55%
244 309
245 if (windowWidth.value < 375) { 310 if (windowWidth.value < 375) {
246 // 小屏手机 311 // 小屏手机
...@@ -481,11 +546,11 @@ const formatter = (day) => { ...@@ -481,11 +546,11 @@ const formatter = (day) => {
481 if (selectedDate.value === formattedDate) { 546 if (selectedDate.value === formattedDate) {
482 day.className = 'calendar-selected'; 547 day.className = 'calendar-selected';
483 day.type = 'selected'; 548 day.type = 'selected';
484 - day.bottomInfo = '已签到'; 549 + day.bottomInfo = '已打卡';
485 } else { 550 } else {
486 day.className = 'calendar-checkin'; 551 day.className = 'calendar-checkin';
487 day.type = 'selected'; 552 day.type = 'selected';
488 - day.bottomInfo = '已签到'; 553 + day.bottomInfo = '已打卡';
489 } 554 }
490 } 555 }
491 } 556 }
...@@ -549,6 +614,40 @@ const handLike = async (post) => { ...@@ -549,6 +614,40 @@ const handLike = async (post) => {
549 } 614 }
550 } 615 }
551 616
617 +/**
618 + * 打开点评详情弹窗
619 + * @param {Object} post - 作业帖子对象
620 + */
621 +const openCommentPopup = (post) => {
622 + currentCommentPost.value = post
623 + showCommentPopup.value = true
624 +}
625 +
626 +/**
627 + * 关闭点评详情弹窗
628 + */
629 +const closeCommentPopup = () => {
630 + showCommentPopup.value = false
631 + currentCommentPost.value = null
632 +}
633 +
634 +/**
635 + * 格式化点评时间
636 + * @param {string} timeString - 时间字符串
637 + * @returns {string} 格式化后的时间
638 + */
639 +const formatCommentTime = (timeString) => {
640 + if (!timeString) return ''
641 + const date = new Date(timeString)
642 + return date.toLocaleString('zh-CN', {
643 + year: 'numeric',
644 + month: '2-digit',
645 + day: '2-digit',
646 + hour: '2-digit',
647 + minute: '2-digit'
648 + })
649 +}
650 +
552 const editCheckin = (post) => { 651 const editCheckin = (post) => {
553 if (post.file_type === 'image') { 652 if (post.file_type === 'image') {
554 router.push({ 653 router.push({
...@@ -707,6 +806,12 @@ const formatData = (data) => { ...@@ -707,6 +806,12 @@ const formatData = (data) => {
707 is_liked: item.is_like, 806 is_liked: item.is_like,
708 is_my: item.is_my, 807 is_my: item.is_my,
709 file_type: item.file_type, 808 file_type: item.file_type,
809 + is_commented: item.is_commented || Math.random() > 0.5, // 随机设置是否已点评,用于测试
810 + comment: item.comment || (Math.random() > 0.5 ? {
811 + rating: Math.floor(Math.random() * 5) + 1,
812 + content: ['作业完成得很好,继续保持!', '需要更加仔细一些,注意细节。', '表现优秀,值得表扬!', '还有进步空间,加油!'][Math.floor(Math.random() * 4)],
813 + created_at: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000).toISOString()
814 + } : null)
710 } 815 }
711 }) 816 })
712 return formattedData; 817 return formattedData;
...@@ -841,4 +946,26 @@ const handleAdd = () => { ...@@ -841,4 +946,26 @@ const handleAdd = () => {
841 } 946 }
842 } 947 }
843 } 948 }
949 +
950 +// 点评弹窗样式
951 +.comment-popup {
952 + .van-popup {
953 + max-width: 500px;
954 + margin: 0 auto;
955 + }
956 +
957 + .van-rate {
958 + justify-content: center;
959 + }
960 +
961 + .van-field {
962 + padding: 12px;
963 + border-radius: 8px;
964 + }
965 +
966 + .van-button {
967 + height: 44px;
968 + border-radius: 8px;
969 + }
970 +}
844 </style> 971 </style>
......
...@@ -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 10:11:32 5 + * @LastEditTime: 2025-06-20 10:17:50
6 * @FilePath: /mlaj/src/views/teacher/myClassPage.vue 6 * @FilePath: /mlaj/src/views/teacher/myClassPage.vue
7 * @Description: 我的班级页面 7 * @Description: 我的班级页面
8 --> 8 -->
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
18 <div class="flex-1"> 18 <div class="flex-1">
19 <h2 class="text-lg font-bold text-gray-800">{{ userInfo.name }}</h2> 19 <h2 class="text-lg font-bold text-gray-800">{{ userInfo.name }}</h2>
20 <div class="flex items-center mt-1"> 20 <div class="flex items-center mt-1">
21 - <van-icon name="clock-o" size="20" color="#10b981" class="mr-1" /> 21 + <van-icon name="clock-o" size="22" color="#10b981" class="mr-1" />&nbsp;
22 - <van-icon name="chat-o" size="20" color="#10b981" class="mr-1" /> 22 + <van-icon name="chat-o" size="22" color="#10b981" class="mr-1" />&nbsp;
23 - <van-icon name="comment-circle-o" size="20" color="#10b981" /> 23 + <van-icon name="comment-circle-o" size="22" color="#10b981" />&nbsp;
24 </div> 24 </div>
25 </div> 25 </div>
26 </div> 26 </div>
...@@ -387,6 +387,9 @@ const handleSearch = (value) => { ...@@ -387,6 +387,9 @@ const handleSearch = (value) => {
387 const handleStudentClick = (student) => { 387 const handleStudentClick = (student) => {
388 console.log('点击学生:', student) 388 console.log('点击学生:', student)
389 // 这里可以跳转到学生详情页 389 // 这里可以跳转到学生详情页
390 + router.push({
391 + path: '/teacher/student/' + student.id,
392 + })
390 } 393 }
391 394
392 /** 395 /**
......