hookehuyr

refactor(页面布局): 重构打卡页面布局为固定日历和可滚动内容区域

将日历组件改为固定定位,内容区域改为可滚动布局
动态计算日历高度并设置内容区域margin-top
移除日历背景样式以保持整体设计一致
<!--
* @Date: 2025-01-25 15:34:17
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-24 22:41:07
* @LastEditTime: 2025-09-25 09:37:57
* @FilePath: /mlaj/src/components/ui/CollapsibleCalendar.vue
* @Description: 可折叠日历组件
-->
<template>
<div class="collapsible-calendar">
<div class="collapsible-calendar ">
<!-- 折叠状态显示 -->
<div v-if="!isExpanded" class="calendar-collapsed" @click="expandCalendar">
<div class="calendar-header">
......@@ -165,8 +165,8 @@ defineExpose({
}
.calendar-collapsed {
background: linear-gradient(135deg, #ffffff 0%, #f8fffe 100%);
border-radius: 16px;
// background: linear-gradient(135deg, #ffffff 0%, #f8fffe 100%);
// border-radius: 16px;
padding: 20px;
box-shadow: 0 4px 20px rgba(76, 175, 80, 0.08), 0 2px 8px rgba(0, 0, 0, 0.06);
cursor: pointer;
......
<!--
* @Date: 2025-05-29 15:34:17
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-24 21:56:56
* @LastEditTime: 2025-09-25 09:30:55
* @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue
* @Description: 文件描述
-->
<template>
<AppLayout :hasTitle="false">
<van-config-provider :theme-vars="themeVars">
<!-- 固定的日历组件 -->
<div class="fixed-calendar">
<CollapsibleCalendar
ref="myRefCalendar"
ref="calendarRef"
:title="taskDetail.title"
:formatter="formatter"
v-model="selectedDate"
@select="onSelectDay"
@click-subtitle="onClickSubtitle"
/>
</div>
<!-- 可滚动的内容区域 -->
<div class="scrollable-content">
<div class="text-wrapper">
<div class="text-header">作业描述</div>
</div>
<div v-if="showProgress" class="text-wrapper">
<div class="text-header">目标进度</div>
......@@ -52,10 +61,6 @@
</div>
</div>
<div class="text-wrapper">
<div class="text-header">作业描述</div>
</div>
<div v-if="!taskDetail.is_finish" class="text-wrapper">
<div class="text-header">打卡类型</div>
<div class="upload-wrapper">
......@@ -166,6 +171,7 @@
</div>
<div style="height: 5rem;"></div>
</div> <!-- 闭合 scrollable-content -->
</van-config-provider>
<van-dialog v-model:show="dialog_show" title="标题" show-cancel-button></van-dialog>
......@@ -196,45 +202,20 @@ const myRefCalendar = ref(null);
const windowHeight = ref(window.innerHeight);
const windowWidth = ref(window.innerWidth);
// 日历高度相关的响应式数据
const calendarRef = ref(null);
const calendarHeight = ref(200); // 默认高度
/**
* 动态计算日历高度
* 根据屏幕尺寸和设备类型自适应调整
* 动态获取日历组件的实际高度
*/
const calendarHeight = computed(() => {
// 获取可视窗口高度
const viewportHeight = windowHeight.value;
// 预留给其他内容的空间(头部、底部等)
const reservedSpace = 200; // 可根据实际需要调整
// 计算可用高度
const availableHeight = viewportHeight - reservedSpace;
// 设置最小和最大高度限制
const minHeight = 300; // 最小高度
const maxHeight = 500; // 最大高度
// 根据屏幕宽度调整高度比例
let heightRatio = 0.6; // 默认占可用高度的55%
if (windowWidth.value < 375) {
// 小屏手机
heightRatio = 0.95;
} else if (windowWidth.value < 414) {
// 中等屏幕手机
heightRatio = 0.95;
} else if (windowWidth.value >= 768) {
// 平板或更大屏幕
heightRatio = 0.95;
const updateCalendarHeight = async () => {
await nextTick();
if (calendarRef.value) {
const rect = calendarRef.value.$el.getBoundingClientRect();
calendarHeight.value = rect.height;
}
const calculatedHeight = Math.floor(availableHeight * heightRatio);
// 确保高度在合理范围内
const finalHeight = Math.max(minHeight, Math.min(maxHeight, calculatedHeight));
return `${finalHeight}px`;
});
};
/**
* 监听窗口尺寸变化
......@@ -242,6 +223,8 @@ const calendarHeight = computed(() => {
const handleResize = () => {
windowHeight.value = window.innerHeight;
windowWidth.value = window.innerWidth;
// 重新计算日历高度
updateCalendarHeight();
};
// 组件挂载时添加事件监听
......@@ -252,6 +235,9 @@ onMounted(() => {
// 延迟更新,等待方向变化完成
setTimeout(handleResize, 100);
});
// 初始化时计算日历高度
updateCalendarHeight();
});
// 存储所有视频播放器的引用
......@@ -731,6 +717,25 @@ const formatData = (data) => {
</script>
<style lang="less">
// 固定日历样式
.fixed-calendar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
background: linear-gradient(to bottom right, #f0fdf4, #f0fdfa, #eff6ff); // 与AppLayout保持一致的渐变背景
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
// 可滚动内容区域样式
.scrollable-content {
margin-top: v-bind('calendarHeight + "px"'); // 动态计算日历高度
padding-top: 1rem;
height: v-bind('"calc(100vh - " + calendarHeight + "px)"'); // 动态计算剩余高度
overflow-y: auto;
}
.van-back-top {
background-color: #4caf50;
}
......