心境日记 - 技术设计文档

1. 设计理念与整体方法

设计理念

  • 用户体验优先: 创建温暖、直观的界面,减少用户的学习成本
  • 隐私安全: 所有数据存储在用户本地,保护用户隐私
  • 渐进式体验: 支持离线使用,逐步引导用户建立习惯
  • 响应式设计: 确保在不同设备上都有良好的体验

整体架构方法

  • 前端单页应用 (SPA): 使用现代前端框架构建流畅的用户体验
  • 本地数据存储: 利用浏览器本地存储技术,无需后端服务器
  • 模块化组件: 采用组件化开发,提高代码复用性和维护性
  • 渐进式增强: 核心功能优先,高级功能逐步添加

2. 技术栈选择与理由

前端框架

选择: React 18 + TypeScript

  • React: 成熟的生态系统,丰富的组件库和工具
  • TypeScript: 提供类型安全,减少运行时错误,提高开发效率
  • 理由: 适合构建复杂的交互式界面,有良好的状态管理能力

构建工具

选择: Vite

  • 理由: 快速的开发服务器,优秀的 HMR 体验,现代化的构建流程

UI 组件库

选择: Antd (Ant Design) + 自定义主题

  • 理由: 丰富的组件,良好的可访问性,支持主题定制

数据可视化

选择: Chart.js + react-chartjs-2

  • 理由: 轻量级,易于使用,支持多种图表类型,动画效果好

富文本编辑器

选择: React-Quill

  • 理由: 功能丰富,易于集成,支持图片上传

数据存储

选择: LocalStorage + IndexedDB

  • LocalStorage: 存储简单的设置和小量数据
  • IndexedDB: 存储结构化数据和大文件(图片)
  • 理由: 完全本地化,无需网络连接,数据隐私安全

状态管理

选择: Zustand

  • 理由: 轻量级,API 简洁,TypeScript 支持良好

样式方案

选择: Tailwind CSS + CSS Modules

  • Tailwind CSS: 快速构建响应式界面
  • CSS Modules: 组件级样式隔离

3. 功能组件架构

核心模块结构

src/
├── components/           # 通用组件
│   ├── UI/              # 基础 UI 组件
│   ├── Layout/          # 布局组件
│   └── Charts/          # 图表组件
├── features/            # 功能模块
│   ├── EmotionRecord/   # 情绪记录功能
│   ├── Diary/           # 日记功能
│   ├── Analytics/       # 数据分析功能
│   └── DataManagement/  # 数据管理功能
├── stores/              # 状态管理
├── services/            # 数据服务
├── utils/               # 工具函数
└── types/               # TypeScript 类型定义

主要组件设计

1. 情绪记录组件 (EmotionRecord)

  • EmotionRecordForm: 情绪记录表单
  • EmotionList: 情绪记录列表
  • EmotionFilter: 情绪筛选器
  • EmotionCard: 单个情绪记录卡片

2. 日记组件 (Diary)

  • DiaryEditor: 富文本日记编辑器
  • DiaryList: 日记列表
  • DiaryViewer: 日记查看器
  • ImageUploader: 图片上传组件

3. 数据分析组件 (Analytics)

  • EmotionTrendChart: 情绪趋势图表
  • EmotionTypeChart: 情绪类型分布图
  • StatsSummary: 统计摘要
  • TimeRangeSelector: 时间范围选择器

4. 布局组件 (Layout)

  • AppLayout: 主应用布局
  • Navigation: 导航组件
  • Header: 页头组件
  • Sidebar: 侧边栏(移动端)

4. 代码与目录结构

kiro-test/
├── public/                 # 静态资源
   ├── index.html
   └── icons/             # 应用图标
├── src/
   ├── components/        # 可复用组件
      ├── UI/
         ├── Button/
         ├── Input/
         ├── Modal/
         └── Loading/
      ├── Layout/
         ├── AppLayout/
         ├── Navigation/
         └── Header/
      └── Charts/
          ├── LineChart/
          └── PieChart/
   ├── features/          # 功能模块
      ├── EmotionRecord/
         ├── components/
         ├── hooks/
         └── types/
      ├── Diary/
         ├── components/
         ├── hooks/
         └── types/
      ├── Analytics/
         ├── components/
         ├── hooks/
         └── types/
      └── DataManagement/
          ├── components/
          ├── hooks/
          └── types/
   ├── stores/            # 状态管理
      ├── emotionStore.ts
      ├── diaryStore.ts
      └── settingsStore.ts
   ├── services/          # 数据服务层
      ├── storage/
         ├── localStorage.ts
         └── indexedDB.ts
      ├── emotionService.ts
      ├── diaryService.ts
      └── exportService.ts
   ├── utils/             # 工具函数
      ├── dateUtils.ts
      ├── formatUtils.ts
      └── validationUtils.ts
   ├── types/             # TypeScript 类型
      ├── emotion.ts
      ├── diary.ts
      └── common.ts
   ├── styles/            # 全局样式
      ├── globals.css
      └── theme.css
   ├── App.tsx
   └── main.tsx
├── package.json
├── vite.config.ts
├── tailwind.config.js
├── tsconfig.json
└── README.md

5. 核心数据设计

5.1 数据结构

情绪记录数据结构

