From 9caeae7928d659339ec82acf1d6a950da51f3733 Mon Sep 17 00:00:00 2001 From: kennethcheng Date: Sun, 3 May 2026 04:41:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E6=A1=A3=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 214 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 155 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 9c3d5cb..e3a7605 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,16 @@ ![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.3.3-3178C6?style=flat-square&logo=typescript) +![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)](#快速部署) @@ -24,40 +25,50 @@ Omniledger 是一款专业的**跨境外汇投资组合追踪应用**,帮助 ### 核心优势 -- **多资产类型支持** - 股票、加密货币、现金全覆盖 -- **多币种管理** - 支持不同货币的交易和换算 -- **高精度计算** - 采用 Big.js 确保金融计算精度 -- **实时持仓计算** - 自动聚合交易记录生成持仓报告 +| 特性 | 说明 | +|------|------| +| **多资产类型** | 股票、加密货币、现金全覆盖 | +| **多币种管理** | 支持 USD/HKD/CNY/JPY 等多币种交易和换算 | +| **高精度计算** | 采用 Big.js 确保金融计算精度(36位精度,18位小数)| +| **实时持仓** | 自动聚合交易记录生成持仓报告 | +| **历史走势** | 每日快照记录,净值曲线可视化 | +| **主题切换** | 浅色/深色模式,流畅过渡动画 | --- ## 功能特性 -### 资产管理 -- 添加/查看资产(支持 STOCK/CRYPTO/CASH 三种类型) -- 统一的资产符号体系,防止重复 -- 资产基础货币设置 +### 仪表盘 + +- 总资产概览(人民币计价) +- 持仓盈亏与总盈亏实时计算 +- 净值走势图表(Recharts 实现) +- 资产分布饼图 + +### 持仓明细 + +- 支持展开/收起每项资产的流水明细 +- 显示:现价、市值、持仓量、摊薄成本、平均成本 +- 浮动盈亏与累计盈亏(金额 + 百分比) +- 一键导出 CSV ### 交易记录 -- 支持多种交易类型:买入(BUY)、卖出(SELL)、分红(DIVIDEND)、空投(AIRDROP)、手续费(FEE) -- 高精度数值存储(36位精度,18位小数) -- 交易手续费精确记录 -- 实时汇率支持 -### 持仓总览 -- 实时持仓计算 -- 自动聚合同资产交易 -- 持仓卡片直观展示 +- 支持交易类型:买入(BUY)、卖出(SELL)、分红(DIVIDEND)、空投(AIRDROP)、手续费(FEE) +- 高精度数值存储 +- 支持修改和删除交易 -### 交易历史 -- 完整的交易流水账 -- 按执行时间排序 -- 交易详情一览无余 +### 资产管理 -### 主题切换 -- 浅色/深色模式 -- 系统主题自动检测 -- 流畅的过渡动画 +- 添加/查看资产(STOCK/CRYPTO/CASH 三种类型) +- 统一的资产符号体系 +- 批量导入历史价格 + +### 历史数据 + +- 自动记录每日组合快照 +- 重构历史走势功能 +- 支持导入历史价格数据 --- @@ -69,12 +80,14 @@ Omniledger 是一款专业的**跨境外汇投资组合追踪应用**,帮助 |------|------|------| | Next.js | 16.2.4 | React 框架 | | React | 19.2.4 | UI 库 | -| TypeScript | 5.3.3 | 类型安全 | +| TypeScript | 5.x | 类型安全 | | Tailwind CSS | 3.4.17 | 样式框架 | -| shadcn/ui | - | UI 组件库 | +| 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 提示 | ### 后端 @@ -106,7 +119,7 @@ cd stock-portfolio_byQwen3.6 npm install # 配置环境变量 -cp .env.local.example .env.local +cp .env.example .env.local # 编辑 .env.local,配置数据库连接 # 数据库初始化 @@ -133,34 +146,64 @@ npm run dev --- +## 快速部署 + +### 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 # 全局样式 +│ ├── 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 # 持仓计算 +│ │ ├── asset.ts # 资产操作 +│ │ ├── transaction.ts # 交易操作 +│ │ ├── portfolio.ts # 持仓计算 +│ │ ├── snapshots.ts # 组合快照 +│ │ ├── exchange.ts # 汇率 +│ │ └── market.ts # 市场数据 │ ├── components/ -│ │ ├── assets/ # 资产组件 -│ │ ├── transactions/ # 交易组件 -│ │ └── ui/ # UI 基础组件 -│ ├── db/ # 数据库层 -│ │ ├── index.ts # Drizzle 客户端 -│ │ └── schema.ts # 数据库 Schema +│ │ ├── dashboard/ # 仪表盘组件 +│ │ │ ├── allocation-chart.tsx +│ │ │ └── net-worth-chart.tsx +│ │ ├── assets/ # 资产相关组件 +│ │ ├── transactions/ # 交易相关组件 +│ │ └── ui/ # shadcn/ui 组件 +│ ├── db/ +│ │ ├── index.ts # Drizzle 客户端 +│ │ └── schema.ts # 数据库 Schema │ └── lib/ -│ └── formatters.ts # 格式化工具 -├── drizzle/ # 数据库迁移 -├── public/ # 静态资源 +│ ├── formatters.ts # 格式化工具 +│ └── utils.ts # 通用工具 +├── drizzle/ # 数据库迁移文件 +├── scripts/ # 辅助脚本 +├── public/ # 静态资源 └── package.json ``` @@ -170,13 +213,24 @@ npm run dev ### 表结构 +#### 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 交易表 @@ -185,7 +239,7 @@ npm run dev | id | UUID | 主键 | | assetId | UUID | 关联资产 | | txType | ENUM | BUY/SELL/DIVIDEND/AIRDROP/FEE | -| quantity | NUMERIC(36,18) | 数量(高精度) | +| quantity | NUMERIC(36,18) | 数量 | | price | NUMERIC(36,18) | 价格 | | fee | NUMERIC(36,18) | 手续费 | | txCurrency | VARCHAR(10) | 交易货币 | @@ -193,24 +247,66 @@ npm run dev | 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. 进入「资产」页面 +1. 进入「资产管理」页面 2. 点击「添加资产」按钮 -3. 填写资产信息(符号、类型、基础货币) +3. 填写资产信息(符号、名称、类型、基础货币) 4. 提交保存 ### 记录交易 -1. 进入「持仓总览」或「交易历史」页面 -2. 点击「记录交易」按钮 -3. 选择资产和交易类型 -4. 填写交易详情(数量、价格、手续费等) -5. 提交保存 +1. 在「持仓总览」中点击资产的「添加」按钮 +2. 选择交易类型(买入/卖出/分红/空投/手续费) +3. 填写交易详情(数量、价格、手续费、日期等) +4. 提交保存 + +### 导入历史价格 + +1. 在「持仓总览」中点击资产的「导入价格」按钮 +2. 从 Excel 复制粘贴数据,格式:`日期, 价格`(每行一条) +3. 点击开始导入 ### 主题切换 @@ -220,4 +316,4 @@ npm run dev ## 许可证 -MIT License +MIT License \ No newline at end of file