Skip to content

Latest commit

 

History

History
470 lines (381 loc) · 12.3 KB

File metadata and controls

470 lines (381 loc) · 12.3 KB

PayNote - 在线记账系统开发指南

项目概述

PayNote 是一个基于 Next.js 15 和 PostgreSQL 的现代化在线记账应用,支持多用户系统,每个用户可以独立管理自己的收支记录、查看统计报表和管理预算。

技术栈

前端

  • 框架: Next.js 15 (App Router)
  • 语言: TypeScript
  • UI 组件库: shadcn/ui
  • 样式: Tailwind CSS
  • 状态管理: React Hooks + Server Actions
  • 图表库: Recharts / Chart.js

后端

  • API: Next.js API Routes / Server Actions
  • 认证: NextAuth.js v5 (Auth.js)
  • 数据库: PostgreSQL
  • ORM: Prisma
  • 数据验证: Zod

开发工具

  • 包管理器: pnpm (推荐) / npm / yarn
  • 代码规范: ESLint + Prettier
  • Git Hooks: Husky (可选)

项目结构

paynote/
├── src/
│   ├── app/                      # Next.js 15 App Router
│   │   ├── (auth)/               # 认证相关页面
│   │   │   ├── login/
│   │   │   └── register/
│   │   ├── (dashboard)/          # 主应用页面 (需要认证)
│   │   │   ├── dashboard/        # 仪表盘
│   │   │   ├── transactions/     # 收支记录
│   │   │   ├── budgets/          # 预算管理
│   │   │   ├── reports/          # 统计报表
│   │   │   └── settings/         # 用户设置
│   │   ├── api/                  # API 路由
│   │   │   ├── auth/             # NextAuth.js 路由
│   │   │   └── [...other]/       # 其他 API 端点
│   │   ├── layout.tsx            # 根布局
│   │   └── page.tsx              # 首页
│   ├── components/               # React 组件
│   │   ├── ui/                   # shadcn/ui 组件
│   │   ├── forms/                # 表单组件
│   │   ├── charts/               # 图表组件
│   │   └── layout/               # 布局组件
│   ├── lib/                      # 工具函数和配置
│   │   ├── prisma.ts             # Prisma 客户端实例
│   │   ├── auth.ts               # NextAuth 配置
│   │   ├── utils.ts              # 通用工具函数
│   │   └── validations/          # Zod 验证模式
│   ├── types/                    # TypeScript 类型定义
│   └── actions/                  # Server Actions
│       ├── transaction.ts
│       ├── budget.ts
│       └── user.ts
├── prisma/
│   ├── schema.prisma             # 数据库模式
│   ├── migrations/               # 数据库迁移文件
│   └── seed.ts                   # 数据库种子文件
├── public/                       # 静态资源
├── .env                          # 环境变量
├── .env.example                  # 环境变量示例
├── next.config.js                # Next.js 配置
├── tailwind.config.ts            # Tailwind CSS 配置
├── tsconfig.json                 # TypeScript 配置
└── package.json

数据库设计

核心表结构

User (用户表)

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String    @unique
  emailVerified DateTime?
  image         String?
  password      String?   // 如果使用邮箱密码登录
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt

  accounts      Account[]
  sessions      Session[]
  transactions  Transaction[]
  categories    Category[]
  budgets       Budget[]
}

Account (账户表 - NextAuth)

model Account {
  id                String  @id @default(cuid())
  userId            String
  type              String
  provider          String
  providerAccountId String
  refresh_token     String?
  access_token      String?
  expires_at        Int?
  token_type        String?
  scope             String?
  id_token          String?
  session_state     String?

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([provider, providerAccountId])
}

Transaction (交易记录表)

model Transaction {
  id          String      @id @default(cuid())
  userId      String
  type        TransactionType // INCOME 或 EXPENSE
  amount      Decimal     @db.Decimal(10, 2)
  categoryId  String?
  description String?
  date        DateTime
  createdAt   DateTime    @default(now())
  updatedAt   DateTime    @updatedAt

  user     User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  category Category? @relation(fields: [categoryId], references: [id])

  @@index([userId, date])
  @@index([userId, type])
}

