stock-portfolio_byQwen3.6/README.md
2026-05-03 04:41:46 +08:00

319 lines
9.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Omniledger 跨界记账中枢
<div align="center">
![Next.js](https://img.shields.io/badge/Next.js-16.2.4-black?style=flat-square&logo=next.js)
![React](https://img.shields.io/badge/React-19.2.4-61DAFB?style=flat-square&logo=react)
![TypeScript](https://img.shields.io/badge/TypeScript-5.7-3178C6?style=flat-square&logo=typescript)
![PostgreSQL](https://img.shields.io/badge/PostgreSQL-16.0-336791?style=flat-square&logo=postgresql)
![Tailwind CSS](https://img.shields.io/badge/Tailwind_CSS-3.4.17-06B6D4?style=flat-square&logo=tailwindcss)
![Drizzle ORM](https://img.shields.io/badge/Drizzle_ORM-0.45.2-f5f5f5?style=flat-square&logo=drizzle)
**跨境外汇投资组合追踪系统 | Cross-Border Portfolio Tracker**
资产管理 · 交易记录 · 持仓分析 · 多币种支持 · 实时汇率
[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?logo=docker&style=flat-square)](#快速部署)
</div>
---
## 项目介绍
Omniledger 是一款专业的**跨境外汇投资组合追踪应用**,帮助用户管理多币种资产组合,支持股票、加密货币和现金的全面持仓管理。系统采用高精度数值计算,确保金融数据计算的准确性。
### 核心优势
| 特性 | 说明 |
|------|------|
| **多资产类型** | 股票、加密货币、现金全覆盖 |
| **多币种管理** | 支持 USD/HKD/CNY/JPY 等多币种交易和换算 |
| **高精度计算** | 采用 Big.js 确保金融计算精度36位精度18位小数|
| **实时持仓** | 自动聚合交易记录生成持仓报告 |
| **历史走势** | 每日快照记录,净值曲线可视化 |
| **主题切换** | 浅色/深色模式,流畅过渡动画 |
---
## 功能特性
### 仪表盘
- 总资产概览(人民币计价)
- 持仓盈亏与总盈亏实时计算
- 净值走势图表Recharts 实现)
- 资产分布饼图
### 持仓明细
- 支持展开/收起每项资产的流水明细
- 显示:现价、市值、持仓量、摊薄成本、平均成本
- 浮动盈亏与累计盈亏(金额 + 百分比)
- 一键导出 CSV
### 交易记录
- 支持交易类型:买入(BUY)、卖出(SELL)、分红(DIVIDEND)、空投(AIRDROP)、手续费(FEE)
- 高精度数值存储
- 支持修改和删除交易
### 资产管理
- 添加/查看资产STOCK/CRYPTO/CASH 三种类型)
- 统一的资产符号体系
- 批量导入历史价格
### 历史数据
- 自动记录每日组合快照
- 重构历史走势功能
- 支持导入历史价格数据
---
## 技术栈
### 前端
| 技术 | 版本 | 用途 |
|------|------|------|
| Next.js | 16.2.4 | React 框架 |
| React | 19.2.4 | UI 库 |
| TypeScript | 5.x | 类型安全 |
| Tailwind CSS | 3.4.17 | 样式框架 |
| Radix UI | - | UI 组件底层 |
| React Hook Form | 7.74.0 | 表单处理 |
| Zod | 4.3.6 | 数据验证 |
| Recharts | 3.8.1 | 图表库 |
| Lucide React | 1.11.0 | 图标库 |
| Sonner | 2.0.7 | Toast 提示 |
### 后端
| 技术 | 版本 | 用途 |
|------|------|------|
| PostgreSQL | 16.0 | 数据库 |
| Drizzle ORM | 0.45.2 | ORM 框架 |
| Big.js | 7.0.1 | 高精度计算 |
| Drizzle Kit | 0.31.10 | 数据库迁移 |
---
## 快速开始
### 环境要求
- Node.js 20+
- PostgreSQL 数据库
- npm / yarn / pnpm / bun
### 安装步骤
```bash
# 克隆项目
git clone <repository-url>
cd stock-portfolio_byQwen3.6
# 安装依赖
npm install
# 配置环境变量
cp .env.example .env.local
# 编辑 .env.local配置数据库连接
# 数据库初始化
npm run db:generate # 生成迁移文件
npm run db:push # 推送 schema 到数据库
# 启动开发服务器
npm run dev
```
打开 [http://localhost:3000](http://localhost:3000) 即可访问。
### 可用命令
| 命令 | 说明 |
|------|------|
| `npm run dev` | 启动开发服务器 |
| `npm run build` | 构建生产版本 |
| `npm run start` | 启动生产服务器 |
| `npm run lint` | 运行 ESLint 检查 |
| `npm run db:generate` | 生成数据库迁移 |
| `npm run db:push` | 推送数据库 Schema |
| `npm run db:studio` | 打开 Drizzle Studio |
---
## 快速部署
### Docker Compose
```bash
# 构建并启动
docker-compose up -d
# 查看日志
docker-compose logs -f
```
访问 [http://localhost:8080](http://localhost:8080)
### 环境变量
```env
DATABASE_URL=postgresql://user:password@localhost:5432/omniledger
```
---
## 项目结构
```
├── app/ # Next.js App Router
│ ├── dashboard/ # 仪表盘页面
│ │ ├── page.tsx # 持仓总览
│ │ ├── assets/page.tsx # 资产管理
│ │ ├── transactions/page.tsx # 交易历史
│ │ └── layout.tsx # 仪表盘布局
│ ├── layout.tsx # 根布局
│ ├── page.tsx # 根页面(重定向)
│ └── globals.css # 全局样式
├── src/
│ ├── actions/ # Server Actions
│ │ ├── asset.ts # 资产操作
│ │ ├── transaction.ts # 交易操作
│ │ ├── portfolio.ts # 持仓计算
│ │ ├── snapshots.ts # 组合快照
│ │ ├── exchange.ts # 汇率
│ │ └── market.ts # 市场数据
│ ├── components/
│ │ ├── dashboard/ # 仪表盘组件
│ │ │ ├── allocation-chart.tsx
│ │ │ └── net-worth-chart.tsx
│ │ ├── assets/ # 资产相关组件
│ │ ├── transactions/ # 交易相关组件
│ │ └── ui/ # shadcn/ui 组件
│ ├── db/
│ │ ├── index.ts # Drizzle 客户端
│ │ └── schema.ts # 数据库 Schema
│ └── lib/
│ ├── formatters.ts # 格式化工具
│ └── utils.ts # 通用工具
├── drizzle/ # 数据库迁移文件
├── scripts/ # 辅助脚本
├── public/ # 静态资源
└── package.json
```
---
## 数据库设计
### 表结构
#### users 用户表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | UUID | 主键 |
| username | VARCHAR(50) | 用户名(唯一) |
| password_hash | VARCHAR(255) | 密码哈希 |
| created_at | TIMESTAMP | 创建时间 |
#### assets 资产表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | UUID | 主键 |
| symbol | VARCHAR(20) | 资产符号(唯一) |
| name | VARCHAR(100) | 资产名称 |
| type | ENUM | STOCK/CRYPTO/CASH |
| exchange | VARCHAR(10) | 交易所(默认 US|
| baseCurrency | VARCHAR(10) | 基础货币 |
| latestPrice | NUMERIC(36,18) | 最新价格 |
| created_at | TIMESTAMP | 创建时间 |
#### transactions 交易表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | UUID | 主键 |
| assetId | UUID | 关联资产 |
| txType | ENUM | BUY/SELL/DIVIDEND/AIRDROP/FEE |
| quantity | NUMERIC(36,18) | 数量 |
| price | NUMERIC(36,18) | 价格 |
| fee | NUMERIC(36,18) | 手续费 |
| txCurrency | VARCHAR(10) | 交易货币 |
| exchangeRate | NUMERIC(20,8) | 汇率 |
| executedAt | TIMESTAMP | 执行时间 |
| createdAt | TIMESTAMP | 创建时间 |
#### exchange_rates 汇率表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | UUID | 主键 |
| fromCurrency | VARCHAR(10) | 源货币 |
| toCurrency | VARCHAR(10) | 目标货币 |
| rate | NUMERIC(20,8) | 汇率 |
| updatedAt | TIMESTAMP | 更新时间 |
#### portfolio_snapshots 组合快照表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | UUID | 主键 |
| date | DATE | 日期(唯一)|
| totalValueCny | NUMERIC(36,18) | 总值CNY|
| totalCostCny | NUMERIC(36,18) | 总成本CNY|
| createdAt | TIMESTAMP | 创建时间 |
| updatedAt | TIMESTAMP | 更新时间 |
#### asset_prices_history 资产价格历史
| 字段 | 类型 | 说明 |
|------|------|------|
| id | UUID | 主键 |
| assetId | UUID | 关联资产 |
| price | NUMERIC(36,18) | 价格 |
| date | DATE | 日期 |
| updateTime | TIMESTAMP | 更新时间 |
#### exchange_rates_history 汇率历史
| 字段 | 类型 | 说明 |
|------|------|------|
| id | UUID | 主键 |
| fromCurrency | VARCHAR(10) | 源货币 |
| toCurrency | VARCHAR(10) | 目标货币 |
| rate | NUMERIC(20,8) | 汇率 |
| fetchTime | TIMESTAMP | 抓取时间 |
---
## 开发指南
### 添加新资产
1. 进入「资产管理」页面
2. 点击「添加资产」按钮
3. 填写资产信息(符号、名称、类型、基础货币)
4. 提交保存
### 记录交易
1. 在「持仓总览」中点击资产的「添加」按钮
2. 选择交易类型(买入/卖出/分红/空投/手续费)
3. 填写交易详情(数量、价格、手续费、日期等)
4. 提交保存
### 导入历史价格
1. 在「持仓总览」中点击资产的「导入价格」按钮
2. 从 Excel 复制粘贴数据,格式:`日期, 价格`(每行一条)
3. 点击开始导入
### 主题切换
点击页面右上角主题切换按钮,可在浅色/深色模式间切换。
---
## 许可证
MIT License