| 1 | # MobileCalendar 移动端日历组件 |
| 2 | |
| 3 | ## 概述 |
| 4 | |
| 5 | 移动端专用的日历组件,用于替代桌面端的 FullCalendar 网格视图。 |
| 6 | 提供更适合触屏操作的周视图/月视图切换,以及选中日期的任务列表展示。 |
| 7 | |
| 8 | ## 目录结构 |
| 9 | |
| 10 | ``` |
| 11 | MobileCalendar/ |
| 12 | ├── index.tsx # 主组件,管理状态和组合子组件 |
| 13 | ├── MobileCalendarHeader.tsx # 顶部工具栏(年月选择、视图切换) |
| 14 | ├── MobileWeekView.tsx # 周视图组件 |
| 15 | ├── MobileMonthView.tsx # 月视图组件 |
| 16 | ├── MobileDayRecords.tsx # 选中日期的任务列表 |
| 17 | ├── mobileCalendar.types.ts # 类型定义 |
| 18 | └── README.md # 本文档 |
| 19 | ``` |
| 20 | |
| 21 | ## 组件说明 |
| 22 | |
| 23 | ### MobileCalendar (index.tsx) |
| 24 | |
| 25 | 主组件,负责: |
| 26 | |
| 27 | - 管理 `selectedDate`(当前选中日期) |
| 28 | - 管理 `viewType`('week' | 'month') |
| 29 | - 组合各子组件 |
| 30 | - 接收 `onClickPub` 回调,传递给子组件 |
| 31 | |
| 32 | **Props:** |
| 33 | | 属性 | 类型 | 说明 | |
| 34 | |------|------|------| |
| 35 | | onClickPub | `(date: string) => void` | 点击添加任务时的回调 | |
| 36 | |
| 37 | ### MobileCalendarHeader |
| 38 | |
| 39 | 顶部工具栏,功能: |
| 40 | |
| 41 | - 显示当前年月(格式:YYYY/MM) |
| 42 | - 点击年月弹出月份选择器 |
| 43 | - 周视图/月视图切换按钮 |
| 44 | - 今天按钮 |
| 45 | |
| 46 | **Props:** |
| 47 | | 属性 | 类型 | 说明 | |
| 48 | |------|------|------| |
| 49 | | currentDate | `Date` | 当前显示的日期 | |
| 50 | | viewType | `'week' \| 'month'` | 当前视图类型 | |
| 51 | | onDateChange | `(date: Date) => void` | 日期改变回调 | |
| 52 | | onViewTypeChange | `(type: ViewType) => void` | 视图切换回调 | |
| 53 | | onToday | `() => void` | 点击今天按钮回调 | |
| 54 | |
| 55 | ### MobileWeekView |
| 56 | |
| 57 | 周视图组件,功能: |
| 58 | |
| 59 | - 显示星期标题行(Sun/Mon/Tue...) |
| 60 | - 显示当前周的 7 天 |
| 61 | - 支持左右滑动切换周 |
| 62 | - 选中日期高亮 |
| 63 | - 有发布记录的日期在右上角显示不占位圆点 |
| 64 | |
| 65 | **Props:** |
| 66 | | 属性 | 类型 | 说明 | |
| 67 | |------|------|------| |
| 68 | | currentDate | `Date` | 当前周的基准日期 | |
| 69 | | selectedDate | `Date` | 选中的日期 | |
| 70 | | recordMap | `Map<string, PublishRecordItem[]>` | 发布记录数据 | |
| 71 | | onDateSelect | `(date: Date) => void` | 选择日期回调 | |
| 72 | | onWeekChange | `(direction: 'prev' \| 'next') => void` | 周切换回调 | |
| 73 | |
| 74 | ### MobileMonthView |
| 75 | |
| 76 | 月视图组件,功能: |
| 77 | |
| 78 | - 紧凑型月历网格 |
| 79 | - 选中日期高亮 |
| 80 | - 点击日期切换选中 |
| 81 | - 有发布记录的日期在右上角显示不占位圆点 |
| 82 | |
| 83 | **Props:** |
| 84 | | 属性 | 类型 | 说明 | |
| 85 | |------|------|------| |
| 86 | | currentDate | `Date` | 当前月的基准日期 | |
| 87 | | selectedDate | `Date` | 选中的日期 | |
| 88 | | recordMap | `Map<string, PublishRecordItem[]>` | 发布记录数据 | |
| 89 | | onDateSelect | `(date: Date) => void` | 选择日期回调 | |
| 90 | |
| 91 | ### MobileDayRecords |
| 92 | |
| 93 | 任务列表组件,功能: |
| 94 | |
| 95 | - 显示选中日期的所有任务 |
| 96 | - 使用 RecordCore 组件展示每条记录 |
| 97 | - 支持 loading 骨架屏 |
| 98 | - 空状态显示 |
| 99 | - 添加任务按钮 |
| 100 | |
| 101 | **Props:** |
| 102 | | 属性 | 类型 | 说明 | |
| 103 | |------|------|------| |
| 104 | | selectedDate | `Date` | 选中的日期 | |
| 105 | | records | `PublishRecordItem[]` | 当天的发布记录 | |
| 106 | | loading | `boolean` | 加载状态 | |
| 107 | | onClickPub | `(date: string) => void` | 添加任务回调 | |
| 108 | |
| 109 | ## 数据流 |
| 110 | |
| 111 | ``` |
| 112 | useCalendarTiming.recordMap (现有 store) |
| 113 | ↓ |
| 114 | MobileCalendar |
| 115 | ↓ |
| 116 | MobileDayRecords |
| 117 | (根据 selectedDate 过滤显示任务列表) |
| 118 | ``` |
| 119 | |
| 120 | **recordMap 结构:** |
| 121 | |
| 122 | ```typescript |
| 123 | Map<string, PublishRecordItem[]> |
| 124 | // key: 日期字符串,格式 'YYYY-MM-DD' |
| 125 | // value: 该日期的发布记录数组 |
| 126 | ``` |
| 127 | |
| 128 | **移动端请求范围:** |
| 129 | |
| 130 | - 周视图和月视图统一按“月视图可见范围”获取数据(包含月初/月末补齐的跨月周) |
| 131 | - 周/月视图切换不重新请求列表接口 |
| 132 | - 当前已加载范围覆盖目标范围时,直接复用 `recordMap` |
| 133 | |
| 134 | ## 复用的组件/工具 |
| 135 | |
| 136 | | 组件/工具 | 说明 | |
| 137 | | ----------------- | ---------------------------- | |
| 138 | | useCalendarTiming | 数据获取和状态管理 store | |
| 139 | | RecordCore | 任务详情展示(已支持移动端) | |
| 140 | | useIsMobile | 设备检测 hook(< 768px) | |
| 141 | | getDays | dayjs 工具函数 | |
| 142 | | Popover | shadcn/ui 弹出层组件 | |
| 143 | | Button/Skeleton | shadcn/ui 基础组件 | |
| 144 | |
| 145 | ## 样式规范 |
| 146 | |
| 147 | - 使用 Tailwind CSS |
| 148 | - 遵循 shadcn/ui 语义化变量 |
| 149 | - 选中日期: `bg-(--primary-color) text-white` |
| 150 | - 今天日期: `text-blue-500`(未选中时) |
| 151 | - 过去日期: `text-muted-foreground` |
| 152 | - 非当月日期: `text-muted-foreground/40` |
| 153 | |
| 154 | ## 交互说明 |
| 155 | |
| 156 | ### 日期选择 |
| 157 | |
| 158 | 点击任意日期 → 更新 `selectedDate` → 任务列表刷新 |
| 159 | |
| 160 | ### 周视图滑动 |
| 161 | |
| 162 | - **左滑**: 显示下一周 |
| 163 | - **右滑**: 显示上一周 |
| 164 | - **实现**: touch 事件监听,计算滑动距离和方向(阈值 50px) |
| 165 | |
| 166 | ### 视图切换 |
| 167 | |
| 168 | 点击切换按钮 → 周视图 ⇄ 月视图 |
| 169 | |
| 170 | - 默认显示周视图 |
| 171 | - 使用图标按钮(CalendarDays / Grid3X3) |
| 172 | |
| 173 | ### 月份跳转 |
| 174 | |
| 175 | 点击顶部年月 → 弹出 Popover 月份选择器 → 选择月份 → 跳转并获取数据 |
| 176 | |
| 177 | ## 国际化 |
| 178 | |
| 179 | 翻译 key 位于 `account` 命名空间下的 `mobileCalendar` 对象: |
| 180 | |
| 181 | ```json |
| 182 | { |
| 183 | "mobileCalendar": { |
| 184 | "weekView": "周视图", |
| 185 | "monthView": "月视图", |
| 186 | "tasks": "任务", |
| 187 | "addTask": "添加任务", |
| 188 | "noTasks": "该日期暂无任务", |
| 189 | "addFirstTask": "添加第一个任务" |
| 190 | } |
| 191 | } |
| 192 | ``` |
| 193 | |
| 194 | ## 注意事项 |
| 195 | |
| 196 | 1. **数据获取**: 切换月份时按月视图可见范围调用 `getPubRecord()`,周/月视图切换复用已有数据 |
| 197 | 2. **拖拽功能**: 移动端禁用拖拽功能(已在 RecordCore 中处理) |
| 198 | 3. **数据同步**: 保持与 PC 端数据同步,共用 `useCalendarTiming` store |
| 199 | 4. **设备判断**: 使用 `useIsMobile` hook,断点为 768px |
| 200 | |
| 201 | ## 修改记录 |
| 202 | |
| 203 | | 日期 | 修改内容 | |
| 204 | | ---------- | --------------------------------------------- | |
| 205 | | 2025-12-30 | 初始版本,实现周视图/月视图切换、任务列表展示 | |
| 206 |