enum TransactionType {
  INCOME
  EXPENSE
}

Category (分类表)

model Category {
  id           String        @id @default(cuid())
  userId       String?       // null 表示系统预设分类
  name         String
  type         TransactionType
  icon         String?       // 图标名称或 emoji
  color        String?       // 颜色代码
  isSystem     Boolean       @default(false)
  createdAt    DateTime      @default(now())

  user         User?         @relation(fields: [userId], references: [id], onDelete: Cascade)
  transactions Transaction[]
  budgets      Budget[]

  @@unique([userId, name, type])
}

Budget (预算表)

model Budget {
  id         String   @id @default(cuid())
  userId     String
  categoryId String?  // null 表示总预算
  amount     Decimal  @db.Decimal(10, 2)
  period     BudgetPeriod
  startDate  DateTime
  endDate    DateTime
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  user     User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  category Category? @relation(fields: [categoryId], references: [id])

  @@index([userId, startDate, endDate])
}

enum BudgetPeriod {
  MONTHLY
  QUARTERLY
  YEARLY
}

功能模块设计

1. 用户认证模块

  • 用户注册(邮箱 + 密码)
  • 用户登录(邮箱 + 密码)
  • OAuth 登录(可选:Google, GitHub)
  • 密码重置
  • 会话管理

2. 收支记录模块

  • 添加收入/支出记录
  • 编辑记录
  • 删除记录
  • 列表查看(支持分页、筛选、排序)
  • 快速记账(简化表单)
  • 批量导入(CSV)

3. 分类管理模块

  • 系统预设分类(餐饮、交通、购物、工资、奖金等)
  • 自定义分类
  • 分类图标和颜色设置
  • 分类统计

4. 预算管理模块

  • 设置月度/季度/年度预算
  • 按分类设置预算
  • 预算执行进度显示
  • 预算超支提醒
  • 预算历史记录

5. 统计报表模块

  • 收支概览(今日、本周、本月、本年)
  • 收支趋势图(折线图)
  • 分类占比(饼图)
  • 月度对比(柱状图)
  • 自定义时间范围查询
  • 数据导出(CSV/Excel)

6. 用户设置模块

  • 个人信息管理
  • 密码修改
  • 默认货币设置
  • 主题设置(可选)

开发步骤

第一阶段:项目初始化

  1. 创建 Next.js 项目
npx create-next-app@latest paynote --typescript --tailwind --app --src-dir
cd paynote
  1. 安装依赖
# Prisma
pnpm add prisma @prisma/client
pnpm add -D prisma

# NextAuth.js
pnpm add next-auth@beta

# UI 组件
pnpm add @radix-ui/react-* # shadcn/ui 会自动安装需要的包
pnpm add class-variance-authority clsx tailwind-merge
pnpm add lucide-react # 图标库

# 表单和验证
pnpm add react-hook-form @hookform/resolvers zod

# 图表
pnpm add recharts

# 其他工具
pnpm add date-fns # 日期处理
pnpm add bcryptjs # 密码加密
pnpm add -D @types/bcryptjs
  1. 初始化 shadcn/ui
npx shadcn-ui@latest init
  1. 配置环境变量 创建 .env 文件:
# 数据库
DATABASE_URL="postgresql://username:password@localhost:5432/paynote?schema=public"

# NextAuth
NEXTAUTH_SECRET="your-secret-key-here"
NEXTAUTH_URL="http://localhost:3000"

# OAuth (可选)
# GOOGLE_CLIENT_ID=""
# GOOGLE_CLIENT_SECRET=""
  1. 初始化 Prisma
npx prisma init

第二阶段:数据库设计与实现

  1. 编写 Prisma Schema (在 prisma/schema.prisma)

    • 定义所有数据模型
    • 设置关系和索引
  2. 创建数据库迁移

npx prisma migrate dev --name init
  1. 创建种子数据 编写 prisma/seed.ts 创建系统预设分类
