Compare commits
No commits in common. "3aefd1e707c3ad24da7c1f217bdaf19251a8b7a1" and "a69b49ed341cba5899432566cf0817d28ea5c5d6" have entirely different histories.
3aefd1e707
...
a69b49ed34
2
client
2
client
@ -1 +1 @@
|
||||
Subproject commit 1559e603b0ac6fdae8e82ec163248c33923e1965
|
||||
Subproject commit a8b4f17043328f8a5e23f9b4fcfca5bd5e2d3b4f
|
||||
@ -149,7 +149,7 @@ Internet
|
||||
| React Router | 6.x | 路由管理 |
|
||||
| Zustand | 4.x | 状态管理 |
|
||||
| Day.js | 1.x | 日期处理 |
|
||||
| Zustand | 4.x | 状态管理 |
|
||||
| React Query | 5.x | 数据同步 |
|
||||
|
||||
### 3.2 后端技术栈
|
||||
|
||||
@ -303,31 +303,23 @@ COMMENT ON COLUMN anniversaries.remind_days IS '提前提醒天数数组,如[-
|
||||
|
||||
```sql
|
||||
CREATE TABLE reminders (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
type VARCHAR(20) DEFAULT 'reminder' NOT NULL,
|
||||
title VARCHAR(200) NOT NULL,
|
||||
content VARCHAR(500),
|
||||
date TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
is_lunar INTEGER DEFAULT 0,
|
||||
repeat_type VARCHAR(20) DEFAULT 'none',
|
||||
repeat_interval INTEGER,
|
||||
next_reminder_date TIMESTAMP WITH TIME ZONE,
|
||||
is_completed INTEGER DEFAULT 0,
|
||||
completed_at TIMESTAMP WITH TIME ZONE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
anniversary_id UUID REFERENCES anniversaries(id) ON DELETE CASCADE,
|
||||
title VARCHAR(200) NOT NULL,
|
||||
remind_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
is_completed BOOLEAN DEFAULT FALSE,
|
||||
completed_at TIMESTAMP WITH TIME ZONE,
|
||||
notification_type VARCHAR(20) DEFAULT 'email',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_reminders_user_id ON reminders(user_id);
|
||||
CREATE INDEX idx_reminders_date ON reminders(date);
|
||||
CREATE INDEX idx_reminders_remind_time ON reminders(remind_time);
|
||||
CREATE INDEX idx_reminders_is_completed ON reminders(is_completed);
|
||||
CREATE INDEX idx_reminders_type ON reminders(type);
|
||||
CREATE INDEX idx_reminders_repeat_type ON reminders(repeat_type);
|
||||
CREATE INDEX idx_reminders_anniversary_id ON reminders(anniversary_id);
|
||||
|
||||
COMMENT ON COLUMN reminders.type IS 'reminder:提醒, anniversary:纪念日';
|
||||
COMMENT ON COLUMN reminders.repeat_type IS 'none:不重复, daily:每天, weekly:每周, monthly:每月, yearly:每年';
|
||||
COMMENT ON COLUMN reminders.next_reminder_date IS '下一次提醒日期(基于周期计算)';
|
||||
COMMENT ON COLUMN reminders.notification_type IS 'email:邮件, browser:浏览器推送';
|
||||
```
|
||||
|
||||
#### 4.2.4 notes 表(便签)
|
||||
@ -448,28 +440,22 @@ model Anniversary {
|
||||
|
||||
// 提醒模型
|
||||
model Reminder {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
type String @default("reminder") @map("type")
|
||||
title String
|
||||
content String? @map("content")
|
||||
date DateTime @map("date")
|
||||
isLunar Int @default(0) @map("is_lunar")
|
||||
repeatType String @default("none") @map("repeat_type")
|
||||
repeatInterval Int? @map("repeat_interval")
|
||||
nextReminderDate DateTime? @map("next_reminder_date")
|
||||
isCompleted Int @default(0) @map("is_completed")
|
||||
completedAt DateTime? @map("completed_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
anniversaryId String? @map("anniversary_id")
|
||||
title String
|
||||
remindTime DateTime @map("remind_time")
|
||||
isCompleted Boolean @default(false) @map("is_completed")
|
||||
completedAt DateTime? @map("completed_at")
|
||||
notificationType String @default("email") @map("notification_type")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
anniversary Anniversary? @relation(fields: [anniversaryId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([userId])
|
||||
@@index([date])
|
||||
@@index([remindTime])
|
||||
@@index([isCompleted])
|
||||
@@index([type])
|
||||
@@index([repeatType])
|
||||
@@map("reminders")
|
||||
}
|
||||
|
||||
@ -1099,27 +1085,41 @@ e:\qia\client\
|
||||
│ │ └── styles/
|
||||
│ │ └── index.css # Tailwind入口
|
||||
│ ├── components/
|
||||
│ │ ├── common/
|
||||
│ │ │ ├── Button/
|
||||
│ │ │ ├── Modal/
|
||||
│ │ │ ├── Input/
|
||||
│ │ │ ├── Select/
|
||||
│ │ │ ├── DatePicker/
|
||||
│ │ │ ├── Toast/
|
||||
│ │ │ └── Loading/
|
||||
│ │ ├── layout/
|
||||
│ │ │ ├── Header/
|
||||
│ │ │ ├── Sidebar/
|
||||
│ │ │ ├── Footer/
|
||||
│ │ │ └── Layout/
|
||||
│ │ ├── anniversary/
|
||||
│ │ │ ├── AnniversaryCard/
|
||||
│ │ │ ├── AnniversaryForm/
|
||||
│ │ │ ├── AnniversaryList/
|
||||
│ │ │ └── HolidayCard/
|
||||
│ │ ├── reminder/
|
||||
│ │ │ ├── ReminderCard/
|
||||
│ │ │ ├── ReminderItem/
|
||||
│ │ │ ├── ReminderList/
|
||||
│ │ │ ├── ReminderForm/
|
||||
│ │ │ ├── ArchiveReminderModal/
|
||||
│ │ │ └── ReminderDetailModal/
|
||||
│ │ │ └── ReminderBadge/
|
||||
│ │ ├── note/
|
||||
│ │ │ ├── NoteCard/
|
||||
│ │ │ ├── NoteCanvas/
|
||||
│ │ │ └── NoteEditor/
|
||||
│ │ ├── ai/
|
||||
│ │ │ └── ChatBox/
|
||||
│ │ ├── layout/
|
||||
│ │ │ └── Layout/
|
||||
│ │ └── common/
|
||||
│ │ ├── Modal/
|
||||
│ │ └── Toast/
|
||||
│ │ │ ├── ChatBox/
|
||||
│ │ │ ├── AIFloatingButton/
|
||||
│ │ │ └── ParsingResult/
|
||||
│ │ └── auth/
|
||||
│ │ ├── LoginForm/
|
||||
│ │ ├── RegisterForm/
|
||||
│ │ ├── ForgotPasswordForm/
|
||||
│ │ └── EmailVerification/
|
||||
│ ├── pages/
|
||||
│ │ ├── Home/
|
||||
│ │ ├── Dashboard/
|
||||
@ -1161,7 +1161,11 @@ e:\qia\client\
|
||||
│ │ └── socket/
|
||||
│ │ └── socketService.ts
|
||||
│ ├── stores/
|
||||
│ │ └── index.ts # Zustand主状态管理(包含所有store)
|
||||
│ │ ├── authStore.ts
|
||||
│ │ ├── anniversaryStore.ts
|
||||
│ │ ├── reminderStore.ts
|
||||
│ │ ├── noteStore.ts
|
||||
│ │ └── uiStore.ts
|
||||
│ ├── utils/
|
||||
│ │ ├── validators.ts
|
||||
│ │ ├── formatters.ts
|
||||
@ -2574,11 +2578,10 @@ enum ErrorCode {
|
||||
|
||||
| 版本 | 日期 | 描述 |
|
||||
|-----|------|------|
|
||||
| 1.3.0 | 2026-02-04 | 更新提醒模块数据模型、重复提醒完成移除设置、逾期列表展开收起、无时间显示优化 |
|
||||
| 1.1.0 | 2026-01-29 | 添加SQLite本地开发支持 |
|
||||
| 1.0.0 | 2026-01-28 | 初始架构设计(PostgreSQL) |
|
||||
|
||||
---
|
||||
|
||||
*文档维护: 系统架构组*
|
||||
*最后更新: 2026-02-04*
|
||||
*最后更新: 2026-01-29*
|
||||
|
||||
398
docs/prd.md
398
docs/prd.md
@ -4,10 +4,10 @@
|
||||
|
||||
| 项目 | 内容 |
|
||||
|-----|------|
|
||||
| **版本号** | v1.0.2 |
|
||||
| **版本号** | v1.0.1 |
|
||||
| **状态** | 开发中 |
|
||||
| **创建日期** | 2026-01-28 |
|
||||
| **最近更新** | 2026-02-04 |
|
||||
| **最近更新** | 2026-02-03 |
|
||||
| **目标用户** | 需要管理纪念日、提醒任务的普通用户 |
|
||||
| **产品定位** | 轻便、灵活的倒数日和提醒App,专注提醒功能 |
|
||||
|
||||
@ -1612,9 +1612,6 @@ Home页面采用三栏布局,总宽度1200px,居中显示。
|
||||
| **设置** | 显示设置 | ✅ 已完成 | 节假日显示开关 |
|
||||
| **其他** | 归档页 | ✅ 已完成 | 恢复/删除功能 |
|
||||
| | 设置页 | ✅ 已完成 | 基础框架 |
|
||||
| | 重复提醒完成移除设置 | ✅ 已完成 | 勾选完成后移除repeat_type等字段 |
|
||||
| | 逾期列表展开收起 | ✅ 已完成 | 默认收起,最多3条,点击展开 |
|
||||
| | 无时间提醒显示优化 | ✅ 已完成 | 只显示日期,不显示00:00 |
|
||||
|
||||
### 10.2 提醒模块当前实现详情
|
||||
|
||||
@ -1708,404 +1705,15 @@ Home页面采用三栏布局,总宽度1200px,居中显示。
|
||||
|------|------|------|----------|
|
||||
| v1.0.0 | MVP基础功能 | ✅ 已完成 | 2026-01-28 |
|
||||
| v1.0.1 | 提醒模块完善、归档页 | ✅ 已完成 | 2026-02-03 |
|
||||
| v1.0.2 | 核心体验优化、重复提醒完成移除设置、逾期列表展开收起 | ✅ 已完成 | 2026-02-04 |
|
||||
| v1.0.2 | 核心体验优化 | 进行中 | 待定 |
|
||||
| v1.1.0 | 功能增强 | 计划中 | 待定 |
|
||||
| v1.2.0 | 生态扩展 | 计划中 | 待定 |
|
||||
|
||||
---
|
||||
|
||||
## 12 重复提醒功能设计
|
||||
|
||||
### 12.1 功能概述
|
||||
|
||||
重复提醒功能允许用户创建周期性的提醒任务,系统自动按照设定的周期计算下一次提醒时间。当前支持三种重复模式:每天、每周、每年。重复提醒从用户设置的首次提醒时间开始,按固定周期循环显示。
|
||||
|
||||
### 12.2 重复模式定义
|
||||
|
||||
| 重复类型 | 描述 | 示例 |
|
||||
|----------|------|------|
|
||||
| **每天(daily)** | 每天同一时间提醒 | 每天早上8点吃药 |
|
||||
| **每周(weekly)** | 每周同一星期同一时间提醒 | 每周五下午3点开会 |
|
||||
| **每年(yearly)** | 每年同一日期同一时间提醒 | 每年3月15日交论文 |
|
||||
|
||||
### 12.3 数据模型扩展
|
||||
|
||||
#### 12.3.1 提醒表扩展(reminders)
|
||||
|
||||
在现有提醒表基础上增加重复相关字段:
|
||||
|
||||
| 字段名 | 类型 | 约束 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| id | UUID | PRIMARY KEY | 提醒唯一标识 |
|
||||
| user_id | UUID | FOREIGN KEY | 所属用户ID |
|
||||
| type | VARCHAR(20) | DEFAULT 'reminder' | 类型:reminder/anniversary |
|
||||
| title | VARCHAR(200) | NOT NULL | 提醒标题 |
|
||||
| content | VARCHAR(500) | | 提醒内容 |
|
||||
| date | TIMESTAMP | NOT NULL | 当前提醒日期(展示用) |
|
||||
| is_lunar | INTEGER | DEFAULT 0 | 是否为农历日期 |
|
||||
| repeat_type | VARCHAR(20) | DEFAULT 'none' | 重复类型:none/daily/weekly/monthly/yearly |
|
||||
| repeat_interval | INTEGER | | 周数间隔(仅 weekly 类型使用) |
|
||||
| next_reminder_date | TIMESTAMP | | 下一次提醒日期(计算用,基于周期推算) |
|
||||
| is_holiday | INTEGER | DEFAULT 0 | 是否为节假日(仅纪念日) |
|
||||
| is_completed | INTEGER | DEFAULT 0 | 是否已完成 |
|
||||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
|
||||
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | 更新时间 |
|
||||
|
||||
**字段说明**:
|
||||
|
||||
- `date`:当前提醒日期(展示用),用于分组和展示
|
||||
- `next_reminder_date`:下一次提醒日期,基于周期推算得出。创建时自动计算,勾选完成时用于计算下一条记录
|
||||
- `repeat_type`:'none'表示不重复,'daily'每天,'weekly'每周,'monthly'每月,'yearly'每年
|
||||
- `repeat_interval`:周数间隔,仅 weekly 类型使用
|
||||
|
||||
#### 12.3.2 重复周期计算规则
|
||||
|
||||
**每天重复**:
|
||||
```
|
||||
next_date = current_date + 1天
|
||||
时间保持不变
|
||||
```
|
||||
|
||||
**每周重复**:
|
||||
```
|
||||
next_date = current_date + 7天
|
||||
时间保持不变
|
||||
星期几根据repeat_base_date确定
|
||||
```
|
||||
|
||||
**每年重复**:
|
||||
```
|
||||
next_date = current_date + 1年
|
||||
如果下一年该日期不存在(如2月29日),则调整为2月28日
|
||||
时间保持不变
|
||||
```
|
||||
|
||||
### 12.4 功能详细描述
|
||||
|
||||
#### 12.4.1 添加重复提醒
|
||||
|
||||
**手动添加**:
|
||||
|
||||
用户点击提醒列表上方的添加按钮,弹出添加弹窗。表单字段:
|
||||
|
||||
- 提醒内容(必填)
|
||||
- 提醒时间(必填,日期+时间)
|
||||
- 重复方式(下拉选择):不重复 / 每天 / 每周 / 每月 / 每年
|
||||
|
||||
**AI对话添加**:
|
||||
用户输入自然语言描述,系统自动识别重复规则:
|
||||
- "每天早上8点吃药" → 自动识别为每天重复
|
||||
- "每周五下午3点开会" → 自动识别为每周重复
|
||||
- "每年3月15日交论文" → 自动识别为每年重复
|
||||
- "提醒我明天下午3点开会" → 不重复
|
||||
|
||||
#### 12.4.2 卡片显示规则
|
||||
|
||||
**正常提醒卡片**(未逾期、未完成):
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ [checkbox] 标题 [循环icon] 2月3日 14:00 │
|
||||
│ 内容... │
|
||||
└─────────────────────────────────────────────────────────<EFBFBD>循环icon位置:在日期时间左侧
|
||||
```
|
||||
|
||||
**逾期提醒卡片**(已过期、未完成):
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ [checkbox] 标题 [循环icon] │
|
||||
│ 内容... 2月1日 14:00 (已错过) │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
循环icon位置:在标题右侧
|
||||
```
|
||||
|
||||
**循环icon设计**:
|
||||
- 样式:循环箭头图标(类似⟳)
|
||||
- 颜色:与重复类型相关
|
||||
- 每天:蓝色
|
||||
- 每周:绿色
|
||||
- 每年:紫色
|
||||
- 悬停提示:显示重复类型("每天重复"、"每周重复"、"每年重复")
|
||||
|
||||
#### 12.4.3 列表显示规则
|
||||
|
||||
**常规分组显示**(今天、明天、更久之后):
|
||||
- 每个重复提醒在常规列表中**只显示最近1条未逾期、未完成的记录**
|
||||
- 当用户勾选完成当前提醒后:
|
||||
1. 当前记录标记完成,移入归档
|
||||
2. 自动计算下一周期日期
|
||||
3. 下一周期记录出现在对应分组中
|
||||
- 始终保持每个重复提醒只有1条可见记录
|
||||
|
||||
**示例**:
|
||||
用户创建"每天早上8点吃药",首次日期为2月3日:
|
||||
- 2月3日显示在"今天"分组
|
||||
- 用户勾选完成后,2月3日记录归档,2月4日自动出现在"明天"分组
|
||||
- 依此类推
|
||||
|
||||
**已错过分组显示**:
|
||||
- **所有逾期未勾选的重复提醒都显示**,不只显示1条
|
||||
- 按过期时间从远到近排序
|
||||
- 勾选完成后,自动计算下一周期并显示
|
||||
|
||||
#### 12.4.4 重复提醒完成流程
|
||||
|
||||
```
|
||||
用户勾选完成当前重复提醒
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 1. 当前记录标记完成 │
|
||||
│ - is_completed = true │
|
||||
│ - 移除重复设置:repeat_type = 'none' │
|
||||
│ repeat_interval = null │
|
||||
│ next_reminder_date = null │
|
||||
│ - 移入归档页 │
|
||||
└───────────┬─────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 2. 从 原始next_reminder_date 开始循环计算 │
|
||||
│ 直到找到 >= 当前日期 的日期作为新提醒日期 │
|
||||
│ (注意:使用计算后的日期,不使用已清空的字段) │
|
||||
│ │
|
||||
│ 示例: │
|
||||
│ - 原始next_reminder_date = 02-04 08:00 │
|
||||
│ - 当前日期 = 02-05 │
|
||||
│ - 02-04 < 02-05 → 不满足 │
|
||||
│ - 02-05 >= 02-05 → 满足 │
|
||||
│ - 新提醒日期 = 02-05 08:00 │
|
||||
└───────────┬─────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 3. 检查是否已存在相同提醒(去重) │
|
||||
│ 条件:title + date + repeat_type 完全相同 │
|
||||
│ - 存在:跳过,不创建 │
|
||||
│ - 不存在:创建新记录 │
|
||||
└───────────┬─────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 4. 创建新记录 │
|
||||
│ - date = 新提醒日期 │
|
||||
│ - repeat_type = 原始重复类型 │
|
||||
│ - repeat_interval = 原始间隔 │
|
||||
│ - next_reminder_date = 新提醒日期 + 周期 │
|
||||
└───────────┬─────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
新记录出现在对应时间分组中(带循环图标)
|
||||
```
|
||||
|
||||
**去重规则**:
|
||||
|
||||
创建新提醒时检查是否存在完全相同的记录:
|
||||
- 条件:title + date + repeat_type 完全相同
|
||||
- 存在:跳过,不创建
|
||||
- 不存在:创建新记录
|
||||
|
||||
#### 12.4.5 二次编辑
|
||||
|
||||
用户点击重复提醒卡片,弹出详情弹窗:
|
||||
|
||||
- 可修改:标题、内容、日期时间、重复方式
|
||||
- 修改重复方式后,下次周期按新规则计算
|
||||
- 修改日期时间后:
|
||||
- **不自动更新 next_reminder_date**
|
||||
- 下次勾选完成时,会从原来的 next_reminder_date 继续计算
|
||||
- 这样可以保持原始周期不被打破
|
||||
|
||||
#### 12.4.6 顺延逻辑(仅逾期提醒)
|
||||
|
||||
**场景**:用户错过了提醒日期,想要将提醒顺延到今天
|
||||
|
||||
- 只更改 `date`(当前提醒日期)
|
||||
- **不更改** `next_reminder_date`(下一次提醒日期)
|
||||
- 这样下次勾选完成时,会从原始的 next_reminder_date 继续计算周期
|
||||
|
||||
**示例**:
|
||||
|
||||
原始记录(2月1日创建):
|
||||
|
||||
```
|
||||
date = 02-01 08:00
|
||||
next_reminder_date = 02-02 08:00
|
||||
```
|
||||
|
||||
顺延到今天(2月3日)后:
|
||||
|
||||
```
|
||||
date = 02-03 08:00 ← 改变
|
||||
next_reminder_date = 02-02 08:00 ← 不变!
|
||||
```
|
||||
|
||||
2月3日勾选完成后:
|
||||
|
||||
```
|
||||
从 next_reminder_date (02-02 08:00) 开始计算
|
||||
02-02 < 当前日期(02-03) → 不满足
|
||||
02-03 >= 当前日期 → 满足
|
||||
新记录:date = 02-03 08:00, next_reminder_date = 02-04 08:00
|
||||
```
|
||||
|
||||
### 12.5 交互流程图
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 重复提醒创建流程 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────┐
|
||||
│ 用户添加提醒 │
|
||||
└────────┬─────────┘
|
||||
│
|
||||
┌───────┴───────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────┐ ┌─────────────────┐
|
||||
│ 手动添加 │ │ AI对话添加 │
|
||||
└────┬────┘ └────────┬────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────────────────┐
|
||||
│ 填写/识别重复方式 │
|
||||
│ none / daily / weekly / │
|
||||
│ yearly │
|
||||
└─────────────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ 设置重复基准日期 │
|
||||
│ repeat_base_date │
|
||||
│ (首次提醒时间) │
|
||||
└─────────────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ 创建提醒记录 │
|
||||
│ date = repeat_base_date │
|
||||
│ repeat_type = 设置值 │
|
||||
└─────────────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 显示在对应分组中 │
|
||||
│ 并显示循环icon │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 12.6 业务规则
|
||||
|
||||
1. **重复基准**:所有重复从用户设置的首次时间开始,不支持"从下周一才开始"等偏移
|
||||
2. **时间不变**:重复时只改变日期,时间分量保持不变
|
||||
3. **闰年处理**:2月29日出生的用户,每年2月28日提醒
|
||||
4. **批量操作限制**:重复提醒不支持批量删除,需要逐条确认
|
||||
5. **归档保留**:已完成的历史记录保留在归档页,供用户追溯
|
||||
6. **数量限制**:单用户最多100个有效重复提醒(防止滥用)
|
||||
|
||||
### 12.7 验收标准
|
||||
|
||||
| 场景 | 验收标准 |
|
||||
|------|----------|
|
||||
| 创建每天重复 | 创建后显示在对应分组,日期时间正确 |
|
||||
| 创建每周重复 | 创建后显示在对应分组,日期+7天计算正确 |
|
||||
| 创建每年重复 | 创建后显示在对应分组,跨年日期正确 |
|
||||
| 循环icon显示 | 正常卡片在日期时间左侧,逾期卡片在标题右侧 |
|
||||
| 勾选完成 | 当前记录归档,下一周期记录出现 |
|
||||
| 逾期列表 | 所有逾期未完成记录都显示,不只1条 |
|
||||
| 编辑重复方式 | 修改后按新规则计算后续周期 |
|
||||
| 闰年日期 | 2月29日创建的每年重复,2月28日提醒 |
|
||||
|
||||
---
|
||||
|
||||
## 13 交互优化设计
|
||||
|
||||
### 13.1 退出后跳转优化
|
||||
|
||||
**当前行为**:退出后跳转到登录页
|
||||
**优化行为**:退出后跳转到宣传页
|
||||
|
||||
**修改位置**:`HomePage.tsx` 的 `handleLogout` 函数
|
||||
```typescript
|
||||
const handleLogout = async () => {
|
||||
await logout();
|
||||
navigate('/landing'); // 改为跳转到宣传页
|
||||
};
|
||||
```
|
||||
|
||||
### 13.2 提醒列表归档入口优化
|
||||
|
||||
**当前状态**:
|
||||
- Home页面右上角有归档入口
|
||||
- 提醒列表Header有归档入口
|
||||
|
||||
**优化方案**:
|
||||
- 移除Home页面右上角的归档入口
|
||||
- 保留提醒列表Header中的归档入口(与归档页功能一致)
|
||||
|
||||
### 13.3 归档图标抖动动画
|
||||
|
||||
**触发时机**:用户勾选完成逾期提醒后
|
||||
**动画效果**:
|
||||
1. 卡片播放淡出动画(300ms)
|
||||
2. 动画完成后,归档图标触发缩放抖动动画(400ms)
|
||||
3. 示意"该提醒已收入归档"
|
||||
|
||||
**实现方式**:CSS animation `@keyframes archive-shake`
|
||||
|
||||
### 13.4 分类折叠功能
|
||||
|
||||
**位置**:提醒列表的"今天"、"明天"、"更久之后"分类
|
||||
|
||||
**功能描述**:
|
||||
- 每个分类标题右侧显示展开/折叠图标
|
||||
- 默认全部展开
|
||||
- 点击分类标题或图标切换展开/折叠状态
|
||||
- 折叠后隐藏该分类下所有卡片
|
||||
|
||||
**图标设计**:
|
||||
- 展开状态:下箭头 `IconChevronDown`
|
||||
- 折叠状态:右箭头 `IconChevronRight`
|
||||
|
||||
### 13.5 逾期列表展开/收起功能
|
||||
|
||||
**位置**:提醒列表的"已错过"分组
|
||||
|
||||
**功能描述**:
|
||||
- 默认收起状态,最多显示3条逾期提醒
|
||||
- 超过3条时显示"还有 X 个逾期提醒..."链接,点击展开
|
||||
- 展开后显示所有逾期提醒,底部显示"收起"按钮
|
||||
- 收起后恢复显示前3条
|
||||
|
||||
**交互效果**:
|
||||
- 点击"还有 X 个逾期提醒..."展开全部逾期列表
|
||||
- 展开后底部显示收起按钮,点击可收起
|
||||
- 收起/展开切换时有平滑过渡效果
|
||||
|
||||
**业务规则**:
|
||||
- 无论逾期数量多少,默认只显示前3条
|
||||
- 展开后显示所有逾期未完成提醒
|
||||
- 已过期且已完成的提醒自动移入归档页,不显示在逾期列表
|
||||
|
||||
### 13.6 无时间提醒显示优化
|
||||
|
||||
**问题场景**:
|
||||
- 用户创建的提醒未设置具体时间(00:00)
|
||||
- 自动创建的重复提醒时间显示异常
|
||||
|
||||
**优化方案**:
|
||||
- 判断逻辑:检查小时和分钟是否全为0
|
||||
- 如果 hours === 0 && minutes === 0,视为"未设置时间"
|
||||
- 显示格式:只显示日期(如"2月5日"),不显示时间
|
||||
- 归档列表同样适用此规则
|
||||
|
||||
---
|
||||
|
||||
### C. 修改记录
|
||||
|
||||
| 版本 | 日期 | 修改内容 | 修改人 |
|
||||
|------|------|----------|--------|
|
||||
| v1.0.0 | 2026-01-28 | 初稿完成 | 产品经理 |
|
||||
| v1.0.1 | 2026-02-03 | 完善提醒模块,实现归档页、设置页、优化样式 | 产品经理 |
|
||||
| v1.0.2 | 2026-02-04 | 退出跳转宣传页、移除重复归档入口、归档抖动动画、分类折叠、重复提醒完成移除设置、逾期列表展开收起、无时间提醒显示优化 | 产品经理 |
|
||||
| v1.1.0 | 待定 | 重复提醒功能:每天/每周/每年重复、循环图标、列表显示优化 | 产品经理 |
|
||||
|
||||
2
server
2
server
@ -1 +1 @@
|
||||
Subproject commit 60fdd4ec2be26590f8f96ddfe6c4468d7cf16b5a
|
||||
Subproject commit e3014a9d4c3c59735726b262ccda3c1e3b007456
|
||||
Loading…
x
Reference in New Issue
Block a user