hookehuyr

feat(打卡): 完善打卡功能逻辑和UI显示

- 在CheckInDialog组件中新增check-in-data事件用于传递打卡数据
- 优化打卡类型选择逻辑,增加task_type条件判断
- 仅在ProfilePage和HomePage有打卡数据时显示打卡相关UI
- 更新视频封面默认图片和音频标题显示逻辑
- 仅显示用户自己的打卡帖子的编辑删除按钮
...@@ -88,7 +88,7 @@ const props = defineProps({ ...@@ -88,7 +88,7 @@ const props = defineProps({
88 } 88 }
89 }) 89 })
90 90
91 -const emit = defineEmits(['update:show', 'check-in-success']) 91 +const emit = defineEmits(['update:show', 'check-in-success', 'check-in-data'])
92 92
93 const selectedCheckIn = ref(null) 93 const selectedCheckIn = ref(null)
94 const checkInContent = ref('') 94 const checkInContent = ref('')
...@@ -96,7 +96,7 @@ const isCheckingIn = ref(false) ...@@ -96,7 +96,7 @@ const isCheckingIn = ref(false)
96 const checkInSuccess = ref(false) 96 const checkInSuccess = ref(false)
97 97
98 const handleCheckInSelect = (type) => { 98 const handleCheckInSelect = (type) => {
99 - if (type.is_gray) { 99 + if (type.is_gray && type.task_type === 'checkin') {
100 showToast('您已经完成了今天的打卡') 100 showToast('您已经完成了今天的打卡')
101 return 101 return
102 } 102 }
...@@ -154,6 +154,7 @@ onMounted(async () => { ...@@ -154,6 +154,7 @@ onMounted(async () => {
154 // 获取签到列表 154 // 获取签到列表
155 const task = await getTaskListAPI() 155 const task = await getTaskListAPI()
156 if (task.code) { 156 if (task.code) {
157 + emit('check-in-data', task.data)
157 task.data.forEach(item => { 158 task.data.forEach(item => {
158 checkInTypes.value.push({ 159 checkInTypes.value.push({
159 id: item.id, 160 id: item.id,
......
1 <!-- 1 <!--
2 * @Date: 2025-03-20 19:55:21 2 * @Date: 2025-03-20 19:55:21
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-06-06 15:16:49 4 + * @LastEditTime: 2025-06-06 17:26:39
5 * @FilePath: /mlaj/src/views/HomePage.vue 5 * @FilePath: /mlaj/src/views/HomePage.vue
6 * @Description: 美乐爱觉教育首页组件 6 * @Description: 美乐爱觉教育首页组件
7 * 7 *
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
74 </FrostedGlass> 74 </FrostedGlass>
75 75
76 <!-- Daily Check-in --> 76 <!-- Daily Check-in -->
77 - <FrostedGlass class="p-4 rounded-xl"> 77 + <FrostedGlass v-if="checkInTypes.length" class="p-4 rounded-xl">
78 <div class="flex justify-between items-center mb-3"> 78 <div class="flex justify-between items-center mb-3">
79 <h3 class="font-medium">今日打卡</h3> 79 <h3 class="font-medium">今日打卡</h3>
80 <router-link to="/profile" class="text-green-600 text-sm">打卡记录</router-link> 80 <router-link to="/profile" class="text-green-600 text-sm">打卡记录</router-link>
...@@ -668,7 +668,7 @@ const scrollToSlide = (index) => { ...@@ -668,7 +668,7 @@ const scrollToSlide = (index) => {
668 668
669 // 打卡功能:处理打卡类型选择 669 // 打卡功能:处理打卡类型选择
670 const handleCheckInSelect = (checkInType) => { 670 const handleCheckInSelect = (checkInType) => {
671 - if (checkInType.is_gray) { 671 + if (checkInType.is_gray && checkInType.task_type === 'checkin') {
672 showToast('您已经完成了今天的打卡') 672 showToast('您已经完成了今天的打卡')
673 return 673 return
674 } 674 }
......
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-06 17:07:25 4 + * @LastEditTime: 2025-06-06 17:32:28
5 * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue 5 * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -81,7 +81,7 @@ ...@@ -81,7 +81,7 @@
81 </div> 81 </div>
82 </van-col> 82 </van-col>
83 <van-col span="3"> 83 <van-col span="3">
84 - <div class="post-menu"> 84 + <div v-if="post.is_my" class="post-menu">
85 <van-icon name="edit" @click="editCheckin()" /> 85 <van-icon name="edit" @click="editCheckin()" />
86 <van-icon name="delete-o" @click="delCheckin()" /> 86 <van-icon name="delete-o" @click="delCheckin()" />
87 </div> 87 </div>
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
99 <div v-for="(v, idx) in post.videoList" :key="idx"> 99 <div v-for="(v, idx) in post.videoList" :key="idx">
100 <!-- 视频封面和播放按钮 --> 100 <!-- 视频封面和播放按钮 -->
101 <div v-if="v.video && !v.isPlaying" class="relative w-full rounded-lg overflow-hidden" style="aspect-ratio: 16/9; margin-bottom: 1rem;"> 101 <div v-if="v.video && !v.isPlaying" class="relative w-full rounded-lg overflow-hidden" style="aspect-ratio: 16/9; margin-bottom: 1rem;">
102 - <img :src="v.videoCover || 'https://cdn.ipadbiz.cn/mlaj/images/cover_video_1.png'" 102 + <img :src="v.videoCover || 'https://cdn.ipadbiz.cn/mlaj/images/cover_video_2.png'"
103 :alt="v.content" class="w-full h-full object-cover" /> 103 :alt="v.content" class="w-full h-full object-cover" />
104 <div class="absolute inset-0 flex items-center justify-center cursor-pointer bg-black/20" 104 <div class="absolute inset-0 flex items-center justify-center cursor-pointer bg-black/20"
105 @click="startPlay(v)"> 105 @click="startPlay(v)">
...@@ -617,7 +617,7 @@ onMounted(async () => { ...@@ -617,7 +617,7 @@ onMounted(async () => {
617 } else if (item.file_type === 'audio') { 617 } else if (item.file_type === 'audio') {
618 audio = item.files.map(file => { 618 audio = item.files.map(file => {
619 return { 619 return {
620 - title: file.title ? file.title : '打卡音频', 620 + title: file.name ? file.name : '打卡音频',
621 artist: file.artist ? file.artist : '', 621 artist: file.artist ? file.artist : '',
622 url: file.value, 622 url: file.value,
623 cover: file.cover ? file.cover : '', 623 cover: file.cover ? file.cover : '',
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
55 </div> 55 </div>
56 <div class="text-xs text-gray-500 mt-1">最长连续</div> 56 <div class="text-xs text-gray-500 mt-1">最长连续</div>
57 </div> 57 </div>
58 - <div> 58 + <div v-if="checkinData.length">
59 <div @click="showCheckInDialog = true" class="cursor-pointer"> 59 <div @click="showCheckInDialog = true" class="cursor-pointer">
60 <button 60 <button
61 class="bg-gradient-to-r from-green-500 to-green-600 text-white py-2 px-6 rounded-full text-sm shadow-sm" 61 class="bg-gradient-to-r from-green-500 to-green-600 text-white py-2 px-6 rounded-full text-sm shadow-sm"
...@@ -114,6 +114,7 @@ ...@@ -114,6 +114,7 @@
114 <CheckInDialog 114 <CheckInDialog
115 v-model:show="showCheckInDialog" 115 v-model:show="showCheckInDialog"
116 @check-in-success="handleCheckInSuccess" 116 @check-in-success="handleCheckInSuccess"
117 + @check-in-data="handleCheckInData"
117 /> 118 />
118 </template> 119 </template>
119 120
...@@ -155,6 +156,11 @@ const handleCheckInSuccess = () => { ...@@ -155,6 +156,11 @@ const handleCheckInSuccess = () => {
155 ); 156 );
156 }; 157 };
157 158
159 +const checkinData = ref([]);
160 +const handleCheckInData = (data) => {
161 + checkinData.value = data;
162 +}
163 +
158 // Handle logout 164 // Handle logout
159 const { logout } = useAuth(); 165 const { logout } = useAuth();
160 const handleLogout = () => { 166 const handleLogout = () => {
......