refactor(页面布局): 重构打卡页面布局为固定日历和可滚动内容区域
将日历组件改为固定定位,内容区域改为可滚动布局 动态计算日历高度并设置内容区域margin-top 移除日历背景样式以保持整体设计一致
Showing
2 changed files
with
51 additions
and
46 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-01-25 15:34:17 | 2 | * @Date: 2025-01-25 15:34:17 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-09-24 22:41:07 | 4 | + * @LastEditTime: 2025-09-25 09:37:57 |
| 5 | * @FilePath: /mlaj/src/components/ui/CollapsibleCalendar.vue | 5 | * @FilePath: /mlaj/src/components/ui/CollapsibleCalendar.vue |
| 6 | * @Description: 可折叠日历组件 | 6 | * @Description: 可折叠日历组件 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | - <div class="collapsible-calendar"> | 9 | + <div class="collapsible-calendar "> |
| 10 | <!-- 折叠状态显示 --> | 10 | <!-- 折叠状态显示 --> |
| 11 | <div v-if="!isExpanded" class="calendar-collapsed" @click="expandCalendar"> | 11 | <div v-if="!isExpanded" class="calendar-collapsed" @click="expandCalendar"> |
| 12 | <div class="calendar-header"> | 12 | <div class="calendar-header"> |
| ... | @@ -165,8 +165,8 @@ defineExpose({ | ... | @@ -165,8 +165,8 @@ defineExpose({ |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | .calendar-collapsed { | 167 | .calendar-collapsed { |
| 168 | - background: linear-gradient(135deg, #ffffff 0%, #f8fffe 100%); | 168 | + // background: linear-gradient(135deg, #ffffff 0%, #f8fffe 100%); |
| 169 | - border-radius: 16px; | 169 | + // border-radius: 16px; |
| 170 | padding: 20px; | 170 | padding: 20px; |
| 171 | box-shadow: 0 4px 20px rgba(76, 175, 80, 0.08), 0 2px 8px rgba(0, 0, 0, 0.06); | 171 | box-shadow: 0 4px 20px rgba(76, 175, 80, 0.08), 0 2px 8px rgba(0, 0, 0, 0.06); |
| 172 | cursor: pointer; | 172 | cursor: pointer; | ... | ... |
| 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-09-24 21:56:56 | 4 | + * @LastEditTime: 2025-09-25 09:30:55 |
| 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue | 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | <AppLayout :hasTitle="false"> | 9 | <AppLayout :hasTitle="false"> |
| 10 | <van-config-provider :theme-vars="themeVars"> | 10 | <van-config-provider :theme-vars="themeVars"> |
| 11 | + <!-- 固定的日历组件 --> | ||
| 12 | + <div class="fixed-calendar"> | ||
| 11 | <CollapsibleCalendar | 13 | <CollapsibleCalendar |
| 12 | - ref="myRefCalendar" | 14 | + ref="calendarRef" |
| 13 | :title="taskDetail.title" | 15 | :title="taskDetail.title" |
| 14 | :formatter="formatter" | 16 | :formatter="formatter" |
| 15 | v-model="selectedDate" | 17 | v-model="selectedDate" |
| 16 | @select="onSelectDay" | 18 | @select="onSelectDay" |
| 17 | @click-subtitle="onClickSubtitle" | 19 | @click-subtitle="onClickSubtitle" |
| 18 | /> | 20 | /> |
| 21 | + </div> | ||
| 22 | + | ||
| 23 | + <!-- 可滚动的内容区域 --> | ||
| 24 | + <div class="scrollable-content"> | ||
| 25 | + <div class="text-wrapper"> | ||
| 26 | + <div class="text-header">作业描述</div> | ||
| 27 | + </div> | ||
| 19 | 28 | ||
| 20 | <div v-if="showProgress" class="text-wrapper"> | 29 | <div v-if="showProgress" class="text-wrapper"> |
| 21 | <div class="text-header">目标进度</div> | 30 | <div class="text-header">目标进度</div> |
| ... | @@ -52,10 +61,6 @@ | ... | @@ -52,10 +61,6 @@ |
| 52 | </div> | 61 | </div> |
| 53 | </div> | 62 | </div> |
| 54 | 63 | ||
| 55 | - <div class="text-wrapper"> | ||
| 56 | - <div class="text-header">作业描述</div> | ||
| 57 | - </div> | ||
| 58 | - | ||
| 59 | <div v-if="!taskDetail.is_finish" class="text-wrapper"> | 64 | <div v-if="!taskDetail.is_finish" class="text-wrapper"> |
| 60 | <div class="text-header">打卡类型</div> | 65 | <div class="text-header">打卡类型</div> |
| 61 | <div class="upload-wrapper"> | 66 | <div class="upload-wrapper"> |
| ... | @@ -166,6 +171,7 @@ | ... | @@ -166,6 +171,7 @@ |
| 166 | </div> | 171 | </div> |
| 167 | 172 | ||
| 168 | <div style="height: 5rem;"></div> | 173 | <div style="height: 5rem;"></div> |
| 174 | + </div> <!-- 闭合 scrollable-content --> | ||
| 169 | </van-config-provider> | 175 | </van-config-provider> |
| 170 | 176 | ||
| 171 | <van-dialog v-model:show="dialog_show" title="标题" show-cancel-button></van-dialog> | 177 | <van-dialog v-model:show="dialog_show" title="标题" show-cancel-button></van-dialog> |
| ... | @@ -196,45 +202,20 @@ const myRefCalendar = ref(null); | ... | @@ -196,45 +202,20 @@ const myRefCalendar = ref(null); |
| 196 | const windowHeight = ref(window.innerHeight); | 202 | const windowHeight = ref(window.innerHeight); |
| 197 | const windowWidth = ref(window.innerWidth); | 203 | const windowWidth = ref(window.innerWidth); |
| 198 | 204 | ||
| 205 | +// 日历高度相关的响应式数据 | ||
| 206 | +const calendarRef = ref(null); | ||
| 207 | +const calendarHeight = ref(200); // 默认高度 | ||
| 208 | + | ||
| 199 | /** | 209 | /** |
| 200 | - * 动态计算日历高度 | 210 | + * 动态获取日历组件的实际高度 |
| 201 | - * 根据屏幕尺寸和设备类型自适应调整 | ||
| 202 | */ | 211 | */ |
| 203 | -const calendarHeight = computed(() => { | 212 | +const updateCalendarHeight = async () => { |
| 204 | - // 获取可视窗口高度 | 213 | + await nextTick(); |
| 205 | - const viewportHeight = windowHeight.value; | 214 | + if (calendarRef.value) { |
| 206 | - | 215 | + const rect = calendarRef.value.$el.getBoundingClientRect(); |
| 207 | - // 预留给其他内容的空间(头部、底部等) | 216 | + calendarHeight.value = rect.height; |
| 208 | - const reservedSpace = 200; // 可根据实际需要调整 | ||
| 209 | - | ||
| 210 | - // 计算可用高度 | ||
| 211 | - const availableHeight = viewportHeight - reservedSpace; | ||
| 212 | - | ||
| 213 | - // 设置最小和最大高度限制 | ||
| 214 | - const minHeight = 300; // 最小高度 | ||
| 215 | - const maxHeight = 500; // 最大高度 | ||
| 216 | - | ||
| 217 | - // 根据屏幕宽度调整高度比例 | ||
| 218 | - let heightRatio = 0.6; // 默认占可用高度的55% | ||
| 219 | - | ||
| 220 | - if (windowWidth.value < 375) { | ||
| 221 | - // 小屏手机 | ||
| 222 | - heightRatio = 0.95; | ||
| 223 | - } else if (windowWidth.value < 414) { | ||
| 224 | - // 中等屏幕手机 | ||
| 225 | - heightRatio = 0.95; | ||
| 226 | - } else if (windowWidth.value >= 768) { | ||
| 227 | - // 平板或更大屏幕 | ||
| 228 | - heightRatio = 0.95; | ||
| 229 | } | 217 | } |
| 230 | - | 218 | +}; |
| 231 | - const calculatedHeight = Math.floor(availableHeight * heightRatio); | ||
| 232 | - | ||
| 233 | - // 确保高度在合理范围内 | ||
| 234 | - const finalHeight = Math.max(minHeight, Math.min(maxHeight, calculatedHeight)); | ||
| 235 | - | ||
| 236 | - return `${finalHeight}px`; | ||
| 237 | -}); | ||
| 238 | 219 | ||
| 239 | /** | 220 | /** |
| 240 | * 监听窗口尺寸变化 | 221 | * 监听窗口尺寸变化 |
| ... | @@ -242,6 +223,8 @@ const calendarHeight = computed(() => { | ... | @@ -242,6 +223,8 @@ const calendarHeight = computed(() => { |
| 242 | const handleResize = () => { | 223 | const handleResize = () => { |
| 243 | windowHeight.value = window.innerHeight; | 224 | windowHeight.value = window.innerHeight; |
| 244 | windowWidth.value = window.innerWidth; | 225 | windowWidth.value = window.innerWidth; |
| 226 | + // 重新计算日历高度 | ||
| 227 | + updateCalendarHeight(); | ||
| 245 | }; | 228 | }; |
| 246 | 229 | ||
| 247 | // 组件挂载时添加事件监听 | 230 | // 组件挂载时添加事件监听 |
| ... | @@ -252,6 +235,9 @@ onMounted(() => { | ... | @@ -252,6 +235,9 @@ onMounted(() => { |
| 252 | // 延迟更新,等待方向变化完成 | 235 | // 延迟更新,等待方向变化完成 |
| 253 | setTimeout(handleResize, 100); | 236 | setTimeout(handleResize, 100); |
| 254 | }); | 237 | }); |
| 238 | + | ||
| 239 | + // 初始化时计算日历高度 | ||
| 240 | + updateCalendarHeight(); | ||
| 255 | }); | 241 | }); |
| 256 | 242 | ||
| 257 | // 存储所有视频播放器的引用 | 243 | // 存储所有视频播放器的引用 |
| ... | @@ -731,6 +717,25 @@ const formatData = (data) => { | ... | @@ -731,6 +717,25 @@ const formatData = (data) => { |
| 731 | </script> | 717 | </script> |
| 732 | 718 | ||
| 733 | <style lang="less"> | 719 | <style lang="less"> |
| 720 | +// 固定日历样式 | ||
| 721 | +.fixed-calendar { | ||
| 722 | + position: fixed; | ||
| 723 | + top: 0; | ||
| 724 | + left: 0; | ||
| 725 | + right: 0; | ||
| 726 | + z-index: 1000; | ||
| 727 | + background: linear-gradient(to bottom right, #f0fdf4, #f0fdfa, #eff6ff); // 与AppLayout保持一致的渐变背景 | ||
| 728 | + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); | ||
| 729 | +} | ||
| 730 | + | ||
| 731 | +// 可滚动内容区域样式 | ||
| 732 | +.scrollable-content { | ||
| 733 | + margin-top: v-bind('calendarHeight + "px"'); // 动态计算日历高度 | ||
| 734 | + padding-top: 1rem; | ||
| 735 | + height: v-bind('"calc(100vh - " + calendarHeight + "px)"'); // 动态计算剩余高度 | ||
| 736 | + overflow-y: auto; | ||
| 737 | +} | ||
| 738 | + | ||
| 734 | .van-back-top { | 739 | .van-back-top { |
| 735 | background-color: #4caf50; | 740 | background-color: #4caf50; |
| 736 | } | 741 | } | ... | ... |
-
Please register or login to post a comment