hailin
8d97ed2720
fix(wallet-service): convert BigInt to string for JSON serialization in getUnprocessedSettlements
...
The entry.id field is BigInt type from Prisma which cannot be JSON serialized directly.
Convert to string for API response and back to BigInt when storing to database.
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 07:46:46 -08:00
hailin
251fee4f1e
feat(wallet-service): add offline settlement deduction feature
...
Add new functionality for admins to automatically deduct all settled
earnings when creating special deductions with amount=0, marking
each record to prevent duplicate deductions.
- Add OfflineSettlementDeduction model to track deducted records
- Add API endpoints for querying unprocessed settlements and executing batch deduction
- Add mode selection UI in admin-web pending-actions
- Add offline settlement card display in mobile-app special deduction page
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 06:56:39 -08:00
hailin
dfdd8ed65a
feat(pending-actions): add special deduction feature for admin-created user actions
...
实现特殊扣减功能,允许管理员为用户创建扣减待办操作,由用户在移动端确认执行。
## 后端 (wallet-service)
### 领域层
- 新增 `SPECIAL_DEDUCTION` 到 LedgerEntryType 枚举
用于记录特殊扣减的账本流水类型
### 应用层
- 新增 `executeSpecialDeduction` 方法
- 验证用户钱包存在性
- 检查余额是否充足
- 乐观锁控制并发
- 扣减余额并记录账本流水
- 返回操作结果和新余额
### API层
- 新增内部API: POST /api/v1/wallets/special-deduction/execute
供移动端调用执行特殊扣减操作
## 前端 (admin-web)
### 类型定义
- 新增 `SPECIAL_DEDUCTION` 到 ACTION_CODES
- 新增 `SpecialDeductionParams` 接口定义扣减参数
- amount: 扣减金额
- reason: 扣减原因
### 页面
- 更新待办操作管理页面
- 当选择 SPECIAL_DEDUCTION 时显示扣减金额和原因输入框
- 验证扣减金额必须大于0
- 验证扣减原因不能为空
### 样式
- 新增特殊扣减表单区域样式
## 前端 (mobile-app)
### 服务层
- 新增 `executeSpecialDeduction` 方法到 WalletService
- 新增 `SpecialDeductionResult` 结果类
- 新增 `specialDeduction` 到 PendingActionCode 枚举
### 页面
- 新增 `SpecialDeductionPage` 特殊扣减确认页面
- 显示扣减金额和管理员备注
- 显示当前余额和扣减后余额
- 余额不足时禁用确认按钮
- 温馨提示说明操作性质
- 更新 `PendingActionsPage`
- 处理 SPECIAL_DEDUCTION 类型的待办操作
- 从 actionParams 解析 amount 和 reason
- 导航到特殊扣减确认页面
## 工作流程
1. 管理员在 admin-web 创建 SPECIAL_DEDUCTION 待办操作
- 选择目标用户
- 输入扣减金额
- 输入扣减原因
2. 用户在 mobile-app 待办操作列表看到该操作
3. 用户点击后进入特殊扣减确认页面
- 查看扣减详情
- 确认余额充足
- 点击确认执行扣减
4. 后端执行扣减并记录账本流水
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 07:04:46 -08:00
hailin
a609600cd8
feat(fiat-withdrawal): add complete fiat withdrawal system
...
实现完整的法币提现功能,支持银行卡、支付宝、微信三种收款方式。
此功能与现有的区块链划转功能完全独立,互不影响。
## 后端 (wallet-service)
### 数据库
- 新增 `fiat_withdrawal_orders` 表存储法币提现订单
- 与现有 `withdrawal_orders` 表(区块链划转)完全分离
- 添加完整索引支持高效查询
### 领域层
- 新增 `FiatWithdrawalStatus` 枚举(与 WithdrawalStatus 独立)
- 流程: PENDING -> FROZEN -> REVIEWING -> APPROVED -> PAYING -> COMPLETED
- 或 REJECTED / FAILED / CANCELLED
- 新增 `PaymentMethod` 枚举: BANK_CARD / ALIPAY / WECHAT
- 新增 `FiatWithdrawalOrder` 聚合根
- 新增 `IFiatWithdrawalOrderRepository` 仓储接口
- 新增 `FIAT_WITHDRAWAL` 账本流水类型
### 应用层
- 新增 `FiatWithdrawalApplicationService` 处理业务逻辑
- 发送短信验证码
- 申请法币提现(冻结余额)
- 提交审核
- 审核通过/驳回
- 开始打款
- 完成打款
### API层
- 新增 `FiatWithdrawalController` 提供用户端API
- POST /wallet/fiat-withdrawal/send-sms - 发送验证码
- POST /wallet/fiat-withdrawal - 申请提现
- GET /wallet/fiat-withdrawal - 获取提现记录
- 新增内部API供管理端调用
- GET /api/v1/wallets/fiat-withdrawals - 查询订单
- POST /api/v1/wallets/fiat-withdrawals/:orderNo/review - 审核
- POST /api/v1/wallets/fiat-withdrawals/:orderNo/start-payment - 开始打款
- POST /api/v1/wallets/fiat-withdrawals/:orderNo/complete-payment - 完成打款
## 前端 (admin-web)
- 新增法币提现审核管理页面 `/withdrawals`
- 支持按状态分 Tab 查看订单
- 支持审核通过/驳回
- 支持打款操作
- 支持查看订单详情
## 前端 (mobile-app)
- 新增 `WithdrawFiatPage` 法币提现页面
- 支持选择银行卡/支付宝/微信
- 输入收款账户信息
- 新增 `WithdrawFiatConfirmPage` 确认页面
- 短信验证码验证
- 密码验证
- 在 `WalletService` 中添加法币提现相关方法和模型
## 重要说明
此功能与现有的区块链划转功能 (withdraw_usdt_page.dart) 完全独立:
- 独立的数据库表
- 独立的聚合根
- 独立的状态枚举
- 独立的API端点
- 独立的前端页面
原有的区块链划转功能保持不变,不受任何影响。
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 06:39:11 -08:00
hailin
d614d18e97
Revert "feat(withdrawal): implement fiat withdrawal with bank/alipay/wechat"
...
This reverts commit 288d894746 .
2026-01-03 05:44:43 -08:00
hailin
288d894746
feat(withdrawal): implement fiat withdrawal with bank/alipay/wechat
...
Add complete fiat withdrawal feature that allows users to withdraw
green credits (绿积分) to their bank card, Alipay, or WeChat account
with 1:1 CNY conversion. Key changes:
Backend (wallet-service):
- Update Prisma schema with fiat withdrawal fields (paymentMethod,
bankName, bankCardNo, cardHolderName, alipay*, wechat*, review fields)
- Rewrite withdrawal status enum for fiat flow: PENDING → FROZEN →
REVIEWING → APPROVED → PAYING → COMPLETED (or REJECTED/FAILED)
- Add PaymentMethod enum: BANK_CARD, ALIPAY, WECHAT
- Update WithdrawalOrderAggregate with new fiat withdrawal methods
- Add review/payment workflow methods in WalletApplicationService
- Add internal API endpoints for admin withdrawal management
- Remove blockchain withdrawal event handler (no longer needed)
Frontend (admin-web):
- Add withdrawal review management page at /withdrawals
- Add tabs for reviewing/approved/paying order states
- Add withdrawal service and React Query hooks
- Add types for withdrawal orders and payment methods
- Add sidebar menu item for withdrawal review
Frontend (mobile-app):
- Add withdrawFiat() method to WalletService
- Add PaymentMethod enum with BANK_CARD/ALIPAY/WECHAT
- Create new WithdrawFiatPage for fiat withdrawal input
- Create WithdrawFiatConfirmPage with SMS + password verification
- Add routes for /withdraw/fiat and /withdraw/fiat/confirm
- Keep existing withdraw/usdt (划转) pages unchanged
Note: The existing withdraw_usdt_page.dart is for point-to-point
transfer (划转), which is a different feature from fiat withdrawal.
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 05:28:05 -08:00
hailin
036696878f
feat(settlement): implement settle-to-balance with detailed source tracking
...
Add complete settlement-to-balance feature that transfers settleable
earnings directly to wallet USDT balance (no currency swap). Key changes:
Backend (wallet-service):
- Add SettleToBalanceCommand for settlement operations
- Add settleToBalance method to WalletAccountAggregate
- Add settleToBalance application service with ledger recording
- Add internal API endpoint POST /api/v1/wallets/settle-to-balance
Backend (reward-service):
- Add settleToBalance client method for wallet-service communication
- Add settleRewardsToBalance application service method
- Add user-facing API endpoint POST /rewards/settle-to-balance
- Build detailed settlement memo with source user tracking per reward
Frontend (mobile-app):
- Add SettleToBalanceResult model class
- Add settleToBalance() method to RewardService
- Update pending_actions_page to handle SETTLE_REWARDS action
- Add completion detection via settleableUsdt balance check
Settlement memo now includes detailed breakdown by right type with
source user accountSequence for each reward entry, e.g.:
结算 1000.00 绿积分到钱包余额
涉及 5 笔奖励
- SHARE_RIGHT: 500.00 绿积分
来自 D2512120001: 288.00 绿积分
来自 D2512120002: 212.00 绿积分
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 04:29:38 -08:00
hailin
0e85c2fd23
fix(wallet-service): 修复社区权益根据 targetId 正确分配
...
问题:社区权益(COMMUNITY_RIGHT)无论 targetId 是什么,都强制分配到
总部账户 S0000000001,导致社区授权人无法在流水明细中看到社区权益。
修复:
- 将 allocateToHeadquartersCommunity 方法重命名为 allocateCommunityRight
- 根据 targetId 判断分配目标:
- D 开头(用户账户): 分配到社区授权人账户
- S 开头或 '1'(系统账户): 分配到总部社区账户
- 更新流水备注以区分用户分配和总部分配
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 07:20:22 -08:00
hailin
09cc696efa
Revert "fix(wallet-service): 社区权益按 targetId 分配到正确账户"
...
This reverts commit 43a0e5f5e1 .
2025-12-26 04:52:01 -08:00
hailin
43a0e5f5e1
fix(wallet-service): 社区权益按 targetId 分配到正确账户
...
修复社区权益分配逻辑:
- 之前所有 COMMUNITY_RIGHT 都直接进入总部账户 S0000000001
- 现在根据 targetId 判断:
- targetId 为 '1' 或 'S0000000001' → 进入总部社区账户
- targetId 为用户账户(D开头)→ 进入该用户可结算余额
这样当用户获取社区授权且伞下认种达到10棵后,
社区权益会正确分配到该用户账户,而不是总部。
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 04:49:10 -08:00
hailin
3f3309e62f
debug: 添加流水明细 allocationType 调试日志
...
- 后端 wallet-service: getMyLedger 打印 payloadJson 和 allocationType
- 前端 wallet_service: 打印原始和解析后的流水数据
- 前端 ledger_detail_page: 打印加载的流水数据详情
用于排查权益类型(社区、省市团队/区域)不显示的问题
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 04:35:46 -08:00
hailin
78d7e0e637
feat(mobile-app): 流水明细支持显示权益类型和详情
...
- 后端 wallet-service: getMyLedger API 返回 allocationType 字段
- 前端流水明细: 显示权益类型名称(分享权益、省/市区域权益等)
- 新增权益详情弹窗,点击权益记录可查看详细信息
- 兑换页面: "RMB/CNY提现" 改为 "提现"
- 我的团队: "暂无下级成员" 改为 "暂无团队成员"
- 自助申请授权: 隐藏团队链占用区域提示
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 03:57:35 -08:00
hailin
f7e2f7f6f2
fix(wallet-service): 添加 WalletAccount 类型导入
2025-12-26 02:23:49 -08:00
hailin
726e3d0fcf
fix(wallet-service): 修复区域权益分配时 targetId 为用户账户导致的 BigInt 转换错误
...
问题:allocateToRegionAccount 假设 targetId 总是纯数字格式的区域账户,
但实际上当权益分配给授权市/省公司用户时,targetId 是 D 开头的用户账户格式。
修复:判断 targetId 格式
- D 开头:用户账户,直接 findByAccountSequence
- 纯数字:区域账户,使用 getOrCreate
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 02:20:05 -08:00
hailin
dbeef0a80b
chore(wallet-service): 移除已执行的OTP修复脚本
2025-12-25 20:55:08 -08:00
hailin
c2ff11bd6d
fix(wallet-service): 添加一次性修复脚本 D25122600004->D25122600006 转账
...
- 修复因并发修改导致的冻结余额不足问题
- 自动完成内部转账、记录流水、更新订单状态
- 幂等执行,可安全重启
- 部署成功后请删除 otp/ 目录和相关引用
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 20:50:39 -08:00
hailin
305bdf63af
fix(wallet-service): 添加钱包乐观锁防止并发修改
...
- WalletAccount aggregate 添加 version 字段
- WalletAccountRepositoryImpl 使用 updateMany + version 检查实现乐观锁
- requestWithdrawal 添加重试机制处理乐观锁冲突
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 20:44:55 -08:00
hailin
f9e2d8483c
feat(wallet-service): allocateFunds 添加幂等性检查
...
防止重复分配奖励,通过检查流水表中的 orderId + accountSequence + allocationType 组合
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 09:05:44 -08:00
hailin
4e670ad774
fix(wallet): 隐藏临时流水记录并统一充值名称显示
...
- 在流水明细查询中排除冻结/解冻等临时记录
- 将"充值 (KAVA)"统一改为"充值"
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 21:00:31 -08:00
hailin
336306d6c0
fix(wallet-service): 修复账本统计双重计算问题
...
排除临时性流水类型(冻结/解冻)的收支统计:
- PLANT_FREEZE(认种冻结)
- PLANT_UNFREEZE(认种解冻)
- FREEZE(通用冻结)
- UNFREEZE(通用解冻)
问题原因:认种流程产生两笔流水(冻结+支付),导致一笔支出被统计两次
修复后:只统计最终的实际支付,冻结/解冻作为中间状态不计入收支
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 20:38:27 -08:00
hailin
f9222fed50
feat: 实现ID-to-ID内部转账功能
...
- 添加内部转账标识字段:is_internal_transfer, to_account_sequence, to_user_id
- 提现时自动检测目标地址是否为内部用户
- 内部转账确认后创建双向流水:发送方TRANSFER_OUT,接收方TRANSFER_IN
- 新增identity-service钱包地址查询API支持内部用户识别
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 22:22:47 -08:00
hailin
3f5203c142
feat: 已认种用户分享权益直接进入可结算状态
...
- 新增 hasPlanted 字段标记用户是否已认种
- 已认种用户的分享权益直接进入可结算余额,无需待领取
- 修正前端权益考核数值(576/288/252/144/108 绿积分)
- 修复账本明细筛选栏选择后滚动位置重置问题
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 21:10:49 -08:00
hailin
cb0f10af34
feat: 多项业务功能增强
...
- 动态提取手续费配置:支持固定/百分比两种费率类型,默认2绿积分/笔
- 找回密码功能:新增手机号+短信验证码重置密码流程
- 授权申请优化:自助申请时验证团队链授权状态
- UI文案调整:登录账号、监控页待开启等
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 19:00:02 -08:00
hailin
13df91a55e
fix(wallet-service): 修复 resolve-address API 路径
...
identity-service 的 resolve-address 接口在 UserAccountController 下,
需要添加 /user 前缀:/users/resolve-address -> /user/users/resolve-address
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 04:17:11 -08:00
hailin
0374e2a55c
fix(wallet-service): 修复 identity-client 响应数据解析
...
identity-service 使用响应拦截器将所有响应包装在 { success, data } 结构中。
修复所有方法的响应解析,从 response.data?.valid 改为 response.data?.data?.valid。
影响方法:
- verifyTotp
- isTotpEnabled
- verifyWithdrawSmsCode
- verifyPassword
- resolveAccountSequenceToAddress
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 04:12:48 -08:00
hailin
9ae1c1cbdb
fix(wallet-service): 添加验证码验证调试日志并修复布尔值比较
...
- 添加完整响应数据日志以便调试
- 使用严格比较 === true 代替 ?? false
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 04:06:40 -08:00
hailin
ac4bd46c13
fix(wallet-service): 添加 /api/v1 前缀到 identity-client 的 baseURL
...
identity-service 有全局前缀 api/v1,所以调用路径应该是:
- /api/v1/user/sms/send-withdraw-code
- /api/v1/user/sms/verify-withdraw-code
- /api/v1/user/verify-password
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 03:51:49 -08:00
hailin
9bc7bb1200
fix(withdraw): 修复提取功能短信验证和手续费计算
...
- 修复 wallet-service 调用 identity-service 的 API 路径(添加 /user 前缀)
- 修复 identity-client 默认端口从 3001 改为 3000
- 添加 docker-compose 中 IDENTITY_SERVICE_URL 环境变量配置
- 手续费改为按 0.1% 费率动态计算(前后端统一)
- 最小提取金额从 10 改为 100
- 文案修改:Kava EVM 网络 → Kava安全网络,接收地址 → 接收账号
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 03:14:22 -08:00
hailin
5b2d255506
feat(auth): 增强提现安全验证
...
- 集成阿里云短信服务 (dysmsapi20170525)
- 提现需同时验证短信验证码和登录密码
- identity-service 添加 /verify-password API
- wallet-service 调用双重验证
- 移动端提现确认页添加密码输入
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 03:05:53 -08:00
hailin
30db6b4238
fix(ledger): 优化账本明细流水类型显示
...
前端:
- 删除 '充值 (BSC)' 筛选选项
- '充值 (KAVA)' → '充值绿积分'
- 添加 '提取' 筛选选项 (REWARD_SETTLED)
后端:
- '充值 (KAVA)' → '充值绿积分'
- '奖励结算' → '提取'
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 08:44:34 -08:00
hailin
15e2bfe236
feat(trading): 添加账本明细页面,含统计图表和流水筛选
...
后端新增:
- GET /wallet/ledger/statistics 流水统计API(按类型汇总)
- GET /wallet/ledger/trend 流水趋势API(按日期统计)
- LedgerStatisticsResponseDTO, LedgerTrendResponseDTO 等DTO
前端新增:
- 账本明细页面(统计概览Tab + 流水明细Tab)
- 收支概览卡片、趋势柱状图、按类型统计
- 流水列表支持分页加载和类型筛选
- 兑换页面右上角添加账本明细入口
授权服务:
- 5种授权方法添加认种前置检查(需至少认种1棵树才能授权)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 07:41:07 -08:00
hailin
257236480f
feat(wallet/profile): 添加可结算和已过期奖励逐笔显示功能
...
后端:
- wallet-service 新增 getSettleableRewards() 和 getExpiredRewards() 方法
- 新增 GET /wallet/settleable-rewards 和 GET /wallet/expired-rewards API
前端:
- reward_service.dart 新增 SettleableRewardItem、ExpiredRewardItem 数据模型
- profile_page.dart 可结算区域和已过期区域支持逐笔明细显示
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 07:20:44 -08:00
hailin
c1fe54a8d4
feat: 暂时禁用 BSC 链,添加 Kafka 企业级重试配置
...
- blockchain-service: getSupportedChains() 只返回 KAVA
- 所有 Kafka consumer 添加企业级重试配置(15次重试,指数退避)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 22:33:34 -08:00
hailin
be7ec87f05
feat(wallet): 增强认种流程可靠性 - 添加事务保护和乐观锁
...
## 问题背景
认种流程(冻结→确认扣款→解冻)存在以下可靠性问题:
1. 余额检查与冻结操作非原子性,存在并发竞态条件
2. 钱包更新与流水记录分开执行,可能导致数据不一致
3. 缺少乐观锁机制,并发修改时可能出现余额错误
4. Kafka consumer 错误被吞掉,消费失败无法重试
## 修复内容
### wallet-application.service.ts
1. **freezeForPlanting (冻结资金)**
- 添加 `prisma.$transaction` 事务保护
- 添加乐观锁 (version 字段检查)
- 添加重试机制 (最多 3 次,指数退避)
- 幂等性检查移入事务内,避免竞态
2. **confirmPlantingDeduction (确认扣款)**
- 添加事务保护,确保扣款与流水原子性
- 添加乐观锁防止并发修改
- 添加重试机制
3. **unfreezeForPlanting (解冻资金)**
- 添加事务保护,确保解冻与流水原子性
- 添加乐观锁防止并发修改
- 添加重试机制
### planting-event-consumer.service.ts
- 添加 `throw error` 重新抛出错误
- 确保消费失败时 Kafka 能感知并触发重试
## 乐观锁实现
```typescript
const updateResult = await tx.walletAccount.updateMany({
where: {
id: walletRecord.id,
version: currentVersion, // 版本检查
},
data: {
usdtAvailable: newAvailable,
version: currentVersion + 1, // 版本递增
},
});
if (updateResult.count === 0) {
throw new OptimisticLockError('版本冲突');
}
```
## 测试验证
- wallet-service 构建成功
- 服务重启正常,所有 handler 注册成功
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 19:56:49 -08:00
hailin
a01284678d
feat(wallet/mpc): 增强提现和充值流程可靠性
...
## 主要改进
### MPC 签名系统 (mpc-system)
- 添加签名缓存机制,避免重复签名请求
- 修复 yParity 恢复逻辑,确保签名格式正确
- 优化签名完成报告流程
### 区块链服务 (blockchain-service)
- EIP-1559 降级为 Legacy 交易(KAVA 测试网兼容)
- 修复 gas 估算逻辑
### 钱包服务 (wallet-service)
- 添加乐观锁机制 (version 字段) 防止并发修改
- 提现确认流程添加事务保护 + 乐观锁
- 提现失败时正确解冻 amount + fee
- 充值流程添加事务保护 + 乐观锁
- Kafka consumer 添加错误重抛,触发重试机制
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 19:47:20 -08:00
hailin
28c44d7219
fix(wallet): 提现失败解冻时优先使用 accountSequence 查找钱包
...
问题背景:
- 原实现使用 userId 查找钱包进行解冻操作
- userId 来自外部 identity-service,存在变化风险
- 如果 userId 发生变化,可能导致解冻到错误的钱包
解决方案:
- 优先使用 accountSequence 查找钱包(wallet-service 内部主键,稳定可靠)
- 保留 userId 作为兜底查找方式,确保向后兼容
- 增加钱包找不到时的详细错误日志
改动点:
- withdrawal-status.handler.ts: handleWithdrawalFailed() 方法
- 与认种(planting)的钱包查找逻辑保持一致
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 07:37:36 -08:00
hailin
579e8c241e
fix(backend): 修复构建错误并添加 TOTP 数据库迁移
...
修复内容:
- identity-service: 添加 CurrentUserPayload 接口定义
- identity-service: 添加 user_totp 表的数据库迁移文件
- wallet-service: 安装 axios 依赖
- wallet-service: 修复 withdrawal-status.handler.ts 中的类型错误
- userId.toString() → userId.value (BigInt 类型)
- unfreezeUsdt() → unfreeze() (正确的方法名)
- amount.asNumber → amount.value (Money 值对象属性)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 05:29:29 -08:00
hailin
b01277ab7d
feat(withdraw): 实现完整的提取功能 - TOTP验证和KAVA转账
...
功能实现:
- identity-service: 添加TOTP二次验证功能
- 新增 UserTotp 数据模型
- 实现 TotpService (生成/验证/启用/禁用)
- 添加 /totp/* API端点
- wallet-service: 提取API添加TOTP验证
- withdrawal.dto 添加可选 totpCode 字段
- 添加 IdentityClientService 调用identity-service验证TOTP
- 添加 WithdrawalStatusHandler 处理区块链确认/失败事件
- blockchain-service: 实现真实KAVA ERC20转账
- 新增 Erc20TransferService (热钱包USDT转账)
- 更新 withdrawal-requested.handler 执行真实转账
- 发布确认/失败事件回wallet-service
- 前端: 对接真实提取API
- withdraw_confirm_page 调用 walletService.withdrawUsdt
环境变量配置:
- TOTP_ENCRYPTION_KEY (identity-service)
- IDENTITY_SERVICE_URL (wallet-service)
- HOT_WALLET_PRIVATE_KEY (blockchain-service)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 05:16:42 -08:00
hailin
846915badc
fix(wallet-service): 使用事务确保 settleUserPendingRewards 原子性
...
- 将 pending_rewards 状态更新和 wallet_accounts 余额更新包装在 Prisma $transaction 中
- 修复 Bug 4: pending_rewards 被标记为 SETTLED 但 settleable_usdt 未更新的问题
- 添加 PrismaService 依赖注入
- 同时减少 pendingUsdt/pendingHashpower,增加 settleableUsdt/settleableHashpower
- 记录 REWARD_TO_SETTLEABLE 类型的流水
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 06:58:07 -08:00
hailin
28864e6160
fix(wallet-service): 修复待领取奖励显示和结算触发问题
...
Bug 1: allocateToUserWallet 同步更新 wallet_accounts.pending_usdt
- 写入 pending_rewards 表时同步调用 wallet.addPendingReward()
- 修复前端待领取金额显示为 0 的问题
Bug 2: Kafka 事件类型匹配兼容 planting-service 格式
- 支持 eventName 字段解析 (planting-service 使用)
- 支持 data 字段解析 (planting-service 使用)
- 新增 PlantingOrderPaid 事件类型支持
- 修复用户认种后待领取无法转换为可结算的问题
其他: 定时任务频率改为每分钟一次 (测试用途)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 05:51:28 -08:00
hailin
e4389a5733
fix(wallet-service): 优化资金分配逻辑 - 区分直接到账和待领取
...
- SHARE_RIGHT (分享权益): 写入 pending_rewards 表,24小时待领取
- PROVINCE_TEAM_RIGHT/PROVINCE_AREA_RIGHT/CITY_TEAM_RIGHT/CITY_AREA_RIGHT: 直接到账
- COMMUNITY_RIGHT (社区权益): 进入总部社区账户 S0000000001,直接到账
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 04:51:34 -08:00
hailin
737fc3bb3c
fix(wallet-service): allocateToUserWallet 改用 pending_rewards 表
...
- 移除 wallet.addPendingReward() 调用(旧方案,更新 wallet_accounts.pending_usdt)
- 改用 PendingReward.create() + pendingRewardRepo.save() 写入 pending_rewards 表
- 支持 7+省代码(省团队)和 6+市代码(市团队)账户格式
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 03:53:23 -08:00
hailin
8f81c46d75
feat: 省市团队账户及待领取奖励逐笔追踪
...
1. authorization-service:
- 省团队权益分配改用系统省团队账户 (7+provinceCode)
- 市团队权益分配改用系统市团队账户 (6+cityCode)
- 无推荐链时不再进总部,而是进对应团队账户
2. wallet-service:
- 新增 pending_rewards 表支持逐笔追踪待领取奖励
- ensureRegionAccounts 同时创建区域账户和团队账户
- 新增 getPendingRewards API 查询待领取列表
- 新增 settleUserPendingRewards 用户认种后结算
- 新增 processExpiredRewards 定时处理过期奖励
- PlantingCreatedHandler 监听认种事件触发结算
- ExpiredRewardsScheduler 每小时处理过期奖励
账户格式:
- 省区域: 9+provinceCode (如 9440000)
- 市区域: 8+cityCode (如 8440100)
- 省团队: 7+provinceCode (如 7440000)
- 市团队: 6+cityCode (如 6440100)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 03:32:47 -08:00
hailin
4d3290f029
fix(wallet-service): 修复系统账户资金分配功能
...
问题:
- 认种订单支付后,系统账户(成本费、运营费、总部社区、RWA底池)余额始终为0
- reward-service 正确计算分配,但 wallet-service 未实际执行系统账户的资金转移
根本原因:
1. allocateToSystemAccount() 方法只打印日志,未执行任何数据库操作(遗留的 TODO)
2. UserId 值对象不允许负数,而系统账户 user_id 为负数(-1 到 -4)
修复内容:
1. wallet-application.service.ts - allocateToSystemAccount()
- 实现完整的系统账户资金分配逻辑
- 通过 findByAccountSequence() 获取系统账户
- 调用 addAvailableBalance() 直接增加可用余额
- 创建 SYSTEM_ALLOCATION 类型的流水记录
2. wallet-account.aggregate.ts
- 新增 addAvailableBalance(amount: Money) 方法
- 用于系统账户直接增加余额(无需待领取/过期机制)
3. ledger-entry-type.enum.ts
- 新增 SYSTEM_ALLOCATION 枚举值,用于系统账户分配流水
4. user-id.vo.ts
- 移除负数校验,允许系统账户使用负数 user_id
- 系统账户约定:-1(总部社区)、-2(成本费)、-3(运营费)、-4(RWA底池)
验证结果(认种1棵树=2199 USDT):
- S0000000001 总部社区: 9 USDT ✓
- S0000000002 成本费账户: 400 USDT ✓
- S0000000003 运营费账户: 300 USDT ✓
- S0000000004 RWA底池: 800 USDT ✓
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 02:01:48 -08:00
hailin
98d8bee20d
fix: 统一推荐码生成逻辑 - 由 identity-service 单点生成
...
重要变更:
- identity-service 生成用户推荐码,通过 Kafka 事件传递给 referral-service
- referral-service 不再自己生成推荐码,直接使用事件中的推荐码
- 修复两个服务推荐码不一致的问题
涉及服务:
- identity-service: 事件 payload 添加 referralCode 字段
- referral-service: 接收并存储 identity-service 生成的推荐码
- wallet-service: 添加区域账户动态创建接口
- planting-service: 调用区域账户创建接口
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 01:14:56 -08:00
hailin
ebbf2d971a
feat: 跨服务使用 accountSequence 查询推荐链 + 系统账户动态创建
...
1. reward-service 使用 accountSequence 查询推荐链
- event-consumer.controller.ts: 优先使用 accountSequence 作为用户标识
- reward-calculation.service.ts: 使用 accountSequence 查询推荐关系
- referral-service.client.ts: 参数从 userId 改为 accountSequence
2. referral-service 支持 accountSequence 格式的推荐链查询
- referral.controller.ts: /chain/:identifier 同时支持 userId 和 accountSequence
3. wallet-service 系统账户动态创建
- wallet-application.service.ts: allocateToUserWallet 使用 getOrCreate
- 支持省区域(9+code)和市区域(8+code)账户自动创建
- 新增 migration seed: 4个固定系统账户 (S0000000001-S0000000004)
4. planting-service 事件增强
- 事件中添加 accountSequence 字段用于跨服务关联
系统账户格式:
- S0000000001: 总部社区 (基础费9U + 兜底权益)
- S0000000002: 成本费账户 (400U)
- S0000000003: 运营费账户 (300U)
- S0000000004: RWAD底池账户 (800U)
- 9+provinceCode: 省区域系统账户 (动态创建)
- 8+cityCode: 市区域系统账户 (动态创建)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 23:22:01 -08:00
hailin
d20ff9e9b5
fix: 修复 wallet-service 支持 accountSequence 格式及订单状态机
...
1. wallet-service/internal-wallet.controller.ts:
- getBalance: 支持 accountSequence (D开头) 和 userId (纯数字) 两种格式
2. wallet-service/wallet-application.service.ts:
- freezeForPlanting: 修复 BigInt 转换错误,优先按 accountSequence 查找钱包
- confirmPlantingDeduction: 同上
- unfreezeForPlanting: 同上
- getMyWallet: 支持 userId='0' 的情况(仅通过 accountSequence 查询)
3. planting-service/planting-order.aggregate.ts:
- schedulePoolInjection: 状态检查从 FUND_ALLOCATED 改为 PAID
- 原因: 资金分配已移至 reward-service 异步处理
修复问题: "Cannot convert D25121300006 to a BigInt"
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 22:35:18 -08:00
hailin
96f031da35
fix(wallet-service): 修复 allocateToUserWallet 使用 accountSequence 查找钱包
...
- targetId 现在是 accountSequence (如 D2512120001),不再是 userId
- 移除无效的 BigInt(targetId) 转换
- 从 wallet 对象获取 userId 用于流水记录和缓存失效
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 19:15:47 -08:00
hailin
4be9c1fb82
refactor!: 重构账户序列号格式 (BREAKING CHANGE)
...
将 accountSequence 从数字类型改为字符串类型,新格式为:
- 普通用户: D + YYMMDD + 5位序号 (例: D2512120001)
- 系统账户: S + 10位序号 (例: S0000000001)
主要变更:
- identity-service: AccountSequence 值对象改为字符串类型
- identity-service: 序列号生成器改为按日期重置计数
- 所有服务: Prisma schema 字段类型从 BigInt/Int 改为 String
- 所有服务: DTO、Command、Event 中的类型定义更新
- Flutter 前端: 相关数据模型类型更新
涉及服务:
- identity-service (核心变更)
- referral-service
- authorization-service
- wallet-service
- reward-service
- blockchain-service
- backup-service
- planting-service
- mpc-service
- admin-service
- mobile-app (Flutter)
注意: 此为破坏性变更,需要清空数据库并重新运行 migration
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 09:11:18 -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