1
2
3
4
5
6
7
8
9
interface EmotionRecord {
  id: string;                    // 唯一标识符
  timestamp: number;             // 时间戳
  score: number;                 // 情绪分数 (1-10)
  emotionTypes: string[];        // 情绪类型标签
  description?: string;          // 情绪描述
  createdAt: number;            // 创建时间
  updatedAt: number;            // 更新时间
}

日记数据结构

interface DiaryEntry {
  id: string;                    // 唯一标识符
  title?: string;                // 日记标题
  content: string;               // 日记内容(HTML格式)
  images: DiaryImage[];          // 图片列表
  createdAt: number;            // 创建时间
  updatedAt: number;            // 更新时间
  wordCount: number;            // 字数统计
}

interface DiaryImage {
  id: string;                    // 图片唯一标识
  name: string;                  // 文件名
  data: string;                  // Base64 数据或 Blob URL
  size: number;                  // 文件大小
  type: string;                  // MIME 类型
}

应用设置数据结构

1
2
3
4
5
6
7
8
interface AppSettings {
  theme: 'light' | 'dark';       // 主题模式
  language: string;              // 语言设置
  emotionTags: string[];         // 自定义情绪标签
  reminderEnabled: boolean;      // 提醒功能
  reminderTime: string;          // 提醒时间
  firstTimeUse: boolean;         // 是否首次使用
}

5.2 数据存储策略

LocalStorage 使用

  • 应用设置 (app_settings)
  • 用户偏好 (user_preferences)
  • 缓存的统计数据 (cached_stats)

IndexedDB 数据库设计

// 数据库名: MoodDiaryDB
// 版本: 1

// Object Store: emotions
{
  keyPath: 'id',
  indexes: [
    { name: 'timestamp', keyPath: 'timestamp' },
    { name: 'score', keyPath: 'score' },
    { name: 'emotionTypes', keyPath: 'emotionTypes', multiEntry: true }
  ]
}

// Object Store: diaries
{
  keyPath: 'id',
  indexes: [
    { name: 'createdAt', keyPath: 'createdAt' },
    { name: 'updatedAt', keyPath: 'updatedAt' },
    { name: 'title', keyPath: 'title' }
  ]
}

// Object Store: images
{
  keyPath: 'id',
  indexes: [
    { name: 'diaryId', keyPath: 'diaryId' }
  ]
}

5.3 数据流设计

状态管理流程

1
2
3
用户操作 → 组件事件 → Store Action → Service 层 → 数据存储
组件重新渲染 ← Store 状态更新 ← Service 层返回

数据操作 API 设计

// 情绪记录服务
interface EmotionService {
  create(emotion: Omit<EmotionRecord, 'id' | 'createdAt' | 'updatedAt'>): Promise<EmotionRecord>;
  getList(options?: { startDate?: Date; endDate?: Date; limit?: number }): Promise<EmotionRecord[]>;
  update(id: string, updates: Partial<EmotionRecord>): Promise<EmotionRecord>;
  delete(id: string): Promise<void>;
  getStats(timeRange: TimeRange): Promise<EmotionStats>;
}

// 日记服务
interface DiaryService {
  create(diary: Omit<DiaryEntry, 'id' | 'createdAt' | 'updatedAt' | 'wordCount'>): Promise<DiaryEntry>;
  getList(options?: { limit?: number; search?: string }): Promise<DiaryEntry[]>;
  getById(id: string): Promise<DiaryEntry | null>;
  update(id: string, updates: Partial<DiaryEntry>): Promise<DiaryEntry>;
  delete(id: string): Promise<void>;
  search(query: string): Promise<DiaryEntry[]>;
}

6. 性能与优化策略

6.1 前端性能优化

  • 代码分割: 使用 React.lazy() 进行路由级代码分割
  • 图片优化: 压缩上传的图片,使用 WebP 格式
  • 虚拟滚动: 长列表使用虚拟滚动技术
  • 缓存策略: 合理使用 React.memo 和 useMemo

6.2 数据存储优化

  • 分页加载: 大量数据分页查询,避免一次加载过多
  • 索引优化: 在 IndexedDB 中建立合适的索引
  • 数据清理: 定期清理过期的临时数据

6.3 用户体验优化

  • 加载状态: 所有异步操作都有加载提示
  • 错误处理: 友好的错误提示和恢复机制
  • 离线支持: 核心功能支持离线使用
  • 响应式设计: 适配不同屏幕尺寸

7. 安全与隐私考虑

7.1 数据安全

  • 本地存储: 数据完全存储在用户设备上
  • 数据加密: 敏感数据在存储前进行加密
  • 输入验证: 所有用户输入都进行验证和清理

7.2 隐私保护

  • 无网络传输: 用户数据不会发送到外部服务器
  • 数据导出: 用户完全控制自己的数据
  • 清理功能: 提供数据清理和重置功能

8. 部署与发布

8.1 构建配置

  • 生产构建: 优化代码体积和性能
  • 静态资源: 使用 CDN 加速资源加载
  • PWA 支持: 配置 Service Worker 支持离线使用

8.2 部署方案

  • 静态网站托管: 可部署到 GitHub Pages、Netlify 等平台
  • 本地部署: 支持本地文件运行
Edit

Pub: 28 Jul 2025 04:52 UTC

Views: 24