From 8d7f2d33dfeeea3613fc31dcfb7c79929a4b5451 Mon Sep 17 00:00:00 2001 From: hzm <934585316@qq.com> Date: Wed, 18 Mar 2026 22:34:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 +- doc/localStorage 数据结构.md | 362 ++++++++++++++++++++++++++++++----- 2 files changed, 331 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index c0c2465..96a2869 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 实时基金估值 (Real-time Fund Valuation) -一个基于 Next.js 开发的纯前端基金估值与重仓股实时追踪工具。采用玻璃拟态设计(Glassmorphism),支持移动端适配。 +一个基于 Next.js 开发的基金估值与重仓股实时追踪工具。采用玻璃拟态设计(Glassmorphism),支持移动端适配。 预览地址: 1. [https://hzm0321.github.io/real-time-fund/](https://hzm0321.github.io/real-time-fund/) 2. [https://fund.cc.cd/](https://fund.cc.cd/) (加速国内访问) @@ -20,9 +20,18 @@ - **实时估值**:通过输入基金编号,实时获取并展示基金的单位净值、估值净值及实时涨跌幅。 - **重仓追踪**:自动获取基金前 10 大重仓股票,并实时追踪重仓股的盘中涨跌情况。支持收起/展开展示。 - **纯前端运行**:采用 JSONP 方案直连东方财富、腾讯财经等公开接口,彻底解决跨域问题,支持在 GitHub Pages 等静态环境直接部署。 -- **本地持久化**:使用 `localStorage` 存储已添加的基金列表及配置信息,刷新不丢失。 +- **本地持久化**:使用 `localStorage` 存储已添加的基金列表、持仓、交易记录、定投计划及配置信息,刷新不丢失。 - **响应式设计**:完美适配 PC 与移动端。针对移动端优化了文字展示、间距及交互体验。 -- **自选功能**:支持将基金添加至“自选”列表,通过 Tab 切换展示全部基金或仅自选基金。自选状态支持持久化及同步清理。 +- **自选功能**:支持将基金添加至"自选"列表,通过 Tab 切换展示全部基金或仅自选基金。自选状态支持持久化及同步清理。 +- **分组管理**:支持创建多个基金分组,方便按用途或类别管理基金。 +- **持仓管理**:记录每只基金的持有份额和成本价,自动计算持仓收益和累计收益。 +- **交易记录**:支持买入/卖出操作,记录交易历史,支持查看单个基金的交易明细。 +- **定投计划**:支持设置自动定投计划,可按日/周/月等周期自动生成买入交易。 +- **云端同步**:通过 Supabase 云端备份数据,支持多设备间数据同步与冲突处理。 +- **自定义排序**:支持多种排序规则(估值涨跌幅、持仓收益、持有金额等),可自由组合和启用/禁用规则。 +- **拖拽排序**:在默认排序模式下可通过拖拽调整基金顺序。 +- **明暗主题**:支持亮色/暗色主题切换,一键换肤。 +- **导入/导出**:支持将配置导出为 JSON 文件备份,或从文件导入恢复。 - **可自定义频率**:支持设置自动刷新间隔(5秒 - 300秒),并提供手动刷新按钮。 ## 🛠 技术栈 diff --git a/doc/localStorage 数据结构.md b/doc/localStorage 数据结构.md index b80d075..d6d03f9 100644 --- a/doc/localStorage 数据结构.md +++ b/doc/localStorage 数据结构.md @@ -12,9 +12,10 @@ ### 1. funds -**类型**: `Array` -**默认值**: `[]` +**类型**: `Array` +**默认值**: `[]` **说明**: 存储用户添加的所有基金信息 +**云端同步**: 是 **数据结构**: ```javascript @@ -43,9 +44,10 @@ ### 2. favorites -**类型**: `Array` -**默认值**: `[]` +**类型**: `Array` +**默认值**: `[]` **说明**: 存储用户标记为自选的基金代码列表 +**云端同步**: 是 **数据结构**: ```javascript @@ -65,9 +67,10 @@ ### 3. groups -**类型**: `Array` -**默认值**: `[]` +**类型**: `Array` +**默认值**: `[]` **说明**: 存储用户创建的基金分组信息 +**云端同步**: 是 **数据结构**: ```javascript @@ -89,9 +92,10 @@ ### 4. collapsedCodes -**类型**: `Array` -**默认值**: `[]` +**类型**: `Array` +**默认值**: `[]` **说明**: 存储用户收起的基金代码列表(用于折叠基金详情) +**云端同步**: 是 **数据结构**: ```javascript @@ -110,9 +114,10 @@ ### 5. collapsedTrends -**类型**: `Array` -**默认值**: `[]` +**类型**: `Array` +**默认值**: `[]` **说明**: 存储用户收起的业绩走势图表的基金代码列表 +**云端同步**: 是 **数据结构**: ```javascript @@ -131,10 +136,11 @@ ### 6. viewMode -**类型**: `string` -**默认值**: `'card'` -**可选值**: `'card'` | `'list'` +**类型**: `string` +**默认值**: `'card'` +**可选值**: `'card'` | `'list'` **说明**: 存储用户选择的视图模式 +**云端同步**: 否(仅通过 customSettings 同步) **数据结构**: ```javascript @@ -150,10 +156,11 @@ ### 7. refreshMs -**类型**: `number` (字符串存储) -**默认值**: `30000` (30秒) -**最小值**: `5000` (5秒) +**类型**: `number` (字符串存储) +**默认值**: `30000` (30秒) +**最小值**: `5000` (5秒) **说明**: 存储数据刷新间隔时间(毫秒) +**云端同步**: 是 **数据结构**: ```javascript @@ -169,9 +176,10 @@ ### 8. holdings -**类型**: `Object` -**默认值**: `{}` +**类型**: `Object` +**默认值**: `{}` **说明**: 存储用户的持仓信息 +**云端同步**: 是 **数据结构**: ```javascript @@ -196,9 +204,10 @@ ### 9. pendingTrades -**类型**: `Array` -**默认值**: `[]` +**类型**: `Array` +**默认值**: `[]` **说明**: 存储待处理的交易记录(当净值未更新时) +**云端同步**: 是 **数据结构**: ```javascript @@ -215,7 +224,6 @@ feeValue: number, // 手续费金额 date: string, // 交易日期 isAfter3pm: boolean, // 是否下午3点后 - isAfter3pm: boolean, // 是否下午3点后 timestamp: number // 时间戳 } ] @@ -230,9 +238,10 @@ ### 10. localUpdatedAt -**类型**: `string` (ISO 8601 格式) -**默认值**: `null` +**类型**: `string` (ISO 8601 格式) +**默认值**: `null` **说明**: 存储本地数据最后更新时间戳,用于云端同步冲突检测 +**云端同步**: 否(本地专用) **数据结构**: ```javascript @@ -245,12 +254,13 @@ --- -### 11. hasClosedAnnouncement_v7 +### 11. hasClosedAnnouncement_v19 -**类型**: `string` -**默认值**: `null` -**可选值**: `'true'` -**说明**: 标记用户是否已关闭公告弹窗 +**类型**: `string` +**默认值**: `null` +**可选值**: `'true'` +**说明**: 标记用户是否已关闭公告弹窗(版本号后缀用于控制不同版本的公告) +**云端同步**: 否 **数据结构**: ```javascript @@ -259,7 +269,234 @@ **使用场景**: - 控制公告弹窗显示 -- 版本号后缀(v7)用于控制公告版本 +- 版本号后缀(v19)用于控制公告版本 + +--- + +### 12. customSettings + +**类型**: `Object` +**默认值**: `{}` +**说明**: 存储用户的高级设置和偏好 +**云端同步**: 是 + +**数据结构**: +```javascript +{ + localSortRules: [ // 排序规则配置 + { + id: string, // 规则唯一标识 + field: string, // 排序字段 + label: string, // 显示标签 + direction: 'asc' | 'desc', // 排序方向 + enabled: boolean // 是否启用 + } + ], + pcContainerWidth: number, // PC端容器宽度(桌面版) + marketIndexSelected: Array, // 选中的市场指数代码 + // ... 其他自定义设置 +} +``` + +**使用场景**: +- 排序规则持久化 +- PC端布局宽度设置 +- 市场指数选择 +- 云端同步所有自定义设置 + +--- + +### 13. localSortBy / localSortOrder + +**类型**: `string` +**默认值**: `'default'` / `'asc'` +**说明**: 存储当前排序字段和排序方向 +**云端同步**: 否(通过 customSettings 同步) + +**数据结构**: +```javascript +// localSortBy +'gszzl' // 按估算涨跌幅排序 +'default' // 默认排序 + +// localSortOrder +'asc' // 升序 +'desc' // 降序 +``` + +**使用场景**: +- 快速访问当前排序状态 +- 与 customSettings.localSortRules 保持同步 + +--- + +### 14. localSortRules (旧版) + +**类型**: `Array` +**默认值**: `[]` +**说明**: 旧版排序规则存储,已迁移到 customSettings.localSortRules +**云端同步**: 否 + +**注意**: 该键已弃用,数据已迁移到 customSettings.localSortRules。代码中仍保留兼容性处理。 + +--- + +### 15. currentTab + +**类型**: `string` +**默认值**: `'all'` +**说明**: 存储用户当前选中的标签页 +**云端同步**: 否 + +**数据结构**: +```javascript +'all' // 全部资产 +'fav' // 自选 +groupId // 分组ID,如 'group_xxx' +``` + +**使用场景**: +- 恢复用户上次查看的标签页 +- 页面刷新后保持标签页状态 + +--- + +### 16. theme + +**类型**: `string` +**默认值**: `'dark'` +**可选值**: `'light'` | `'dark'` +**说明**: 存储用户选择的主题模式 +**云端同步**: 否 + +**数据结构**: +```javascript +'dark' // 暗色主题 +'light' // 亮色主题 +``` + +**使用场景**: +- 控制应用整体配色 +- 页面加载时立即应用(通过 layout.jsx 内联脚本) + +--- + +### 17. fundValuationTimeseries + +**类型**: `Object` +**默认值**: `{}` +**说明**: 存储基金估值分时数据,用于走势图展示 +**云端同步**: 否(测试中功能,暂不同步) + +**数据结构**: +```javascript +{ + "000001": [ // 按基金代码索引 + { + time: string, // 时间点 "HH:mm" + value: number, // 估算净值 + date: string // 日期 "YYYY-MM-DD" + } + ], + "110022": [ + // ... + ] +} +``` + +**数据清理规则**: +- 当新数据日期大于已存储的最大日期时,清空该基金所有旧日期数据,只保留当日分时 +- 同一日期内按时间顺序追加数据 + +**使用场景**: +- 基金详情页分时图展示 +- 实时估值数据记录 + +--- + +### 18. transactions + +**类型**: `Object` +**默认值**: `{}` +**说明**: 存储用户的交易历史记录 +**云端同步**: 是 + +**数据结构**: +```javascript +{ + "000001": [ // 按基金代码索引的交易列表 + { + id: string, // 交易唯一标识 + type: 'buy' | 'sell', // 交易类型 + amount: number, // 交易金额 + share: number, // 交易份额 + price: number, // 成交价格 + date: string, // 交易日期 + timestamp: number // 时间戳 + } + ], + "110022": [ + // ... + ] +} +``` + +**使用场景**: +- 交易历史查询 +- 收益计算 +- 买入/卖出操作记录 + +--- + +### 19. dcaPlans (定投计划) + +**类型**: `Object` +**默认值**: `{}` +**说明**: 存储用户的定投计划配置 +**云端同步**: 是 + +**数据结构**: +```javascript +{ + "000001": { // 按基金代码索引 + amount: number, // 每次定投金额 + feeRate: number, // 手续费率 + cycle: string, // 定投周期 + firstDate: string, // 首次定投日期 + enabled: boolean // 是否启用 + }, + "110022": { + // ... + } +} +``` + +**使用场景**: +- 自动定投执行 +- 定投计划管理 +- 买入操作时设置 + +--- + +### 20. marketIndexSelected + +**类型**: `Array` +**默认值**: `[]` +**说明**: 存储用户选中的市场指数代码 +**云端同步**: 否(通过 customSettings 同步) + +**数据结构**: +```javascript +[ + "sh000001", // 上证指数 + "sz399001", // 深证成指 + // ... +] +``` + +**使用场景**: +- 市场指数面板显示 +- 指数选择管理 --- @@ -267,22 +504,36 @@ ### 云端同步 -项目支持通过 Supabase 进行云端数据同步: +项目支持通过 Supabase 进行云端数据同步。以下键参与云端同步: -1. **上传到云端**: 用户登录后,本地数据会自动上传到云端 -2. **从云端下载**: 用户在其他设备登录时,会从云端下载数据 -3. **冲突处理**: 当本地和云端数据不一致时,会提示用户选择使用哪份数据 - -**同步的数据字段**: +**参与云端同步的键**: - funds - favorites - groups - collapsedCodes - collapsedTrends -- viewMode - refreshMs - holdings - pendingTrades +- transactions +- dcaPlans +- customSettings + +**不参与云端同步的键**: +- localUpdatedAt(本地专用) +- hasClosedAnnouncement_v19(本地专用) +- localSortBy / localSortOrder(通过 customSettings 同步) +- localSortRules(旧版兼容,通过 customSettings 同步) +- currentTab(本地会话状态) +- theme(本地主题偏好) +- fundValuationTimeseries(测试中功能) +- marketIndexSelected(通过 customSettings 同步) +- viewMode(通过 customSettings 同步) + +**同步流程**: +1. 用户登录后,本地数据会自动上传到云端 +2. 用户在其他设备登录时,会从云端下载数据 +3. 当本地和云端数据不一致时,会提示用户选择使用哪份数据 ### 导入/导出 @@ -296,9 +547,11 @@ groups: [], collapsedCodes: [], refreshMs: 30000, - viewMode: 'card', holdings: {}, pendingTrades: [], + transactions: {}, + dcaPlans: {}, + customSettings: {}, exportedAt: '2024-01-15T10:30:00.000Z' } ``` @@ -334,23 +587,40 @@ const dedupeByCode = (list) => { 1. 清理无效的持仓数据(基金不存在的持仓) 2. 清理无效的自选、分组、收起状态 -3. 确保数据类型正确 +3. 清理无效的交易记录和定投计划 +4. 确保数据类型正确 --- ## 存储辅助工具 -项目使用 `storageHelper` 对象来封装 localStorage 操作,提供统一的错误处理和日志记录。 +项目使用 `storageHelper` 对象来封装 localStorage 操作,提供统一的错误处理和云端同步触发。 ```javascript const storageHelper = { - setItem: (key, value) => { /* ... */ }, - getItem: (key) => { /* ... */ }, - removeItem: (key) => { /* ... */ }, - clear: () => { /* ... */ } + setItem: (key, value) => { + // 1. 写入 localStorage + // 2. 触发云端同步(如果是同步键) + // 3. 更新 localUpdatedAt 时间戳 + }, + getItem: (key) => { + // 从 localStorage 读取 + }, + removeItem: (key) => { + // 从 localStorage 删除 + // 触发云端同步 + }, + clear: () => { + // 清空所有 localStorage + } }; ``` +**特性**: +- 自动触发云端同步(对于参与同步的键) +- 自动更新 localUpdatedAt 时间戳 +- funds 变更时比较签名,避免无意义同步 + --- ## 注意事项 @@ -360,6 +630,7 @@ const storageHelper = { 3. **错误处理**: 所有 localStorage 操作都应包含 try-catch 错误处理 4. **数据格式**: 复杂数据必须使用 JSON.stringify/JSON.parse 进行序列化/反序列化 5. **版本控制**: 公告等配置使用版本号后缀,便于控制不同版本的显示 +6. **fundValuationTimeseries**: 该数据不同步到云端,因为数据量较大且属于临时性数据 --- @@ -367,10 +638,15 @@ const storageHelper = { - `app/page.jsx` - 主要页面组件,包含所有 localStorage 操作 - `app/components/Announcement.jsx` - 公告组件 +- `app/components/PcFundTable.jsx` - PC端基金表格组件 +- `app/components/MobileFundTable.jsx` - 移动端基金表格组件 +- `app/components/MarketIndexAccordion.jsx` - 市场指数组件 - `app/lib/supabase.js` - Supabase 客户端配置 +- `app/lib/valuationTimeseries.js` - 估值分时数据管理 --- ## 更新日志 +- **2026-03-18**: 全面更新文档,补充 transactions、dcaPlans、fundValuationTimeseries、customSettings 等键的详细说明,修正云端同步键列表 - **2026-02-19**: 初始文档创建