npx prisma db seed
  1. 创建 Prisma 客户端实例src/lib/prisma.ts 中创建单例实例

第三阶段:认证系统

  1. 配置 NextAuth.js

    • 创建 src/lib/auth.ts 配置文件
    • 设置凭据提供商(Credentials Provider)
    • 配置回调函数
  2. 创建认证 API 路由

    • src/app/api/auth/[...nextauth]/route.ts
  3. 实现注册和登录页面

    • 创建注册表单
    • 创建登录表单
    • 密码加密处理
  4. 创建认证中间件

    • 保护需要登录的路由

第四阶段:核心功能开发

  1. 仪表盘页面

    • 显示收支概览
    • 显示最近交易
    • 显示预算执行情况
  2. 收支记录管理

    • 创建交易表单组件
    • 实现 CRUD Server Actions
    • 创建交易列表页面
    • 实现筛选和排序
  3. 分类管理

    • 分类列表和编辑
    • 图标和颜色选择器
  4. 预算管理

    • 预算设置表单
    • 预算进度可视化
    • 预算提醒逻辑
  5. 统计报表

    • 实现数据聚合查询
    • 集成图表组件
    • 导出功能

第五阶段:优化与部署

  1. 性能优化

    • 实现分页和虚拟滚动
    • 优化数据库查询
    • 添加适当的索引
    • 使用 Next.js 缓存策略
  2. 用户体验优化

    • 添加加载状态
    • 错误处理和提示
    • 表单验证反馈
    • 响应式设计
  3. 测试

    • 单元测试(可选)
    • E2E 测试(可选)
  4. 部署

    • 选择部署平台(Vercel 推荐)
    • 配置生产环境数据库
    • 设置环境变量
    • 部署应用

开发建议

最佳实践

  1. 数据安全

    • 所有数据库查询必须包含 userId 过滤,确保用户只能访问自己的数据
    • 使用 Server Actions 时进行权限验证
    • 密码使用 bcrypt 加密
  2. 代码组织

    • 使用 TypeScript 严格模式
    • 创建可复用的组件
    • 使用 Zod 进行数据验证
    • Server Actions 统一放在 src/actions 目录
  3. 性能优化

    • 使用 Next.js 的 Server Components 减少客户端 JS
    • 合理使用 use client 指令
    • 数据库查询使用 Prisma 的 select 和 include 优化
    • 对列表数据实现分页
  4. 用户体验

    • 提供即时反馈(乐观更新)
    • 实现骨架屏加载状态
    • 表单验证实时反馈
    • 移动端友好设计

常见问题

  1. 数据库连接

    • 确保 PostgreSQL 服务正在运行
    • 检查 DATABASE_URL 配置是否正确
    • 使用 Prisma Studio 查看数据:npx prisma studio
  2. 认证问题

    • 确保 NEXTAUTH_SECRET 已设置
    • 检查 Session 配置
    • 使用 getServerSession 获取服务端会话
  3. 部署问题

    • 设置正确的生产环境变量
    • 运行数据库迁移:npx prisma migrate deploy
    • 确保构建成功:npm run build

扩展功能(可选)

  • 账户管理(支持多个账户,如现金、银行卡、信用卡)
  • 账户间转账记录
  • 周期性交易(自动记账)
  • 多货币支持
  • 数据备份和恢复
  • 团队账本(家庭共享)
  • 发票/收据图片上传
  • 数据可视化高级功能(预测、趋势分析)
  • PWA 支持(离线使用)
  • 通知提醒(邮件、推送)

参考资源

项目时间线(参考)

根据项目复杂度,建议按以下顺序开发:

Week 1: 项目初始化 + 数据库设计 + 认证系统 Week 2: 收支记录 CRUD + 分类管理 Week 3: 预算管理 + 统计报表基础功能 Week 4: 统计图表 + UI 优化 + 测试 Week 5: 性能优化 + 部署

下一步

按照本文档的开发步骤,从第一阶段开始逐步实现。建议先完成基础的认证和收支记录功能,再逐步添加预算和报表功能。

祝开发顺利!🚀