hailin
edc81cc55d
fix(trading+mining-app): 修复"全网兑换销毁量"显示为0的问题
...
根因:前端"全网兑换销毁量"读取的是circulationPool(流通池积分股),
但实际应该显示burn_records中source_type=SELL_BURN的销毁总量。
这是两个不同的概念:circulationPool是卖出交易进入流通的积分股,
而兑换销毁量是卖出时被销毁(进入黑洞)的积分股。
修复:
- 后端: BlackHoleRepository添加getTotalSellBurned()聚合查询
- 后端: asset.service.ts市场概览API新增totalSellBurned字段
- 前端: MarketOverview实体/Model新增totalSellBurned字段
- 前端: trading_page销毁明细弹窗改用totalSellBurned显示
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 09:52:10 -08:00
hailin
acf55b26a7
feat(pricing): 预种每份价格从 3171 调整为 3566 绿积分
...
分配规则:按 reward-service RIGHT_AMOUNTS(15831 整棵树)各项 /5 取整,
余额全归总部社区(HQ_BASE_FEE)。5 份合成一棵树 = 17830。
10 类分配金额变更:
- COST_FEE: 576 (不变, floor(2880/5))
- OPERATION_FEE: 420 (不变, floor(2100/5))
- HQ_BASE_FEE: 29.4 → 427 (3566 - 3139, 吸收全部余额)
- RWAD_POOL: 1152 (不变, floor(5760/5))
- SHARE_RIGHT: 720 (不变, floor(3600/5))
- PROVINCE_AREA: 21.6 → 21 (floor(108/5))
- PROVINCE_TEAM: 28.8 → 28 (floor(144/5))
- CITY_AREA: 50.4 → 50 (floor(252/5))
- CITY_TEAM: 57.6 → 57 (floor(288/5))
- COMMUNITY: 115.2 → 115 (floor(576/5))
- 合计: 3171 → 3566 ✓
涉及服务:planting-service, admin-service, contribution-service
涉及前端:admin-web, mobile-app (Flutter)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 08:02:17 -08:00
hailin
ed6b48562a
feat(pricing): 认种树动态定价涨价系统(总部运营成本压力涨价)
...
基础价 15831 USDT/棵不变,新增 HQ_PRICE_SUPPLEMENT 加价项全额归总部(S0000000001)。
支持手动调价+自动周期涨价,所有变更可审计,移动端动态展示价格及涨价预告。
- admin-service: TreePricingConfig/ChangeLog 表 + Service + Controller + 定时任务
- planting-service: 正式认种和预种订单快照 priceSupplement,动态价格校验
- reward-service: HQ_PRICE_SUPPLEMENT 分配类型,涨价金额直接入总部账户
- admin-web: Settings 页面新增定价配置区间(手动调价/自动涨价/变更历史)
- mobile-app: TreePricingService + 动态价格加载 + 涨价预告展示
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 03:02:56 -08:00
hailin
577979bc83
chore: 同步线上构建版本号,避免服务器编译时版本号回退
...
- mining-app: 1.0.0+1 → 1.0.0+58(与线上已发布版本对齐)
- mobile-app: 2.0.0+1 → 2.0.0+357(与线上已发布版本对齐)
构建脚本会在此基础上自动递增,下次构建将从 59/358 开始。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:29:29 -08:00
hailin
a68fe5e999
feat(mining-app): 兑换页面"流通池"改名及"已销毁量"点击查看销毁明细
...
1. 将市场数据卡片中的"流通池"标签改名为"已分配积分股"
- 展示值不变,仍为 totalMined(全网已挖矿产出总量)
2. "已销毁量"新增点击交互,点击弹出"销毁明细"对话框:
- 系统总销毁量(blackHoleAmount):当前页面已展示的黑洞销毁总量
- 全网兑换销毁量(circulationPool):卖出交易实际产生的流通池金额
- 标签旁显示 info_outline 图标提示可点击
3. 重构 _buildMarketDataItem,拆分出 _buildMarketDataItemContent:
- _buildMarketDataItem:包含 Expanded 包裹,供普通数据项使用
- _buildMarketDataItemContent:纯内容组件,支持 showTapHint 参数
- 避免 Row > GestureDetector > Expanded 的布局冲突
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:55:37 -08:00
hailin
eda39b982d
fix(mobile-app): 修复切换窗口期 NotificationBadge 混账号请求问题
...
问题(通过日志发现):
账号切换时存在一个 storage 空窗期(旧数据已清除、新数据尚未恢复完成)。
在此期间,NotificationBadgeNotifier 的 30s 定时器恰好触发,导致:
- _loadUnreadCount() 从 authProvider 内存读到旧账号 userSerialNum
- HTTP interceptor 从 storage 读到已恢复的新账号 accessToken
- 发出混账号请求:?userSerialNum=旧账号 + Authorization: Bearer 新账号token
日志证据:
_restoreAccountData() 执行期间出现
GET /notifications/unread-count?userSerialNum=D26022600000
Authorization: Bearer [D26022600001的token]
修复:
1. notification_badge_provider.dart
新增 stopAutoRefresh() 公开方法,取消 30s 定时器而不 dispose,
Provider invalidate 重建后会自动重启定时器。
2. account_switch_page.dart - _switchToAccount
在 onBeforeRestore 中补加:
ref.read(notificationBadgeProvider.notifier).stopAutoRefresh()
确保切换空窗期内 notificationBadge 定时器不触发。
同时移除 UI 层冗余的 saveCurrentAccountData() 调用——
switchToAccount() 内部已有此步骤,无需重复。
日志步骤从 [1/6]...[6/6] 更新为 [1/5]...[5/5],
并在 onBeforeRestore 注释中说明停止各定时器的原因。
切换空窗期现在所有定时器均已停止:
✓ walletStatusProvider (60s)
✓ pendingActionPollingService (4s)
✓ notificationBadgeProvider (30s) ← 本次新增
✓ TelemetryUploader (30s)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 09:09:37 -08:00
hailin
825c8a32e4
chore(mobile-app): 补全多账号切换流程的关键日志,便于验证与排查
...
切换流程中的每一步现在都有清晰的日志输出,方便通过 adb logcat
或 flutter logs 验证切换行为是否符合预期。
account_switch_page.dart - 三条路径全部覆盖:
_switchToAccount(切换账号):
[1/6] 保存当前账号数据
[2/6] 调用 switchToAccount()
[3/6] onBeforeRestore - 停止 walletStatus/pendingAction 轮询、暂停遥测
[4/6] invalidate authProvider / walletStatusProvider / notificationBadgeProvider
[5/6] 恢复遥测上传
[6/6] 导航到 ranking 页面
_addNewAccount(添加新账号):
[1/5] 保存当前账号数据
[2/5] 停止定时器
[3/5] 调用 logoutCurrentAccount()
[4/5] invalidate 三个 Provider
[5/5] 导航到 guide 页面
_deleteAccount(删除账号):
删除前打印目标账号,删除后打印剩余账号数
profile_page.dart - _performLogout(退出登录):
[1/4] 停止 walletStatus/pendingAction 轮询
[2/4] 调用 logoutCurrentAccount()
[3/4] invalidate 三个 Provider
[4/4] 导航到 guide 页面
每条关键操作完成后打印 ✓ 确认符号,便于逐步验证。
每条路径用 ========== 分隔符标识开始/完成,日志易于 grep 过滤。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 09:04:14 -08:00
hailin
e02bcf418c
fix(mobile-app): 升级弹窗禁止点击外部或返回键关闭,必须通过按钮操作
...
问题:
检测到新版本弹出升级对话框时,用户点击弹窗外部区域或按系统返回键
即可直接关闭弹窗,绕过升级提示,导致用户可能永远不会注意到更新。
修复:
对所有 3 个升级弹窗统一加两层防护:
- barrierDismissible: false — 禁止点击弹窗外部区域关闭
- PopScope(canPop: false) — 禁止系统返回键关闭
涉及弹窗:
1. self_hosted_updater.dart - _showSelfHostedUpdateDialog(自建APK更新)
2. self_hosted_updater.dart - _showMarketUpdateDialog(应用市场引导更新)
3. update_service.dart - _checkGooglePlayUpdate(Google Play 更新)
用户必须通过弹窗内按钮操作:
- 非强制更新:点击「稍后」/「暂时不更新」关闭,或点击「立即更新」开始更新
- 强制更新:只有「立即更新」按钮,无法跳过
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 08:01:52 -08:00
hailin
8f8a9230d0
fix(mobile-app): 修复多账号切换数据串号问题,完善存储隔离与状态重置
...
问题:
多账号切换时,前一个账号的推荐码、种植省市、缓存数据等会串到下一个账号,
同时定时器(钱包轮询、通知刷新、遥测上传)未正确停止/重启,
导致旧账号的 API 请求混入新账号上下文。
修复内容:
1. StorageKeys 补充种植省市常量(storage_keys.dart)
- 新增 plantingProvinceName/Code、plantingCityName/Code 4个常量
- 将硬编码的 key 统一收口,确保隔离列表引用一致
2. MultiAccountService 补全隔离列表(multi_account_service.dart)
- _accountSecureKeys 新增 inviterReferralCode(修复邀请码串号)
- _accountLocalKeys 新增 4个种植省市key + cachedAppAssets +
cachedCustomerServiceContacts(修复种植/缓存数据串号)
- switchToAccount() 新增 onBeforeRestore 回调参数,用于在
storage清空后、恢复新数据前 停止定时器
3. AccountSwitchPage 三层状态重置(account_switch_page.dart)
- _switchToAccount: onBeforeRestore 内停止 walletStatus 轮询、
pendingAction 轮询、telemetry 上传;返回后 invalidate
authProvider/walletStatusProvider/notificationBadgeProvider,
最后 resumeAfterLogin 恢复遥测
- _addNewAccount: 退出前停止定时器,退出后 invalidate Provider
4. ProfilePage 退出登录补全清理(profile_page.dart)
- _performLogout: 退出前停止 walletStatus/pendingAction 轮询,
退出后 invalidate 三个 Provider
5. 页面 key 统一引用 StorageKeys 常量
- planting_location_page.dart 和 authorization_apply_page.dart
将硬编码 key 替换为 StorageKeys.plantingXxx 常量
关键时序(switchToAccount 内部):
save → clear → onBeforeRestore(停timer) → restore → 返回
→ invalidate Provider(此时storage已恢复新数据)→ resume telemetry → navigate
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 06:13:05 -08:00
hailin
a5a69645b4
fix(trading): 流通池改为显示已挖矿产出总量,解决显示为0的问题
...
前端"流通池"原来读取 circulationPool(交易流通池),因系统尚无卖出交易故为 0。
现改为读取 totalMined(全网已挖矿产出的积分股总量 = 用户已挖 + 系统已挖)。
后端新增 getTotalMinedFromMiningService() 方法,调用 mining-service 的
GET /mining/progress 接口获取 totalDistributed。
注意:价格公式中的 circulationPool 保持不变,仍用交易流通池参与计算。
新增的 totalMined 字段仅用于前端展示。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 02:54:26 -08:00
hailin
18675f083c
fix(admin-web): 滚动区域改到 nav 内部,避免裁掉 toggle 按钮
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 06:55:32 -08:00
hailin
31d3eabcf8
fix(admin-web): 侧边栏菜单项过多时支持滚动,底部不再被截断
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 06:46:15 -08:00
hailin
e32ef9b9ff
fix(frontend): snapshot.types 补充 MPC_POSTGRES 类型和标签
...
后端新增了 MPC_POSTGRES 备份目标,前端 BackupTarget 类型和
BACKUP_TARGET_LABELS 缺少对应项导致复选框无法渲染。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 04:19:57 -08:00
hailin
26e55a649f
feat(snapshot): 进度显示增加文件大小信息,完成项显示 "完成 (29.4 MB)"
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 02:59:07 -08:00
hailin
ff28615fc3
fix(admin-web): Dockerfile 构建时传入 SNAPSHOT_SERVICE_URL build arg
...
Next.js rewrites 在构建阶段烘焙,运行时环境变量不生效
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 02:53:03 -08:00
hailin
de361e24f6
fix(infra): 网关 nginx 添加 snapshot-api 代理 + admin-web 配置 SNAPSHOT_SERVICE_URL
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 02:44:46 -08:00
hailin
30f1355bb4
fix(admin-web): snapshots 页面补上 PageContainer 包裹,恢复侧边栏
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 02:27:43 -08:00
hailin
8855491637
feat(snapshot): 进度精度升级 — Float百分比 + MB消息存DB
...
- schema: progress Int→Float,新增 progressMsg 字段
- PG handler: 百分比保留2位小数(toFixed(2)),不再 Math.floor
- orchestrator: 每2秒写DB时同时写 progressMsg (含MB信息)
- 前端: 百分比显示 toFixed(1),message 优先读 progressMsg
效果: 113GB库每次轮询进度条和MB数都有变化,不再卡在整数百分比
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 01:57:47 -08:00
hailin
38efa891b8
fix(snapshot): Dockerfile 添加 SNAPSHOT_SERVICE_URL build ARG
...
Next.js rewrites 在 build 时烘焙到 routes-manifest.json,
运行时环境变量无法覆盖。需要通过 Docker build ARG 在构建时传入。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:43:33 -08:00
hailin
ee94f1420d
fix(snapshot): 前端 API 改走 Next.js rewrites 代理 + WebSocket 改 REST 轮询
...
- snapshot.api.ts: 从直连 localhost:port 改为 /api/snapshots/* 走 Next.js 代理
- next.config: 两个前端都添加 /api/snapshots/:path* → snapshot-service 代理规则
- docker-compose.2.0-snapshot.yml: overlay 中追加 mining-admin-web 的 SNAPSHOT_SERVICE_URL
- useSnapshotWebSocket → useSnapshotPolling: 2秒轮询 GET /snapshots/:id 获取进度
- 移除 socket.io-client 依赖(Next.js standalone 不支持 WebSocket proxy)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:37:41 -08:00
hailin
ef2f0f67bf
chore: 更新前端 package-lock.json 同步 socket.io-client 依赖
...
添加 socket.io-client 到 package.json 后未同步 lock 文件,
导致 Docker 构建时 npm ci 报 EUSAGE 错误。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:56:28 -08:00
hailin
cf07eb03be
feat(snapshot): 数据快照备份服务全量实现(纯新增,零侵入)
...
一套代码两处部署的在线备份编排服务,为 1.0 认种分配系统和 2.0 算力挖矿系统
分别提供 PostgreSQL / Redis / Kafka / ZooKeeper / MinIO / Uploads 的在线备份能力。
管理员在 admin-web / mining-admin-web 中选择备份目标和存储方式,点击备份后系统
串行执行各组件备份,通过 Socket.IO WebSocket 实时推送进度到前端。
## 后端 snapshot-service(NestJS 10 + Prisma 5 + SQLite)
架构: DDD 四层(api / application / domain / infrastructure)
- api 层:
· SnapshotController — REST API(创建/查询/删除/下载)含 Range/206 断点续传
· SnapshotGateway — Socket.IO WebSocket 实时推送 5 类事件
· HealthController — 健康检查
· CreateSnapshotDto — class-validator 验证
· toSnapshotResponse — BigInt→string 序列化
- application 层:
· SnapshotOrchestratorService — 核心编排引擎
- startSnapshot() 异步启动,不阻塞 HTTP
- 按 PG→Redis→Kafka→ZK→MinIO→Uploads 顺序串行执行
- 单目标失败不中断整体任务
- MinIO 模式: 备份完上传到 MinIO 后删除本地临时文件
- LOCAL 模式: 保留在服务器临时目录供下载
- @Cron(EVERY_HOUR) 自动清理过期本地备份(默认 72h)
- runningTaskId 防止并发执行
- domain 层:
· BackupTarget 枚举(6 种目标)+ BACKUP_TARGET_ORDER 执行顺序
· SnapshotStatus 枚举(PENDING/RUNNING/COMPLETED/FAILED)
· StorageType 枚举(MINIO/LOCAL)
· BackupHandler 接口 + BACKUP_HANDLER_TOKEN
- infrastructure 层:
· 6 个备份 Handler(均实现 BackupHandler 接口):
- PostgresBackupHandler: pg_basebackup 通过网络流式备份,解析 stderr 进度
- RedisBackupHandler: BGSAVE + LASTSAVE 轮询 + 打包 dump.rdb/AOF
- KafkaBackupHandler: archiver 打包数据卷,按字节计算进度
- ZookeeperBackupHandler: archiver 打包 data/ + log/
- MinioBackupHandler: SDK 列举并下载所有桶(排除备份桶)后打包
- UploadsBackupHandler: archiver 打包上传文件目录
· 2 个存储适配器:
- MinioStorageAdapter: fPutObject 上传 / removeObjects 批量删除
- LocalStorageAdapter: 本地临时目录管理 + 过期清理
· PrismaService (SQLite) + SnapshotRepository (完整 CRUD)
· BACKUP_HANDLER_TOKEN 工厂: 根据 AVAILABLE_TARGETS 环境变量过滤可用 handler
- Prisma Schema (SQLite):
· SnapshotTask: 主表,targets 存 JSON 字符串,totalSize 用 BigInt
· SnapshotDetail: 明细表,每个目标一行,@@index([taskId])
· onDelete: Cascade 级联删除
- Dockerfile: 多阶段构建,生产镜像安装 postgresql-client + mc (MinIO CLI)
SQLite 使用 prisma db push 而非 migrate deploy
- 部署端口: 1.0 系统 = 3099,2.0 系统 = 3199
## Docker Compose overlay(纯新增,不修改现有 docker-compose)
- docker-compose.snapshot.yml (1.0):
· 挂载 redis_data/kafka_data/zookeeper_data/zookeeper_log/admin_uploads_data 只读卷
· AVAILABLE_TARGETS=POSTGRES,REDIS,KAFKA,ZOOKEEPER,MINIO,UPLOADS
· 依赖 postgres + redis 健康检查
- docker-compose.2.0-snapshot.yml (2.0 standalone):
· 挂载 redis_2_data/mining-admin-uploads/trading-uploads 只读卷
· AVAILABLE_TARGETS=POSTGRES,REDIS,UPLOADS
· 依赖 postgres-2 + redis-2 健康检查
## 前端 admin-web(Next.js 15 + SCSS)
- 新增 /snapshots 页面: 创建备份表单 + 实时进度条 + 历史列表 + 下载/删除
- 新增 useSnapshotWebSocket hook: Socket.IO 连接 + 5 类事件监听
- 新增 snapshot.api.ts: 独立 fetch(不走通用 apiClient,snapshot 服务独立端口)
- 新增 snapshot.types.ts: 共享类型定义
- 新增 page.module.scss: 表单/进度条/表格样式
- 修改 Sidebar.tsx: 添加「数据快照」菜单项
- package.json: 添加 socket.io-client 依赖
## 前端 mining-admin-web(Next.js 14 + Tailwind CSS)
- 新增 /snapshots 页面: 同 admin-web 功能,Tailwind CSS 风格
- 新增 useSnapshotWebSocket hook
- 新增 snapshot.api.ts + snapshot.types.ts
- 修改 sidebar.tsx: 添加「数据快照」菜单项 + HardDrive 图标
- package.json: 添加 socket.io-client 依赖
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:53:09 -08:00
hailin
e690a55c8e
style(transfer): 树转让 3 页面从暗夜主题改为 App 标准浅色棕金主题
...
问题:树转让的 transfer_list_page、transfer_initiate_page、
transfer_detail_page 三个页面使用了深色暗夜主题(#1A1A2E 背景 +
#16213E 卡片),与 App 其余 40+ 功能页面的浅色棕金主题不一致。
修改内容(3 个文件,纯样式重写,零业务逻辑变更):
1. 页面背景:#1A1A2E → 渐变 #FFF7E6 → #EAE0C8(与 planting_quantity_page 一致)
2. 卡片背景:#16213E → #99FFFFFF 半透明白 + boxShadow(与认种页一致)
3. AppBar:深色背景白字 → 透明背景 + 金色返回键(#D4AF37) + 棕色标题(#5D4037)
4. 正文文字:Colors.white/white70 → #5D4037 棕色 / #745D43 次级棕色
5. 输入框:#16213E 填充 → #99FFFFFF 填充 + #EAE0C8 边框
6. 按钮:ElevatedButton → GestureDetector+Container(高度 56,与全局一致)
7. 分割线:Colors.white24 → #EAE0C8
8. Tab 栏:暗色系 → 半透明白卡片容器 + 金色指示器
9. Saga 时间线未完成节点:white 20% → #EAE0C8 暖色
10. 对话框:系统默认 → #FFF7E6 背景 + 棕色文字
样式参考基准:planting_quantity_page.dart(现有认种数量页)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 20:25:25 -08:00
hailin
b3a3652f21
feat(transfer): 树转让功能全量实现(纯新增,零侵入)
...
实现已认种果树所有权在用户间转让的完整功能。采用方案一:
独立 transfer-service 微服务 + Saga 编排器模式。
=== 架构设计 ===
- Saga 编排器 8 步正向流程:卖方确认 → 冻结资金 → 锁定树 →
变更所有权 → 调整算力 → 更新统计 → 结算资金 → 完成
- 补偿回滚:任一步骤失败自动反向补偿(解冻资金 → 解锁树)
- 13 种状态:PENDING → SELLER_CONFIRMED → PAYMENT_FROZEN →
TREES_LOCKED → OWNERSHIP_TRANSFERRED → CONTRIBUTION_ADJUSTED →
STATS_UPDATED → PAYMENT_SETTLED → COMPLETED / CANCELLED /
FAILED / ROLLING_BACK / ROLLED_BACK
=== Phase 1-2: transfer-service(独立微服务) ===
新建文件:
- Prisma Schema:transfer_orders + transfer_status_logs + outbox_events
- Domain:TransferOrder 聚合根 + TransferFeeService(5% 手续费)
- Application:TransferApplicationService + SagaOrchestratorService
- Infrastructure:Kafka 事件消费/生产 + Outbox Pattern
- API:TransferController(用户端)+ AdminTransferController(管理端)
- External Clients:wallet/planting/identity-service HTTP 客户端
- Docker + 环境配置
=== Phase 3: 现有微服务扩展(纯追加) ===
planting-service:
- Prisma schema 追加 transferLockId 可空字段
- InternalTransferController:锁定/解锁/执行 3 个新端点
- Kafka handlers:transfer-lock/execute/rollback 事件处理
- main.ts 追加 Kafka consumer group 配置
referral-service:
- PlantingTransferredHandler:处理转让后团队统计更新
- TeamStatisticsAggregate 追加 handleTransfer() 方法
- TeamStatisticsRepository 追加 adjustForTransfer() 方法
- ProvinceCityDistribution 追加 transferTrees() 方法
contribution-service:
- TransferOwnershipHandler:处理所有权变更事件
- TransferAdjustmentService:算力调整(879 行核心逻辑)
- Prisma schema 追加 transferOrderId 可空字段
- ContributionAccount 追加 applyTransferAdjustment() 方法
=== Phase 4A: wallet-service(3 个新内部端点) ===
新建文件:
- FreezeForTransferDto / UnfreezeForTransferDto / SettleTransferDto
- FreezeForTransferCommand / UnfreezeForTransferCommand / SettleTransferPaymentCommand
- InternalTransferWalletController(POST freeze/unfreeze/settle-transfer)
修改文件:
- wallet-application.service.ts 追加 3 组方法(+437 行):
freezeForTransfer / unfreezeForTransfer / settleTransferPayment
(乐观锁 + 3 次重试 + Prisma $transaction + 幂等检查)
- 结算操作:单事务内更新 3 个钱包(买方扣减 + 卖方入账 + 手续费归集)
=== Phase 4B: admin-web(转让管理页面) ===
新建文件:
- transferService.ts:API 调用服务 + 完整类型定义
- useTransfers.ts:React Query hooks(list/detail/stats/forceCancel)
- /transfers/page.tsx:列表页(统计卡片 + 搜索筛选 + 分页 + 13 种状态 badge)
- /transfers/[transferOrderNo]/page.tsx:详情页(Saga 时间线 + 状态日志 + 强制取消)
- transfers.module.scss:完整样式
修改文件:
- endpoints.ts 追加 TRANSFERS 端点配置
- Sidebar.tsx 追加「转让管理」菜单项
- hooks/index.ts 追加 useTransfers 导出
=== Phase 4C: mobile-app(转让 UI) ===
新建文件:
- transfer_service.dart:Flutter API 服务 + Model(TransferOrder/Detail/StatusLog)
- transfer_list_page.dart:转让记录列表(全部/转出/转入 Tab + 下拉刷新)
- transfer_detail_page.dart:转让详情(Saga 时间线 + 确认/取消操作)
- transfer_initiate_page.dart:发起转让表单(手续费自动计算)
修改文件:
- injection_container.dart 追加 transferServiceProvider
- route_paths.dart + route_names.dart 追加 3 个路由
- app_router.dart 追加 3 个 GoRoute
- profile_page.dart 追加「发起转让」+「转让记录」按钮行
=== 基础设施 ===
- docker-compose.yml 追加 transfer-service 容器配置
- deploy.sh 追加 transfer-service 部署
- init-databases.sh 追加 transfer_db 数据库初始化
=== 纯新增原则 ===
所有变更均为追加式修改,不修改任何现有业务逻辑:
- 新增 nullable 字段(不影响现有数据)
- 新增 enum 值(不影响现有枚举使用)
- 新增 providers/controllers(不影响现有依赖注入)
- 新增页面/路由(不影响现有页面行为)
回滚方式:删除 transfer-service 目录 + 移除各服务中带 [2026-02-19] 标记的代码
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 03:44:02 -08:00
hailin
765a4f41d3
feat(pre-planting): Admin Web 预种管理页面 + Sidebar 入口
...
[2026-02-17] Admin Web 预种计划管理页面完整实现
新增文件:
- (dashboard)/pre-planting/page.tsx: 预种管理页面
- 预种开关控制卡片(开启/关闭 + 状态徽章)
- 四格统计卡片(总订单、总份数、总金额、合成树数)
- Tab 切换:预种订单 / 用户持仓 / 合并记录
- 订单表格:订单号、用户、份数、金额、状态标签、时间
- 持仓表格:用户、累计份数、待合并进度、合成树数、省市
- 合并表格:合并号、用户、树数、来源订单、合同状态、挖矿状态
- 搜索过滤、刷新、加载/错误/空状态处理
- pre-planting.module.scss: 页面样式
- 开关状态卡片(渐变背景,开/关不同主题色)
- 统计网格(4列响应式)
- Tab、表格、状态标签样式
修改文件:
- Sidebar.tsx: 新增"预种管理"菜单项(数据统计与系统维护之间)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:54:21 -08:00
hailin
63ae7662a4
feat(pre-planting): Admin Web 预种计划 Service 层
...
[2026-02-17] Admin Web 预种管理 API 服务 + React Query Hooks
新增文件:
- endpoints.ts: PRE_PLANTING 端点组(config/toggle/orders/positions/merges/stats)
- prePlantingService.ts: 预种管理服务(开关配置、订单/持仓/合并查询、统计汇总)
- 完整 TypeScript 类型定义(Config, Stats, Order, Position, Merge)
- 分页列表请求/响应类型
- usePrePlanting.ts: React Query hooks
- Query key factory(层级化参数化)
- usePrePlantingConfig/Stats/Orders/Positions/Merges
- useTogglePrePlantingConfig(mutation + 自动刷新)
- hooks/index.ts: 导出新 hooks
所有端点走 admin-service 的 PrePlantingAdminModule
与现有认种管理完全独立
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:48:58 -08:00
hailin
03f5c4af28
feat(pre-planting): Profile 页面添加预种计划入口
...
[2026-02-17] 在 Profile 页面认种按钮下方新增预种计划入口
新增内容(纯新增,不改现有逻辑):
- _goToPrePlantingPurchase():跳转预种购买页
- _goToPrePlantingPosition():跳转预种持仓页
- _buildPrePlantingButtons():两个并排按钮
- 左侧「预种购买」:金色主题,跳转购买页
- 右侧「预种持仓」:棕色主题,跳转持仓页
布局位置:认种按钮正下方,主内容卡片上方
现有功能零影响,仅新增 3 个方法 + 1 处布局插入
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:44:48 -08:00
hailin
d248f92443
feat(pre-planting): Mobile App 预种合并详情页完整实现
...
[2026-02-17] 预种合并详情页面 (pre_planting_merge_detail_page.dart)
完整功能:
- 合并信息卡片:合并号、合并时间、份数→树数、总价值、省市
- 合同签署状态卡片:待签署/已签署/已过期,含签署时间
- 挖矿状态卡片:已开启/未开启,含开启时间
- 来源订单列表:编号圆标 + 订单号 + 金额,逐条展示 5 笔订单
- 签约确认弹窗:列出签约后解锁的权限(交易/提现/授权/挖矿)
- 底部签约按钮:仅待签署状态显示,含加载状态
- 签约成功后自动刷新页面状态
UI 风格与全局一致:渐变背景、金色主色调、卡片容器
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:43:17 -08:00
hailin
99f5070552
feat(pre-planting): Mobile App 预种持仓页面完整实现
...
[2026-02-17] 预种持仓页面 (pre_planting_position_page.dart)
完整功能:
- 持仓概览卡片:累计份数、待合并份数、已合成树数(三列统计)
- 合并进度条:当前 N/5 份进度可视化 + 文字提示
- 省市信息显示(已锁定的省市)
- Tab 切换:预种订单 / 合并记录
- 预种订单列表:订单号、份数、金额、状态标签(待支付/已支付/已合并)
- 合并记录列表:合并号、树数、来源订单数、合同状态标签
- 待签约合并记录高亮显示 + "点击签署合同"提示
- 点击合并记录跳转到合并详情页
- 顶部快捷购买按钮
- 下拉刷新、错误重试、空状态提示
UI 风格与全局一致:渐变背景、金色主色调、卡片阴影
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:41:34 -08:00
hailin
8a4508fe0d
feat(pre-planting): Mobile App 预种购买页面完整实现
...
[2026-02-17] 预种计划购买页面 (pre_planting_purchase_page.dart)
完整功能:
- 并行加载数据(余额 + 配置 + 资格 + 持仓)
- 余额卡片:显示绿积分可用余额,支持刷新
- 合并进度卡片:显示当前 N/5 份进度条 + 已合成树数
- 省市选择:首次购买使用 city_pickers 选择,续购自动锁定复用
- 份数选择器:+/- 按钮 + 输入框,自动校验余额和资格限制
- 价格明细:单价 3171 USDT、最大可购买数、本次总价
- 购买确认弹窗:含合并预告(购买后将自动合成提示)
- 开关关闭禁用态:显示不可购买原因
- 错误重试、加载中状态完备
UI 风格与现有认种页面 (planting_quantity_page) 完全一致:
- 渐变背景 (#FFF7E6 → #EAE0C8)
- 金色主色调 (#D4AF37)
- 棕色文字 (#5D4037)
- 卡片容器带阴影
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:38:44 -08:00
hailin
1f9129d220
feat(pre-planting): Mobile App 预种计划路由注册 + 占位页面
...
[2026-02-17] 新增预种计划的 GoRouter 路由和占位页面:
1. route_paths.dart / route_names.dart(各 +5 行)
- /pre-planting/purchase 购买页
- /pre-planting/position 持仓页
- /pre-planting/merge/:mergeNo 合并详情页
2. app_router.dart(+28 行)
- 3 个 GoRoute 注册
3. 占位页面(3 个新文件)
- pre_planting_purchase_page.dart
- pre_planting_position_page.dart
- pre_planting_merge_detail_page.dart
后续将逐步填充完整 UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:33:26 -08:00
hailin
27751731e8
feat(pre-planting): Mobile App 预种计划 Service 层
...
[2026-02-17] 新增预种计划的 Flutter 端 API 服务层:
1. pre_planting_service.dart(新增)
- PrePlantingService:预种 API 调用(配置/资格/持仓/订单/合并/签约)
- 数据模型:PrePlantingPosition、PrePlantingOrder、PrePlantingMerge 等
- 与现有 PlantingService 完全独立
2. api_endpoints.dart(+10 行)
- 添加 /pre-planting/* 端点常量
3. injection_container.dart(+9 行)
- 注册 prePlantingServiceProvider
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:31:39 -08:00
hailin
d27f327f9c
fix(mining-app): 资产页面数据一致性修复与冗余估值隐藏
...
问题:
1. 总资产估值(顶部)使用 WebSocket 实时推送的价格和销毁倍数计算,
而积分股列表项中的"≈ xxx 积分值"使用 API 返回的静态值计算,
导致两处显示的积分值不一致(因自动销毁每分钟改变价格参数)。
2. 修复数据源统一后,积分股下方的"≈ xxx 积分值"与顶部总资产估值
完全相同,显示冗余。
修改:
- _buildAssetList 中的 multiplier 和 currentPrice 改为优先使用
WebSocket 实时值(_currentBurnMultiplier / _currentPrice),
API 值仅作为 fallback,确保与 _calculateTotalAssetValue 一致
- 暂时隐藏积分股条目下方的"≈ xxx 积分值"显示(注释保留,便于恢复)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 22:57:41 -08:00
hailin
07f7f26948
feat(mining-app): 已销毁量去掉小数位显示
...
- format_utils.dart: 新增 formatIntWithCommas(),逗号千位分隔但不保留小数
- trading_page.dart: 已销毁量改用 formatIntWithCommas()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 07:47:05 -08:00
hailin
bc3d800936
feat(mining-app): 贡献值730天失效倒计时功能
...
将贡献值页面的"贡献值失效倒计时"从硬编码静态文字改为基于用户
首次挖矿时间的真实730天倒计时。纯新增方式实现,不影响现有功能。
后端 (mining-service):
- get-mining-account.query.ts: MiningAccountDto 新增 firstMiningDate
字段,在 Promise.all 中并行查询用户最早的 miningRecord,利用
@@unique([accountSequence, miningMinute]) 索引高效查询
前端实体/模型:
- share_account.dart: 新增 DateTime? firstMiningDate(可空,向后兼容)
- share_account_model.dart: fromJson/toJson 解析和序列化 firstMiningDate
前端 UI (contribution_page.dart):
- watch shareAccountProvider 获取首次挖矿时间
- 计算已过天数和剩余天数(730 - 已过天数)
- 进度条显示实际已用时间占比
- 显示具体失效日期和剩余天数
- 无挖矿记录 → 显示"暂无挖矿记录"
- 已过期 → 显示"贡献值已失效"
- 剩余 ≤30 天 → 进度条和文字变红色警告
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 07:30:01 -08:00
hailin
6082725c80
feat(mining-app): 兑换页面积分股池和已销毁量改为原始数字显示
...
将"市场数据"中的"积分股池"和"已销毁量"从缩写单位(万/亿)
改为原始十进制数字显示,使用逗号千位分隔符。
- format_utils.dart: 新增 formatWithCommas() 函数,直接显示原始
数值并用逗号每3位分隔,不再缩写为万/亿
- trading_page.dart: 积分股池和已销毁量两个字段从 formatCompact()
改为 formatWithCommas()
示例: 52.38亿 → 5,238,000,000
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 07:29:43 -08:00
hailin
7564c1151d
feat(admin-web): 做市商充值记录流水查询功能
...
在"充值现金(积分值)"弹窗底部新增"查看充值记录"入口按钮,
点击后打开独立的充值流水记录弹窗,支持以下功能:
- 筛选 Tab:全部 / 中心化充值 / 区块链充值(通过 memo 字段区分)
- 表格列:时间、充值方式(Badge)、金额、变动前余额、变动后余额、备注
- 分页控件:上一页/下一页 + 页码显示 + 总记录数
改动文件:
- market-maker.api.ts: 新增 LedgerEntry 类型定义和 getLedgers() API 函数
- use-market-maker.ts: 新增 useCashDepositLedgers() hook
- page.tsx: 充值弹窗底部入口 + 充值记录 Dialog UI
后端 API(GET /admin/market-maker/{name}/ledgers)已存在,无需改动。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 00:46:41 -08:00
hailin
254796b08d
feat(mining-app): 提升价格显示小数精度
...
- K线详情弹窗(开/高/低/收):小数位数增加5位
- 价格≥1: 4位 → 9位
- 价格0.0001~1: 6位 → 11位
- 超小价格有效数字: 4位 → 9位
- 兑换页面"当前积分股价值":小数位数增加2位
- formatPriceFull 新增 extraDecimals 可选参数,支持按需增加精度
- 调用时传入 extraDecimals: 2
- 资产页面"总资产估值":小数位数从4位增加到6位
- formatAmount(4位) → formatDecimal(6位)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 07:46:28 -08:00
hailin
cd1d16fc7f
feat(admin-web): 批量下载支持断点续传
...
- 下载前检查文件是否已存在
- 已存在的文件自动跳过
- 显示跳过数量和新下载数量
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 00:22:04 -08:00
hailin
b2bace1687
feat(admin-web): 批量下载改为逐个下载到用户选择的目录
...
- 先弹出目录选择对话框让用户指定保存位置
- 逐个下载合同 PDF 到指定目录
- 显示下载进度(已下载数/总数)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 00:20:13 -08:00
hailin
9771a3d69d
fix(admin-web): 修复 TypeScript 类型错误
...
将 Uint8Array[] 改为 ArrayBuffer[] 以兼容 Blob 构造函数
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 00:07:18 -08:00
hailin
91132ec167
feat(admin-web): 批量下载增加进度条显示
...
- 显示打包进度和下载进度两个阶段
- 进度条实时更新百分比
- 使用 File System Access API 支持用户选择保存位置
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 00:04:02 -08:00
hailin
f97eacdc70
feat(admin-web): 批量下载支持选择保存路径
...
使用 File System Access API 让管理员可以选择文件保存位置,
而不是自动下载到默认目录。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 00:01:40 -08:00
hailin
8b7872d205
fix(admin-web): 批量下载完成后直接触发浏览器另存为对话框
...
- 创建任务后自动轮询等待完成
- 完成后使用 <a download> 触发浏览器下载对话框
- 按钮显示打包进度
- 打包期间禁用按钮防止重复点击
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:59:04 -08:00
hailin
15019206c8
fix(admin-web): 修复合同下载URL环境变量名错误
...
使用 NEXT_PUBLIC_API_BASE_URL 替代 NEXT_PUBLIC_API_URL,
与 .env.production 配置保持一致。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:37:46 -08:00
hailin
d108d2c693
fix(admin-web): 合同管理省份筛选只使用6位代码
...
PROVINCE_CODE_NAMES 同时包含2位和6位省份代码,但数据库存储的是6位代码。
筛选下拉菜单只使用6位代码,避免查询不到数据。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:32:55 -08:00
hailin
86461a052d
feat(contracts): 合同管理功能 - 查询/下载/批量打包
...
新增功能:
- 合同列表查询(支持省市、状态、时间筛选)
- 单个合同 PDF 下载(支持断点续传)
- 批量下载 ZIP 打包(异步任务处理)
- 增量下载(基于上次下载时间)
- 用户详情页合同 Tab
后端:
- planting-service: 内部合同查询 API
- admin-service: 合同管理控制器、服务、批量下载 Job
- 新增 contract_batch_download_tasks 表
前端:
- 新增独立合同管理页面 /contracts
- 用户详情页新增合同信息 Tab
- 侧边栏新增合同管理入口
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:50:17 -08:00
hailin
5bacd21840
feat(mobile-app): 为3个主导航页面添加下拉刷新功能
...
- TradingPage (兑换): 添加 RefreshIndicator,刷新时重新加载钱包和收益数据
- RankingPage (龙虎榜): 添加 RefreshIndicator,刷新时 invalidate leaderboardStatusProvider
- 列表视图和待开启状态视图均支持下拉刷新
- MiningPage (监控): 使用 LayoutBuilder + IntrinsicHeight 模式实现
- 刷新时并行加载用户数据、授权数据和钱包状态
注:ProfilePage 已有完整的下拉刷新实现,无需修改
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 21:50:43 -08:00
hailin
a1aba14ccf
feat(trade-password): 实现卖出交易的支付密码验证功能
...
## 后端改动
### auth-service
- user.aggregate.ts: 添加支付密码相关方法 (setTradePassword, verifyTradePassword, hasTradePassword)
- trade-password.service.ts: 新建支付密码业务逻辑服务
- trade-password.controller.ts: 新建支付密码 REST API (status/set/change/verify)
- user.repository.ts: 添加 tradePasswordHash 字段的持久化
- schema.prisma: 添加 trade_password_hash 字段
- migration 0003: 添加支付密码字段迁移
### trading-service
- audit-ledger.service.ts: 新建审计分类账服务 (Append-Only设计,仅INSERT)
- schema.prisma: 添加 AuditLedger 模型和 AuditActionType 枚举
- migration 0008: 添加审计分类账表迁移
## 前端改动 (mining-app)
### 新增页面/组件
- trade_password_page.dart: 支付密码设置/修改页面 (6位数字)
- trade_password_dialog.dart: 交易时的支付密码验证弹窗
### 功能集成
- trading_page.dart: 卖出时检查支付密码
- 未设置: 提示用户跳转设置页面
- 已设置: 弹出验证弹窗,验证通过后才能卖出
- profile_page.dart: 账户设置增加"支付密码"入口
- user_providers.dart: 添加支付密码相关 Provider
- auth_remote_datasource.dart: 添加支付密码 API 调用
- api_endpoints.dart: 添加支付密码 API 端点
- routes.dart/app_router.dart: 添加支付密码页面路由
## 安全设计
- 支付密码独立于登录密码 (6位纯数字)
- 审计分类账采用链式哈希保证完整性
- 所有敏感操作记录不可变审计日志
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 18:12:39 -08:00
hailin
1c621c32ec
feat(mobile-app): 暂时隐藏自助申请授权页面的"省团队"选项
...
- 在 _buildAuthorizationTypes() 方法中过滤掉 AuthorizationType.provinceTeam
- 现在"自助申请授权"页面只显示"社区"和"市团队"两个选项
- 原代码以注释形式保留,方便未来需要时快速恢复
- 相关枚举和后端逻辑保持不变,仅前端UI隐藏
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:46:02 -08:00
hailin
d29454fc74
feat(admin-web): 省团队收益汇总明细增加来源用户列并修复账户名称显示
...
问题描述:
1. 省团队收益汇总的详细明细中缺少收益来源用户信息
2. 账户类型显示为数字(如7440000)而不是省名称
修改内容:
1. 后端 reward-service (reward-application.service.ts)
- getRewardEntriesByType 方法返回值新增 sourceAccountSequence 字段
- 该字段表示触发此收益的用户账户序列号(来自认种用户)
2. 后端 reporting-service (reward-service.client.ts)
- RewardEntryDTO 接口新增 sourceAccountSequence 字段
3. 前端 admin-web
- system-account.types.ts: RewardEntryDTO 新增 sourceAccountSequence 字段
- system-account.types.ts: getAccountDisplayName 函数支持7开头的省团队账户
示例:7440000 → "广东省团队 (7440000)"
- SystemAccountsTab.tsx: 详细明细表格新增"来源用户"列
效果:
- 省团队收益明细现在显示:时间、账户(省名称)、来源用户、订单号、金额、状态
- 账户列显示格式:"{省名}省团队 ({账户序列号})"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:35:22 -08:00
hailin
04d3b2470a
feat(admin-web): 将USDT显示文本统一替换为"绿积分"
...
根据业务需求,将管理后台中所有面向用户显示的"USDT"文本改为"绿积分":
修改文件及内容:
1. system-transfer/page.tsx (7处)
- 错误提示: "最小划转金额为 1 USDT" → "最小划转金额为 1 绿积分"
- 余额显示: "余额: xxx USDT" → "余额: xxx 绿积分"
- 表单标签: "划转金额 (USDT)" → "划转金额 (绿积分)"
- 表单提示: "最小划转金额为 1 USDT" → "最小划转金额为 1 绿积分"
- 订单金额、详情弹窗金额、确认弹窗金额显示
2. userDetail.types.ts (2处)
- DEPOSIT_USDT: 'USDT充值' → '绿积分充值'
- USDT: 'USDT' → '绿积分'
3. users/[id]/page.tsx (1处)
- DEPOSIT_USDT: 'USDT充值' → '绿积分充值'
4. formatters.ts (1处)
- formatCurrency函数中 USDT: '积分 ' → '绿积分 '
注意:所有修改均为纯UI显示文本,不影响程序逻辑和功能。
映射对象的key保持不变,仅修改显示给用户的value值。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 17:29:27 -08:00
hailin
207b522754
feat(customer-service): 客服联系方式从硬编码改为后台可配置
...
将 mobile-app "联系客服" 弹窗的微信/QQ联系方式从硬编码改为
admin-web 后台动态配置,支持任意数量的联系方式管理。
## Backend (admin-service)
- 新增 Prisma 模型: ContactType 枚举(WECHAT/QQ) + CustomerServiceContact
- 新增迁移 SQL: 建表 + 2条索引 + 4条种子数据(保留现有硬编码联系方式)
- 新增双 Controller (参考 app-asset.controller.ts 模式):
- AdminCustomerServiceContactController (admin/customer-service-contacts)
GET 列表 / POST 新增 / PUT 更新 / DELETE 删除
- PublicCustomerServiceContactController (customer-service-contacts)
GET 仅返回 isEnabled=true,按 sortOrder 排序
- 注意: 公开 Controller 用 @Controller('customer-service-contacts')
避免与全局前缀 api/v1 双重叠加
## Kong 网关
- 新增路由 admin-customer-service-contacts-public
路径 /api/v1/customer-service-contacts → admin-service:3010
- Admin 端点由已有 admin-api 路由 (/api/v1/admin) 覆盖
## Admin-web
- endpoints.ts: 新增 CUSTOMER_SERVICE_CONTACTS 端点组
- customerServiceContactService.ts: CRUD 服务 (list/create/update/delete)
- settings/page.tsx: 新增"客服联系方式管理"区块
表格展示(排序/类型/标签/联系方式/启停/操作) + 内联新增/编辑表单
- settings.module.scss: contactTable / contactForm / contactFormFields 样式
## Flutter Mobile-app
- storage_keys.dart: 新增 cachedCustomerServiceContacts 缓存 key
- customer_service_contact_service.dart: API + 缓存服务
(内存5分钟TTL + SharedPreferences持久化 + 后台静默刷新)
- injection_container.dart: 注册 customerServiceContactServiceProvider
- profile_page.dart: _showCustomerServiceDialog() 从硬编码改为
动态 API 加载,contacts 为空时显示"暂无客服联系方式"占位符
## 文件清单 (4 新建 + 9 修改)
新建:
- backend/.../migrations/20260205100000_add_customer_service_contacts/migration.sql
- backend/.../controllers/customer-service-contact.controller.ts
- frontend/admin-web/src/services/customerServiceContactService.ts
- frontend/mobile-app/lib/core/services/customer_service_contact_service.dart
修改:
- backend/.../prisma/schema.prisma
- backend/.../src/app.module.ts
- backend/api-gateway/kong.yml
- frontend/admin-web/src/infrastructure/api/endpoints.ts
- frontend/admin-web/src/app/(dashboard)/settings/page.tsx
- frontend/admin-web/src/app/(dashboard)/settings/settings.module.scss
- frontend/mobile-app/lib/core/storage/storage_keys.dart
- frontend/mobile-app/lib/core/di/injection_container.dart
- frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 05:00:25 -08:00
hailin
34ba209e44
fix(app-assets): 修复公开API路径双重前缀 + Kong网关路由缺失
...
问题:移动端配置的开屏图/引导图无效
根因:
1. PublicAppAssetController 和 PublicSystemConfigController 的
@Controller('api/v1/xxx') 与 NestJS 全局前缀 api/v1 叠加,
导致实际端点为 api/v1/api/v1/xxx(双重前缀)
2. Kong 网关缺少 /api/v1/app-assets 和 /api/v1/system-config 路由
3. Flutter 端使用 /admin-service/api/v1/xxx 路径,不匹配任何 Kong 路由
修复:
- 后端:Controller 路径去掉 api/v1 前缀,由全局前缀统一添加
- Kong:新增 admin-app-assets-public 和 admin-system-config-public 路由
- Flutter:API 路径改为 /app-assets 和 /system-config/display/settings
受影响文件:
- backend/api-gateway/kong.yml (新增2条路由)
- backend/.../app-asset.controller.ts (Controller路径修正)
- backend/.../system-config.controller.ts (Controller路径修正)
- frontend/.../app_asset_service.dart (API路径修正)
- frontend/.../system_config_service.dart (API路径修正)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 04:36:53 -08:00
hailin
cba7ff590a
fix(mining-app): K线蜡烛图最小实体高度优化,消除横线"-"显示
...
问题:销毁时段(无交易)的小时K线中,open ≈ close(价差仅 ~2.8e-10),
蜡烛实体映射到像素后高度接近0,旧代码强制最小1px导致显示为横线"-"。
修复:将蜡烛实体最小高度从固定1px改为 max(bodyWidth * 0.4, 3.0)px,
即至少为蜡烛宽度的40%或3像素(取较大值),使 doji 蜡烛显示为
可辨识的小方块而非横线。有正常涨跌幅的蜡烛不受影响。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 21:31:52 -08:00
hailin
ef5ac2bf94
fix(mining-app): 价格刷新倒计时与后端销毁调度器同步
...
- 倒计时不再从页面打开时任意起点开始
- 自动计算距下一个整分钟第3秒的剩余秒数作为初始值
(销毁在每分钟第0秒执行,留3秒余量等数据库写完)
- 倒计时归零时通过 ref.invalidate 主动刷新价格数据
- 确保每次刷新都能拿到最新的销毁后价格
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 21:17:10 -08:00
hailin
abb0da36a9
feat(mining-app): 兑换页价格刷新改为60秒并显示倒计时
...
- 价格 Provider 刷新间隔从15秒改为60秒,与后端销毁调度器同步
(销毁每分钟执行一次,15秒内数据不会变化,避免无意义请求)
- 兑换页"当前积分股价值"右侧新增倒计时显示(60s→1s)
让用户直观知道下次数据刷新时间
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 21:14:16 -08:00
hailin
b639b5d499
fix(mining-app): 价格显示优化 + 涨跌幅精度再提升
...
- 兑换页顶部价格改用 formatPriceFull 显示完整零(不再用 0.0{n} 缩写)
- K线纵坐标有效数字从7位精简为4位,节省空间更简洁
- 涨跌幅精度再提升:后端 toFixed(8)→toFixed(12),前端 6位→10位小数
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:43:48 -08:00
hailin
2e91686a88
fix(mining-app): 优化页面文案与涨跌幅精度
...
- 兑换页顶部隐藏价格后方"积分值"文字,界面更简洁
- 兑换页"较上线首日"涨跌幅精度从2位小数提升至6位,每分钟销毁引起的涨幅尾数可见
- 兑换页"黑洞销毁量"文案改为"已销毁量",更直观易懂
- 贡献值页"积分股池实时余量"文案改为"100亿销毁剩余量"
- 后端 priceChangePercent 精度从 toFixed(2) 提升至 toFixed(8),支持前端高精度显示
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:23:59 -08:00
hailin
dcc46c37b6
fix(mining-app): 价格有效数字从6位调整为7位,最后2位每分钟可见变化
...
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:12:15 -08:00
hailin
f5d25afab8
fix(mining-app): 价格显示有效数字从3位增加到6位
...
每分钟销毁引起的价格变化约 4.66e-12(第7位有效数字),
原来只显示3位有效数字 0.0{5}979 无法观察到变化。
改为6位后 0.0{5}979941,最后一位每1-2分钟变化一次,
用户可在兑换页面实时观察到销毁带来的价格上涨。
影响范围:formatPrice、K线图Y轴/十字线、交易记录、挖矿记录
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:09:32 -08:00
hailin
deffdab18b
fix(mobile-upgrade): 股行App版本管理API地址改为 mapi.szaiai.com
...
mobile-upgrade 部署在榴莲皇后服务器上,股行的 mining-admin-service
运行在另一台服务器(103.39.231.240),需通过 mapi.szaiai.com 域名访问。
原配置 rwaapi.szaiai.com/mining-admin 无法路由到股行服务器,导致 30s 超时。
修改: NEXT_PUBLIC_MINING_API_URL 从 rwaapi.szaiai.com → mapi.szaiai.com
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 19:04:56 -08:00
hailin
59acea33fe
feat(trading): K线图增加周/月/年周期
...
- 前端周期选项增加「周」「月」「年」
- 后端 parsePeriodToMinutes 增加 1w/1M/1y 映射
- getPeriodStart 对日历周期按自然边界对齐:
- 1w → 周一 00:00 UTC(ISO 周标准)
- 1M → 月初1日 00:00 UTC
- 1y → 年初1月1日 00:00 UTC
- 固定周期(1m~1d)仍使用 epoch 模运算,不受影响
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 18:42:38 -08:00
hailin
c24f383501
fix(trading): K线Y轴动态缩放 + 价格显示格式统一 + 首日涨幅修复
...
- K线图Y轴改为只基于可见K线计算范围,实现动态缩放(类似TradingView)
- 价格显示统一使用 0.0{n}xxx 格式替代科学计数法,覆盖全局 formatPrice、
K线图、交易记录页、挖矿记录页
- 修复"较上线首日"百分比始终显示 +0.00% 的问题:getFirstSnapshot 过滤
price=0 的早期快照
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 18:36:26 -08:00
hailin
f13814e577
fix(mobile-app): 排名详情页隐藏敏感统计字段
...
火柴人排名详情页 (UserProfilePage) 暂时隐藏以下显示元素(代码保留,注释隐藏):
- 统计卡片:引荐数、同伴数、本人认种数(仅保留"同伴认种")
- 基本信息卡片:用户ID (accountSequence)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:41:11 -08:00
hailin
d075853a7f
feat(app-assets): 应用图片管理 — 开屏图/引导图可从 admin-web 配置
...
新增从 admin-web 后台管理开屏图(2张)和引导图(5张+标题/副标题)的完整功能链路。
移动端优先使用后台配置的远程图片,无配置或加载失败时自动回退到本地 asset。
### Backend (admin-service)
- Prisma schema 新增 AppAssetType 枚举 + AppAsset 模型 (type/sortOrder 唯一约束)
- 新增 AdminAppAssetController: 图片上传(multipart)、列表查询、元数据更新、删除
- 新增 PublicAppAssetController: 公开查询接口供移动端消费 (仅返回 isEnabled=true)
- 新增数据库 migration: 20260204100000_add_app_assets
### Admin-web
- endpoints.ts 新增 APP_ASSETS 端点组
- 新增 appAssetService.ts: list/upload/update/delete 方法
- Settings 页新增"应用图片管理"区块: 开屏图 2 卡槽 + 引导图 5 卡槽
- 每个卡槽支持: 图片上传预览、启用/禁用开关、删除、引导图额外支持标题和副标题编辑
### Mobile-app (Flutter)
- 新增 AppAssetService: 3 级缓存策略 (内存 5min TTL → SharedPreferences → 后台静默刷新)
- splash_page.dart: 支持远程开屏图 (CachedNetworkImage),fallback 到本地 asset
- guide_page.dart: 支持远程引导图+标题/副标题覆盖,fallback 到本地 asset
- 替换 2 张开屏图为新版 (1280x1826/1834, ~245KB)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 11:20:26 -08:00
hailin
50dc18a224
feat(admin-web): 用户管理高级筛选增加"已认种/未认种"过滤
...
在用户管理页面的"用户状态"下拉框中新增"已认种"和"未认种"两个筛选选项。
实现方式:
- 复用后端已有的 minAdoptions/maxAdoptions 查询参数
- "已认种"映射为 minAdoptions=1(personalAdoptionCount >= 1)
- "未认种"映射为 maxAdoptions=0(personalAdoptionCount = 0)
- 与原有"正常/冻结"状态筛选互斥(同一下拉框)
- 切换筛选时自动重置分页到第 1 页
后端无改动:admin-service 的 ListUsersDto 和 UserQueryRepository
已支持 minAdoptions/maxAdoptions 参数及对应的 WHERE 条件。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 07:58:24 -08:00
hailin
ebe7123583
feat(market-maker): 积分股(eUSDT)和积分值(fUSDT)使用独立 MPC 钱包
...
- Prisma: MarketMakerConfig 新增 eusdt_wallet_address 字段
- 后端: 初始化/更新配置时读取 EUSDT_MARKET_MAKER_ADDRESS 环境变量
- 后端: getConfig API 返回 eusdtWalletAddress
- 前端: 积分股充值弹窗使用 eusdtWalletAddress (不再共用 kavaWalletAddress)
- 前端: 积分值充值弹窗继续使用 kavaWalletAddress (fUSDT 钱包)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:39:54 -08:00
hailin
8cfd107a92
refactor(pool-accounts): 移除硬编码钱包名,改为从后端 API 动态获取
...
- 后端: 新增 GET /admin/pool-accounts 接口,返回从 .env 配置的池账户列表
- 前端: 新增 usePoolAccounts hook,动态渲染池账户卡片
- 前端: 提取 PoolAccountCard 子组件,消除重复代码
- 移除前端硬编码的 BURN_POOL_WALLET_NAME / MINING_POOL_WALLET_NAME 常量
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 02:57:40 -08:00
hailin
a5f6b23a95
feat(pool-account): 池账户充值弹窗新增中心化充值 tab
...
与做市商管理一致,充值弹窗包含"中心化充值"和"区块链充值"两个 tab。
中心化充值直接调整池账户余额(ADJUSTMENT 类型分类账),无需区块链交易。
变更:
- wallet-service: pool-account.service 新增 centralizedDeposit 方法
- wallet-service: pool-account.controller 新增 POST /centralized-deposit
- admin-service: pool-account.controller 新增 POST /:walletName/centralized-deposit 代理
- frontend: configs.api + use-configs hook + configs page 充值弹窗 Tabs UI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 02:26:31 -08:00
hailin
4f5b18be48
feat(pool-account): 实现池账户区块链充值检测和提现功能
...
为100亿销毁池和200万挖矿池实现完整的区块链充值/提现流程:
- 充值:独立扫描器检测 fUSDT 转入 → Kafka 事件 → wallet-service 入账
- 提现:前端 → admin-service 代理 → blockchain-service MPC签名转账 → wallet-service 记账
mining-blockchain-service:
- 新增 PoolAccountDeposit/PoolAccountBlockCheckpoint Prisma 模型
- 新增 PoolAccountDepositDetectionService(每5秒扫描 fUSDT 充值,每30秒更新确认数)
- 扩展 MPC 签名客户端支持 burnPool/miningPool 2-of-3 门限钱包
- 扩展 ERC20TransferService 支持池账户 fUSDT 转账
- 新增 API: POST /transfer/pool-account, GET /pool-accounts/:poolType/wallet-info
- 新增 Kafka topic 映射: pool_account.deposit.confirmed → pool_account.deposits
mining-wallet-service:
- TransactionType 枚举新增 BLOCKCHAIN_DEPOSIT/BLOCKCHAIN_WITHDRAW
- Seed: SHARE_POOL_A/B 初始余额改为0(完全靠链上充值)
- PoolAccountService 新增 blockchainDeposit()/blockchainWithdraw() 方法
- 新增 PoolAccountDepositConsumer 监听 Kafka 充值确认事件(Redis+DB 双重幂等)
- 新增 POST /pool-accounts/blockchain-withdraw 内部 API
mining-admin-service:
- 新增 PoolAccountController 代理到 wallet-service + blockchain-service
- GET /admin/pool-accounts/:walletName/balance(并行查询链下余额+链上钱包信息)
- POST /admin/pool-accounts/:walletName/blockchain-withdraw(先链上转账再记账)
- 新增配置: MINING_WALLET_SERVICE_URL, MINING_BLOCKCHAIN_SERVICE_URL, 池钱包用户名
frontend (mining-admin-web):
- 池账户 API 从 tradingClient (→trading-service) 改为 apiClient (→admin-service)
- 移除未使用的 tradingClient 和 axios 依赖
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 01:34:06 -08:00
hailin
4d2bcc7568
fix(mining-admin): 池账户钱包配置移到后端 .env,前端从 API 读取
...
做市商的 kavaWalletAddress 是后端 API 返回的,池账户应该一样。
- 后端 mining-blockchain-service/.env.example: 新增
BURN_POOL_WALLET_USERNAME/ADDRESS 和
MINING_POOL_WALLET_USERNAME/ADDRESS(同做市商钱包配置模式)
- 前端 .env.production: 移除 NEXT_PUBLIC_BURN/MINING_POOL 变量
- 前端 configs/page.tsx: 钱包地址改从 API 响应
(poolAccountBalance.walletAddress) 读取,未配置时显示提示
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 00:14:38 -08:00
hailin
6dbb620e82
feat(mining-admin): 配置管理新增100亿销毁池和200万挖矿池账户
...
在配置管理页面新增两个池账户卡片,UI 风格对齐做市商管理中的
"现金余额(积分值)",仅支持区块链方式充值与提现:
- 100亿销毁池 (wallet-22fd661f, 2-of-3 门限)
地址: 0xdE2932D2A25e1698c1354A41e2e46B414C46F5a1
- 200万挖矿池 (wallet-974e78f5, 2-of-3 门限)
地址: 0x8BC9091375ae8ef43ae011F0f9bAf10e51bC9D59
具体改动:
- .env.production: 新增 BURN_POOL / MINING_POOL 钱包名和地址环境变量
- configs.api.ts: 新增 tradingClient、PoolAccountBalance 接口、
getPoolAccountBalance 和 poolAccountBlockchainWithdraw API
- use-configs.ts: 新增 usePoolAccountBalance (30s 刷新) 和
usePoolAccountBlockchainWithdraw hooks
- configs/page.tsx: 新增两个并排池账户 Card,包含余额展示、
QR 码充值弹窗、区块链提现弹窗(含 0x 地址校验)
后端需实现:
- GET /admin/pool-accounts/:walletName/balance
- POST /admin/pool-accounts/:walletName/blockchain-withdraw
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 00:02:32 -08:00
hailin
6f43408da5
fix(mining-admin-web): docker-compose 自动连接 rwa-2-network
...
mining-admin-web 需要同时连接 rwa-network 和 rwa-2-network,
以便通过 Next.js rewrite 直连 rwa-2-network 上的后端服务。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:43:06 -08:00
hailin
e99dc122ad
fix(nginx): API 请求改为代理到 Next.js 而非直连 mining-admin-service
...
nginx /api/ 直连 mining-admin-service:3023 会绕过 Next.js rewrite,
导致 /api/trading 和 /api/mining 无法路由到对应服务 (404)。
改为代理到 Next.js (3100), 由 rewrite 规则分发到各后端服务。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:36:55 -08:00
hailin
0b8c76f8b5
fix(mining-admin-web): Dockerfile 添加 build ARG 传入后端服务地址
...
next.config.js 的 rewrite 在 next build 时计算, Docker build 阶段
环境变量不可用导致 rewrite 使用 localhost 默认值 (容器内不可达)。
添加 ARG 将服务地址传入 build 阶段:
- NEXT_PUBLIC_API_URL -> mining-admin-service:3023
- TRADING_SERVICE_URL -> trading-service:3022
- MINING_SERVICE_URL -> mining-service:3021
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:32:29 -08:00
hailin
59efdb1f78
fix(mining-admin-web): 修复 API 请求超时和路由问题
...
问题:
- mining-admin-web 容器与后端服务在不同 Docker 网络, 无法通过公网 IP 回连 (hairpin NAT 失败)
- next.config.js 生产模式强制走 mapi.szaiai.com Kong 网关, 容器内无法访问
- client.ts 使用 NEXT_PUBLIC_API_URL 导致外部 URL 被 build 时内联到客户端包
- mining-service controller 有 mining/ 前缀, 直连模式 rewrite 丢失该前缀
修复:
- next.config.js: 改用 API_GATEWAY_URL 判断路由模式, 未设置则直连后端服务
- next.config.js: mining rewrite 保留 mining/ 前缀匹配 controller 路由
- client.ts: baseURL 固定为 /api, 所有请求统一走 Next.js rewrite 代理
- docker-compose.2.0.yml: 添加 TRADING_SERVICE_URL 和 MINING_SERVICE_URL 环境变量
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 01:14:19 -08:00
hailin
394f2529cd
fix(mining-admin-web): ensure public dir exists in Docker build
...
mkdir -p public before build so COPY --from=builder /app/public works
even without static assets.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 22:03:44 -08:00
hailin
ad51aa521f
fix(mining-admin-web): add public/.gitkeep to fix Docker build
...
Dockerfile COPY --from=builder /app/public fails when public dir is missing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 22:03:01 -08:00
hailin
88ad3ab53d
feat: 2.0 API 域名从 rwaapi.szaiai.com 迁移到 mapi.szaiai.com
...
- mining-admin-web: .env.production, next.config.js fallback URL
- mining-app: environment.dart baseUrl, update_config.dart checkUpdateUrl
- docker-compose.2.0.yml: mining-admin-service UPLOAD_BASE_URL
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 21:58:03 -08:00
hailin
f39fd52001
feat(c2c-bot): rename HOT_WALLET to C2C_BOT_WALLET and change dUSDT to 绿积分
...
- Rename env vars HOT_WALLET_ADDRESS/USERNAME to C2C_BOT_WALLET_ADDRESS/USERNAME
in mining-blockchain-service to avoid conflict with existing hot wallet
- Update docker-compose.2.0.yml with new env var names
- Change all "dUSDT" labels to "绿积分" on C2C Bot admin page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 08:40:45 -08:00
hailin
251e37f772
feat(c2c-bot): 添加C2C Bot管理页面,支持运行时开关和热钱包查看
...
- 新增C2C Bot管理页面(mining-admin-web):Bot开关、热钱包余额/地址/QR码、统计、订单历史
- 新增admin API端点(trading-service):status/enable/disable/orders
- 重构Bot调度器enabled为Redis驱动,支持运行时开关(多实例安全)
- C2cOrderRepository新增findBotPurchasedOrders和getBotStats查询方法
- 侧边栏添加C2C Bot导航入口
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:47:28 -08:00
hailin
bf772967f5
feat(mining): 批量补发30%分配到运营和总部账户,并添加交易筛选器
...
- 批量补发时将剩余30%分配到运营(12%)和总部(18%)系统账户
- SystemMiningAccountRepository.mine()支持referenceId/referenceType参数
- BatchMiningExecution新增operationAmount/headquartersAmount字段(含DB迁移)
- 三层架构(mining-service→admin-service→admin-web)全链路支持referenceType筛选
- 系统账户交易记录页面增加"全部/批量补发"筛选按钮
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 04:25:20 -08:00
hailin
bcfa5143e3
fix(mining-app): C2C订单详情页自动刷新,列表刷新间隔缩短
...
- 订单详情 Provider 活跃状态(PENDING/MATCHED/PAID)每10秒自动刷新
过期/完成/取消后停止刷新,节省资源
- 市场订单和我的订单列表刷新间隔从1分钟缩短到30秒
- 离开订单详情页时立即刷新市场和我的订单列表
确保过期恢复的新PENDING订单及时在列表中显示
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 02:23:21 -08:00
hailin
7f2479d995
fix(mining-app): 更新弹窗不可点击外部关闭,订单详情按买卖角色显示不同倒计时文案
...
- 更新提示弹窗 barrierDismissible 始终为 false,防止用户误触关闭
- 订单详情页根据买家/卖家角色显示不同的倒计时提示文案
- 买方:你需要在xx:xx内完成付款 / 等待卖方确认收款
- 卖方:对方将在xx:xx内完成付款 / 请在xx:xx内确认收款
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 01:58:53 -08:00
hailin
73a617b88c
fix(c2c): 单价和总金额单位改为绿积分,待付款提示改为对方
...
- C2C市场列表/接单弹窗中单价和总金额单位从"积分值"改为"绿积分"
- 订单详情待付款倒计时提示改为"对方将在xx:xx内完成付款"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 00:57:30 -08:00
hailin
64d998c7b3
fix(trading): 卖出金额超过可用积分股时提示并禁用确认按钮
...
- 新增 _getSellValidationError 校验方法
- 输入金额反算的积分股数量 > 可用余额时显示红色提示
- 校验失败时禁用"确认交易"按钮(灰色)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:29:33 -08:00
hailin
b8f8831516
feat: PENDING订单自动过期、接单显示余额、积分股金额输入
...
1. C2C PENDING订单24小时自动过期并解冻冻结资产
- 新增 DEFAULT_PENDING_TIMEOUT_HOURS 常量
- findExpiredOrders 支持 PENDING 状态查询
- expireOrder 处理 PENDING 卖单解冻
2. C2C接单对话框显示卖方可用余额
- 确认出售时显示用户账户可用积分值(非订单数量)
- 新增订单数量行,方便对比
3. 积分股兑换页面新增金额输入
- 卖出时显示金额输入框(积分值),与数量双向联动
- 输入数量自动计算金额,输入金额自动反算数量
- 全部按钮同步更新两个字段
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:15:47 -08:00
hailin
83c29f8540
fix(c2c): 订单详情单价和总金额标签改为绿积分
...
- 单价: "积分值" → "绿积分/积分值"
- 总金额: "积分值" → "绿积分"(买方实际支付的绿积分数量)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:46:26 -08:00
hailin
6ec829a804
fix(c2c): 隐藏订单详情页的买入/卖出标签
...
订单信息卡片中移除"买入"/"卖出"类型标签,
仅保留"我发布的"标记(当用户是maker时显示)。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:43:50 -08:00
hailin
a1c3657390
fix(c2c): 修复付款水单图片无法显示的问题
...
1. 后端: proofs 图片端点添加 @Public() 装饰器,
Image.network 无法携带 JWT token
2. 前端: paymentProofUrl 是相对路径,拼接 baseUrl
构建完整 URL 供 Image.network 加载
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:16:53 -08:00
hailin
f9835c388e
fix(c2c): 我的订单显示用户角色视角,修复详情页缓存
...
1. "我的"列表根据用户是maker/taker判断实际角色,
接买单(taker)时显示"卖出"而非"买入"
2. 订单详情 provider 改为 autoDispose,每次进入详情页
都从API获取最新数据,避免显示旧的数量和状态
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:02:04 -08:00
hailin
f1c99949ad
fix(c2c): 发布页绿积分输入框和预估卡片单位标签修正
...
- 第二个输入框后缀 "积分值" → "绿积分"
- 预估卡片第二行标签 "积分值数量" → "绿积分数量",单位 → "绿积分"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 20:50:32 -08:00
hailin
6bcc571453
revert(c2c): 还原C2C市场页资产概览为原始状态
...
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:25:03 -08:00
hailin
0ad1136e48
fix(c2c): 修正资产概览显示,C2C只涉及积分值不涉及积分股
...
左栏改回"可用积分值",右栏改为"冻结积分值",消除重复显示。
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:23:59 -08:00
hailin
f60e3751b8
fix(c2c): 修复水单上传权限、手机号、卖方ID、资产显示
...
- Dockerfile: 用 su-exec 模式解决 Docker volume 权限问题
- JWT guard: 从 token 提取 phone 字段
- 订单详情: 新增卖方ID显示
- C2C市场页: 修复资产概览两列重复显示 availableCash,
改为左列显示可用积分股、右列显示可用积分值
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:19:38 -08:00
hailin
e783661002
fix(c2c): 修复水单上传权限、手机号显示、卖方ID显示
...
- Dockerfile 预创建 /app/uploads/c2c-proofs 并设置正确权限
- JWT guard 从 token payload 提取 phone 字段(之前仅提取 accountSequence)
- 订单详情页订单信息组新增卖方ID显示
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:13:46 -08:00
hailin
ce173451f5
feat(c2c): 订单详情增强、付款水单上传、买单逻辑修复及schema对齐
...
- 订单详情页显示完整手机号和收款账号信息
- 新增付款水单上传功能(前后端全链路)
- 修复时间显示为本地时区格式
- 移除买单发布时的积分值余额验证(买方通过外部绿积分支付)
- 前端买单发布页隐藏余额卡片和"全部"按钮
- 补齐 Prisma migration 与 schema 差异(payment_proof_url、
bot_purchased索引、market_maker_deposits/withdraws表)
- docker-compose 新增 trading-uploads 卷用于水单持久化
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 08:54:05 -08:00
hailin
c5126187d2
feat(mining-app): 二维码扫描支持从相册选择图片识别
...
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 07:21:56 -08:00
hailin
286b82c63b
fix(c2c): 修复 RangeError 崩溃及订单详情灰色页面问题
...
根因:多处 [0] 访问空列表/空字符串导致 RangeError 崩溃
- api_client.dart: 后端错误 message 为空数组时 ?[0] 崩溃,改为安全检查
- c2c_order_detail_page.dart: nickname 和 phone 均为 null 时 name[0] 崩溃,
添加 isNotEmpty 检查和 '未知用户' 回退
- c2c_market_page.dart: makerNickname 为空字符串时 [0] 崩溃,添加 isNotEmpty 检查
这是 C2C 买方"待付款灰色页面"的根本原因:页面在渲染交易双方信息时
因空用户名 RangeError 崩溃,导致整个页面无法显示
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 07:10:05 -08:00