Skip to content

架构设计

爱生活 的分层架构、技术决策、离线优先策略与模块化设计


总体架构

爱生活 采用 Page → Store → Module (Repository) → Database Engine 的四层单向数据流。每一层只依赖下一层,上层完全不感知底层的存储引擎差异(SQLite / IndexedDB)和加解密逻辑。

┌─────────────────────────────────────────────────────────┐
│                     Pages (60+)                          │
│   页面视图层:任务列表、日历、财务仪表盘、AI对话……        │
│   只调用 Store 的方法,不直接操作数据库                   │
├─────────────────────────────────────────────────────────┤
│                     Stores (Pinia)                       │
│   状态管理层:任务、日历、习惯、番茄钟、笔记、模式……      │
│   持有 Repository 引用,管理 UI 状态和业务逻辑            │
├─────────────────────────────────────────────────────────┤
│               Modules (Repository + Types)               │
│   数据持久层:每个模块 = types.ts + repository.ts         │
│   继承 BaseRepository,自动获得 CRUD 全套能力              │
├─────────────────────────────────────────────────────────┤
│                  Database Engine                         │
│   存储引擎:DexieStore (H5) / SqliteStore (App)          │
│   透明加密:EncryptedStore 包装层                         │
└─────────────────────────────────────────────────────────┘

数据流严格单向:用户操作 → Page 调用 Store → Store 调用 Repository → Repository 写入 Engine → Engine 返回结果 → Store 更新状态 → Page 响应式更新。


目录结构

src/
├── ai/                    # AI 子系统
│   ├── pipeline.ts        #   端侧模型加载与推理(H5: Transformers.js)
│   ├── edge-stream.ts     #   端侧流式推理输出
│   ├── agent-prompt.ts    #   Agent 系统提示词模板
│   ├── model-manager.ts   #   模型下载、缓存、切换管理
│   └── actions.ts         #   AI 操作路由(20+ 动作 Schema + 执行函数)

├── database/              # 数据库层(多引擎适配)
│   ├── index.ts           #   表结构定义、字段 Schema、索引声明
│   ├── schema.ts          #   数据库版本管理
│   ├── base-repository.ts #   通用 Repository 基类
│   ├── storage-store.ts   #   uni.storage 兼容层(小程序降级)
│   ├── migration.ts       #   v1→v2 加密数据迁移
│   └── engines/
│       ├── types.ts       #   IStore<T> 统一接口
│       ├── dexie-store.ts #   H5 引擎(IndexedDB via Dexie.js)
│       ├── encrypted-store.ts # 透明加密包装器
│       └── ...            #   SqliteStore 等

├── modules/               # 业务模块(60+ 模块目录)
│   ├── task/              #   任务管理
│   │   ├── types.ts       #     Task, TaskStatus, TaskPriority 等类型
│   │   └── repository.ts  #     TaskRepository extends BaseRepository
│   ├── calendar/          #   日历
│   ├── habit/             #   习惯
│   ├── finance/           #   财务
│   ├── health/            #   健康
│   ├── knowledge/         #   知识库
│   ├── pomodoro/          #   番茄钟
│   ├── inventory/         #   库存
│   └── ...                #   其余 50+ 模块

├── stores/                # Pinia 状态管理
│   ├── task.store.ts      #   任务 Store
│   ├── calendar.store.ts  #   日历 Store
│   ├── habit.store.ts     #   习惯 Store
│   ├── note.store.ts      #   知识库/便签 Store
│   ├── pomodoro.store.ts  #   番茄钟 Store
│   ├── channel.store.ts   #   渠道 Store
│   └── mode.store.ts      #   生活模式 Store

├── sync/                  # 同步引擎
│   └── sync-manager.ts    #   可插拔 Provider 架构的同步管理器

├── services/              # 全局服务层
│   ├── event.service.ts   #   事件发射服务(跨模块联动)
│   ├── ai-agent.service.ts #  AI Agent 编排服务
│   ├── ai-insight.service.ts # AI 洞察生成服务
│   └── reminder.service.ts #  提醒服务

├── pages/                 # 页面视图(60+ 页面目录)
│   ├── task/              #   任务页面
│   ├── calendar/          #   日历页面
│   └── ...                #   其余页面

├── components/            # 通用组件库
│   ├── Layout.vue         #   应用主布局
│   ├── TabBar.vue         #   底部导航栏
│   ├── default-layout/    #   默认布局组件
│   └── ...                #   通用 UI 组件

├── hooks/                 # 通用 Hooks
│   ├── useSafeArea.ts     #   安全区域适配
│   └── useTimePhase.ts    #   时间段判断(早/中/晚)

├── types/                 # 全局类型定义
│   ├── index.ts           #   基础类型
│   ├── life-event.ts      #   生活事件类型
│   └── entity-relation.ts #   实体关系类型

