Commit Graph

26 Commits

Author SHA1 Message Date
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 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 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 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 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 2136b7a144 feat(mobile-app): 添加待办操作轮询机制
解决老版本 App 升级后不重启导致无法激活待办事项的问题。

- 新增 PendingActionPollingService 定时轮询服务(每4秒检查)
- App启动时无待办则启动轮询,有待办则直接进入待办页面
- 轮询检测到待办后自动停止并跳转,防止重入问题

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 05:36:18 -08:00
hailin dacefa2b51 feat(leaderboard): add toggle control for mobile-app ranking page
- Add public /leaderboard/status endpoint (no auth required)
- Add LeaderboardService in mobile-app to fetch board status
- Update RankingPage to show "待开启" when board is disabled
- Connect admin-web leaderboard page to real API
- Board toggle now takes effect immediately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 03:35:57 -08:00
hailin 28e0396a65 feat(pending-actions): add user pending actions system
Add a fully optional pending actions system that allows admins to configure
specific tasks that users must complete after login.

Backend (identity-service):
- Add UserPendingAction model to Prisma schema
- Add migration for user_pending_actions table
- Add PendingActionService with full CRUD operations
- Add user-facing API (GET list, POST complete)
- Add admin API (CRUD, batch create)

Admin Web:
- Add pending actions management page
- Support single/batch create, edit, cancel, delete
- View action details including completion time
- Filter by userId, actionCode, status

Flutter Mobile App:
- Add PendingActionService and PendingActionCheckService
- Add PendingActionsPage for forced task execution
- Integrate into splash_page login flow
- Users must complete all pending tasks in priority order

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 18:22:51 -08:00
hailin 2a929fc082 fix(mobile-app): 修复头像更新未同步到账号列表的问题
- AccountService 添加 MultiAccountService 依赖
- updateLocalAvatarSvg() 更新后同步到账号列表
- updateProfile() 更新昵称/头像后同步到账号列表
- uploadAvatar() 上传头像后同步到账号列表
- 新增 _syncProfileToAccountList() 统一处理同步逻辑
- 调整 injection_container 依赖注入顺序

确保切换账号时显示正确的头像和昵称

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 10:25:19 -08:00
hailin 4de96dac9d fix(mobile-app): 完善退出登录时的数据清理逻辑
遵循大厂最佳实践,确保退出登录后下次登录是干净的环境:

SecureStorage 新增清除项:
- inviterReferralCode (临时邀请码)
- biometricEnabled (生物识别设置)

LocalStorage 新增清除项:
- lastSyncTime (最后同步时间)
- cachedRankingData (排行榜缓存)
- cachedMiningStatus (矿机状态缓存)

遥测数据:
- 清除用户相关的事件队列

重构:
- MultiAccountService 增加 LocalStorage 和 TelemetryStorage 依赖
- 更新依赖注入容器
- TelemetryStorage 新增 clearUserData 方法

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 09:55:17 -08:00
hailin 8ee65c95e1 fix(planting): 修复KycService构造函数参数
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 21:13:29 -08:00
hailin 59e9cddf5b feat(planting): 认种成功后检查实名认证状态
当CONTRACT_SIGNING_ENABLED=true时,认种成功后检查用户是否已完成实名认证:
- 如果未完成实名认证,显示提示弹窗引导用户去认证
- 如果已完成或功能未启用,按原有流程返回个人中心

新增:
- KycRequiredDialog 实名认证提示弹窗组件
- ContractSigningConfig 配置类和getConfig()方法
- kycServiceProvider 依赖注入

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 21:10:55 -08:00
hailin 5b8c6bc317 feat(frontend): 添加电子合同签署功能前端实现
- 添加 ContractSigningService 合同签署 API 调用服务
- 添加 ContractCheckService App 启动时检查待签署合同
- 添加 ContractSigningPage 完整签署流程页面
  - 24小时倒计时
  - 滚动阅读 → 确认法律效力 → 手写签名
  - 支持超时后补签