├── data/                  # 静态数据
│   └── features.json      #   功能模块注册表(62 条目)

└── uni_modules/           # uni-app 原生模块
    ├── biometric-auth2/   #   生物认证(Face ID / 指纹)
    └── llama-ai3/         #   Llama.cpp 原生 AI 引擎

分层设计

Page 层

页面组件只负责两件事:渲染 UI、调用 Store 方法。页面内不应出现直接操作数据库的代码。所有数据读取通过 Store 的 computed/getter,所有数据写入通过 Store 的 action。

typescript
// 典型页面组件的交互模式
const taskStore = useTaskStore()

// 读:computed 自动响应
const tasks = computed(() => taskStore.tasks)

// 写:调用 action
await taskStore.addTask({ title: '新任务', priority: 'HIGH' })

Store 层

Pinia Store 是业务逻辑的集中点。每个核心模块有一个对应的 Store,持有 Repository 实例,负责:

  • 缓存数据到响应式状态(减少数据库读取)
  • 提供 action 方法封装复杂业务流程
  • 管理 UI 状态(排序方式、筛选条件、当前选中项)
ts
// Store 模式示例
export const useTaskStore = defineStore('task', () => {
  const repo = new TaskRepository(getDatabase().tasks)
  const tasks = ref([])

  async function loadTasks() {
    tasks.value = await repo.findAll()
  }

  // data 类型: Omit Task, keyof BaseEntity
  async function addTask(data) {
    const task = await repo.create(data)
    tasks.value.unshift(task)
    emitEvent({
      type: 'task_created',
      module: 'task',
      sourceId: task.id,
      title: task.title,
    })
    return task
  }

  return { tasks, loadTasks, addTask }
})

关键约定:所有成功的写操作(create/update/delete)都应调用 emitEvent 发射生活事件,供全局事件系统消费。

Module 层

每个模块独立一个目录,包含 types.tsrepository.ts。模块之间完全解耦——它们共享 BaseEntity 基类和 IStore<T> 接口,但彼此的 Repository 实例互不依赖。

添加新模块的成本

features.json 注册 → 创建页面组件 → 创建 src/modules/{name}/ 目录 → 定义 types 和 repository → 创建 Store。无需修改任何已有模块的代码。

Database 层

详细设计见 数据库 Schema 设计。关键架构点:

  • IStore<T> 接口统一了 DexieStore / SqliteStore / EncryptedStore 的 API
  • BaseRepository<T> 提供了开箱即用的 CRUD + 软删除 + 分页 + 批量操作
  • EncryptedStore 通过装饰器模式包装底层引擎,透明加解密

平台适配

uni-app 的条件编译指令是跨平台适配的核心机制。关键适配点:

场景策略实现方式
数据库引擎App→SQLite,H5→Dexie#ifdef APP-PLUS / #ifdef H5 条件编译
端侧 AIApp→Llama.cpp,H5→Transformers.jsuni_modules 条件编译
生物认证App→uni.指纹/面容,H5→降级密码Feature detection
文件系统App→plus.io,H5→File API条件编译
推送通知App→厂商推送,H5→不支持平台预判

条件编译发生在构建阶段,编译产物中不包含其他平台的代码,保证包体积最优。


AI 子系统

AI 子系统采用双引擎 + Agent 中间层架构,如下图所示:

用户输入


┌──────────────┐    端侧可用?
│ ai-agent     │────yes──▶ pipeline.ts ──▶ Llama.cpp / Transformers.js
│ service.ts   │              │
│ (编排层)      │         边缘流式输出
└──────────────┘
   │ 端侧不可用

SSE Stream ──▶ 云端 AI API ──▶ 流式响应

端侧 AI 引擎

平台引擎推理方式模型缓存
Android / iOSllama.cpp 原生库GPU/NPU 加速本地文件系统
H5Transformers.js (ONNX Runtime Web)WebAssembly + WebGPUIndexedDB 缓存

模型管理:model-manager.ts 负责从 HuggingFace 下载模型文件、校验完整性、维护缓存索引。端侧模型仅首次使用需下载(几百 MB),后续从本地缓存秒开。

云端 AI Agent

ai-agent.service.ts 是 Agent 编排层,负责:

  1. 接收用户自然语言输入
  2. 决定路由到端侧 AI 还是云端 AI
  3. 若路由到云端,发起 SSE 流式请求
  4. 解析响应中的 [ACTION] 标签,提取 JSON 操作指令
  5. 调用 actions.ts 中注册的执行函数,将 AI 意图转化为实际数据操作

Actions 注册表

actions.ts 定义了 20+ 个动作 Schema,每个动作包含:

  • name:动作唯一标识(如 record_transactioncreate_event
  • description:供 AI 理解的描述
  • params:参数 Schema(名称、类型、是否必填、枚举值)
  • execute:执行函数,调用对应 Store 完成数据操作
typescript
// 示例:记账动作
{
  name: 'record_transaction',
  description: '记录收支',
  params: [
    { name: 'type', type: 'string', description: '类型', required: true, enum: ['income', 'expense'] },
    { name: 'amount', type: 'number', description: '金额(元)', required: true },
    { name: 'remark', type: 'string', description: '备注', required: false },
    { name: 'category', type: 'string', description: '分类', required: false },
  ],
  execute: async (payload) => {
    return await useFinanceStore().addTransaction({
      type: payload.type as TransactionType,
      amount: Math.round((payload.amount as number) * 100), // 元→分
      remark: payload.remark as string || '',
      category: payload.category as string || '其他',
    })
  },
}

Agent Prompt

agent-prompt.ts 构建 System Prompt,包含当前日期、动作 Schema 速查表、使用示范。Prompt 只展示一种 [ACTION] JSON 格式做示例,避免端侧小模型混淆。


同步系统

整体架构

Repositories ──▶ SyncQueue (syncQueue 表)


                  SyncManager


                SyncProvider (可插拔)

                   ┌────┼────┐
                   ▼    ▼    ▼
                Gist  S3  WebDAV 未来扩展

同步队列

每个写操作完成后,Repository 将变更记录写入 syncQueue 表,字段包括 tableNamerecordIdoperation(create/update/delete)、data(变更数据快照)。

SyncManager

sync-manager.ts 是同步流程的总调度器:

  • push() — 从 syncQueue 取待同步记录,批量推送到远端 Provider
  • pull() — 从远端 Provider 拉取变更,merge 到本地
  • resolveConflict() — 基于 version 字段的乐观锁检测冲突

Provider 架构

同步后端通过 SyncProvider 接口抽象。当前实现为 Local Provider(无远端同步),但接口已预留 pushpullresolve 三个方法。未来接入 Gist / WebDAV / S3 等后端只需实现此接口即可。

冲突解决

采用乐观锁策略:每条记录有 version 字段。执行 update 时 Repository 自动将 version + 1。同步时若远端版本 > 本地版本,说明有冲突,执行合并策略(最后写入者胜出,保存冲突副本供用户手动选择)。


事件系统

services/event.service.ts 提供全局事件发射能力。任何模块的写操作在完成后都应调用 emitEvent 发射一个 LifeEvent,包含:

字段说明
type事件类型(如 task_createdmood_recorded
module来源模块
sourceId源记录 ID
title事件标题
description事件描述(可选)
timestamp事件时间
metadata扩展数据(可选)

事件写入 lifeEvents 表,可供 AI 洞察、统计面板、时间线等模块消费。例如,AI 洞察服务可以通过分析近一周的 task_completedmood_recorded 事件,生成"本周任务完成率 85%,心情指数平均 4.2"的自动摘要。


状态管理

使用 Pinia 做状态管理,采用 Setup Store 语法(Composition API 风格)。当前 7 个 Store 覆盖核心模块:

Store管理范围关键功能
task.store任务管理CRUD、分类筛选、拖拽排序
calendar.store日历事件事件 CRUD、时间范围查询
habit.store习惯打卡习惯定义、每日打卡、统计
note.store知识库/便签笔记 CRUD、笔记本管理
pomodoro.store番茄钟计时器、历史统计、设置
channel.store渠道管理渠道 CRUD
mode.store生活模式模式切换、预设管理

Store 之间通过 Pinia 的 useXxxStore() 互相引用,而非依赖注入。每个 Store 持有对应 Repository 的实例,所有写操作自动触发 emitEvent


离线优先数据流

爱生活 的核心设计哲学:网络是可选的增强,而非必需品。具体体现:

  1. 本地优先写入 — 用户操作立即写入本地数据库(SQLite/IndexedDB),同步到远端是异步的后台任务
  2. 本地优先读取 — 所有页面展示的数据来自本地数据库,不依赖网络请求
  3. AI 离线可用 — 端侧 AI 引擎在无网络时照常工作,云端 AI 仅在用户主动调用且网络可用时使用
  4. 同步滞后可接受 — 离线期间积累的变更在恢复网络后批量同步
用户操作


Store action ──▶ Repository.create/update/delete()

                   ┌───┴───┐
                   ▼       ▼
            本地写入      push 到 syncQueue
           (即时完成)     (异步后台)


                          SyncManager

                          (有网络时)

                          远端同步

这种设计意味着飞机上、地铁里、信号盲区——所有核心功能依然可用。唯一的区别是同步队列中的记录数会增长,恢复网络后自动清空。