- 添加 PendingContractsPage 待签署合同列表
- 添加 SignaturePad 手写签名板组件
- HomeShellPage 启动时检查未签署合同,强制签署

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 20:15:13 -08:00
hailin 943fd9efe9 chore: 提交所有未提交的修改
包括:
- admin-service: 系统配置功能
- authorization-service: 自助授权申请功能
- planting-service: 资金分配服务
- reward-service: 奖励计算服务
- admin-web: 用户管理和设置页面
- mobile-app: 授权、认证、路由等功能

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 06:09:43 -08:00
hailin f3a475a6f4 feat(account): 实现多账号管理功能
- 新增 MultiAccountService 处理多账号存储和切换
- 新增 AccountSwitchPage 账号切换页面
- 修改 storage_keys.dart 添加多账号相关键和前缀方法
- 修改 ProfilePage 切换账号按钮跳转到账号切换页面
- 修改退出登录逻辑,保留账号数据只清除会话状态
- 新账号创建时自动添加到账号列表
- 支持旧单账号数据自动迁移到多账号架构
- 支持删除账号(带确认对话框)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 02:57:13 -08:00
hailin db37fbf860 feat(notification): 添加通知中心功能
后端 (admin-service):
- 新增 Notification 和 NotificationRead 数据模型
- 支持通知类型: 系统/活动/收益/升级/公告
- 实现管理端 API: 创建/更新/删除/列表
- 实现移动端 API: 获取通知列表/未读数量/标记已读

前端 (mobile-app):
- 新增 NotificationService 和 Provider
- 新增通知中心页面 (NotificationInboxPage)
- 在"我的"页面右上角添加通知图标(带未读角标)
- 支持查看通知详情、标记已读、全部已读

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 20:45:03 -08:00
hailin 7d9837fc22 refactor(reward): 前端直接从 reward-service 查询奖励数据
移除 reward-service 和 wallet-service 之间的 Kafka 同步机制:
- 屏蔽 reward-service 的 outbox 发布逻辑
- 屏蔽 wallet-service 的 RewardEventConsumerController 订阅

Flutter 前端改为直接调用 reward-service API:
- 新增 RewardService 调用 /rewards/summary
- profile_page 改用 rewardService.getMyRewardSummary()

这样简化了架构,数据从源头获取,避免同步问题。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 00:36:53 -08:00
hailin dfa21c0280 feat(mobile): integrate PlantingService with real API
- Add PlantingService for planting order management
  - createOrder: Create new planting order
  - selectProvinceCity: Select province and city
  - confirmProvinceCity: Confirm province/city selection
  - payOrder: Pay for order
  - getOrder/getMyOrders: Query orders
  - cancelOrder: Cancel unpaid orders
- Register PlantingService in DI container
- Update planting_quantity_page to create order before navigation
- Update planting_location_page to call real API endpoints
- Fix referral-service event-ack.publisher to use KafkaService

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 22:28:36 -08:00
hailin 8335187436 feat(mobile): integrate wallet-service API for profile page rewards
- Add WalletService to fetch wallet/rewards data from backend
- Replace hardcoded earnings data with real API calls
- Add loading/error states for earnings section
- Implement claim rewards functionality with API
- Add comprehensive debug logging for troubleshooting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 20:05:14 -08:00
hailin d0487c4a7e feat(profile): integrate referral and authorization APIs for profile page
- Add Kong routes for identity-service /me, referral-service, and authorization-service
- Create AuthorizationService in Flutter for fetching user authorizations
- Extend ReferralService with getMyReferralInfo() and getDirectReferrals() methods
- Update profile_page.dart to display real team stats from APIs
- Fix authorization-service JWT strategy to accept identity-service token format
- Add decimal.js dependency to authorization-service
- Add prisma migration file for authorization-service

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-09 01:57:39 -08:00
hailin e8e0c6db86 fix(mobile-app): fix avatar and wallet address issues after mnemonic recovery
- Mining page: use accountService to load avatar (consistent with profile page)
- Account recovery: fetch and save wallet addresses after successful recovery
- Account recovery: set isWalletReady=true to skip backup mnemonic page
- Deposit service: read wallet addresses from local storage or fetch from /user/wallet API

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 12:13:39 -08:00
hailin 747e4ae8ef refactor(mpc-system): migrate to party-driven architecture with PartyID-based routing
- Remove Address field from PartyEndpoint (parties connect to router themselves)
- Update K8s Discovery to only manage PartyID and Role labels
- Add Party registration and SessionEvent protobuf definitions
- Implement PartyRegistry and SessionEventBroadcaster domain logic
- Add RegisterParty and SubscribeSessionEvents gRPC handlers
- Prepare infrastructure for party-driven MPC coordination

This is the first phase of migrating from coordinator-driven to party-driven
architecture following international MPC system design patterns.
2025-12-05 08:11:28 -08:00
Developer a966d71fa0 . 2025-11-30 06:44:57 -08:00
Developer 083db83c96 . 2025-11-29 19:22:42 -08:00
hailin 2915c4ccc5 Flutter v0.1 draft ok 2025-11-25 20:09:50 -08:00