Commit Graph

1061 Commits

Author SHA1 Message Date
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 1e15b820b4 fix(planting-service): 合同PDF显示完整手机号和身份证号
- 移除 PDF 生成时对手机号和身份证号的脱敏处理
- 表单字段模式和坐标定位模式都直接使用原始值
- 删除 maskIdCard() 和 maskPhone() 脱敏方法
- 签订合同需要显示完整信息

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 18:55:55 -08:00
hailin 285465827d fix(blockchain-service): 添加 --accept-data-loss 参数
prisma db push 需要此参数来接受精度变更

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 18:28:23 -08:00
hailin 1d817a5be2 fix(blockchain-service): 扩大充值金额字段精度
- amount 字段从 Decimal(36,18) 改为 Decimal(78,0) 支持超大金额
- amountFormatted 字段从 Decimal(20,8) 改为 Decimal(36,8)

修复问题:100亿 USDT 充值导致 numeric field overflow 错误

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 18:19:48 -08:00
hailin e95ac15605 fix(reward-service): 添加奖励分配幂等性检查
- distributeRewards 方法添加幂等性检查,防止同一订单重复分配奖励
- distributeRewardsForExpiredContract 方法同样添加幂等性检查
- 通过 findBySourceOrderNo 检查订单是否已分配过奖励

修复问题:recovery job 重复触发导致同一订单奖励被多次分配

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 10:42:01 -08:00
hailin 68a071cfaa fix(identity-service): 暂时恢复三要素身份验证
二要素 API (Id2MetaStandardVerify) 返回 440 无权限调用错误
暂时恢复使用三要素验证,保留二要素代码待开通权限后使用

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 10:12:20 -08:00
hailin 4ec4df14b5 feat(identity-service): KYC 改用二要素验证
- 默认使用阿里云 Id2MetaStandardVerify API(姓名+身份证号)
- 保留三要素验证方法 verifyIdCardThreeFactor 作为备用
- 二要素验证始终调用真实 API,不使用 mock
- 兼容 BizCode 数字和字符串类型

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 09:46:17 -08:00
hailin 7a1e789f4d fix(contract): 合同签署页面和模板优化
1. 合同模板:身份证号和联系方式显示完整信息,不再使用星号掩码
2. 签署页面:checkbox 默认不选中,用户阅读到底部后才可点击确认

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 09:31:39 -08:00
hailin fba91ec256 fix(referral-service): 添加 WalletServiceClient 初始化日志
方便排查 WALLET_SERVICE_URL 环境变量是否正确加载

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 09:22:47 -08:00
hailin 63ac0debf3 feat(planting-service): 添加合同签署后事件恢复定时任务
每2~5分钟随机间隔扫描已签署超过2分钟的合同
重新发布 contract.signed 事件,确保扣款确认和奖励分配完成

幂等性已由 wallet-service 保证

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 09:08:47 -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 bf7f4af88d fix(docker-compose): 添加 referral-service 的 WALLET_SERVICE_URL 配置
referral-service 需要调用 wallet-service 确认扣款,
但缺少环境变量配置导致使用默认 localhost:3002 无法访问

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 08:59:53 -08:00
hailin 484cc99636 fix(planting-service): 修复 identity-service 响应解析
identity-service 响应被 TransformInterceptor 包装为 { success, data }
需要从 response.data.data 获取实际用户信息

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 08:47:43 -08:00
hailin 48f4ed60a6 fix(planting-service): 修复 identity-service API 调用路径
添加 /api/v1 前缀以匹配 identity-service 的全局路由配置

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 08:39:45 -08:00
hailin c907f44851 feat(planting-service): 订单表添加 accountSequence,实现合同恢复任务
变更内容:
1. 订单表添加 account_sequence 字段
   - 创建订单时保存用户的 accountSequence
   - 避免跨服务调用 identity-service 获取用户信息

2. 新增 ContractSigningRecoveryJob 定时任务
   - 每 3 分钟扫描已支付但未创建合同的订单
   - 使用订单中的 accountSequence 获取 KYC 信息
   - 为已通过 KYC 的用户补创建合同签署任务

3. 修改 PlantingOrder 聚合根
   - create() 方法增加 accountSequence 参数
   - markAsPaid() 不再需要 accountSequence 参数
   - 事件中携带 accountSequence

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 08:19:36 -08:00
hailin 1c3ddb0f9b fix: 修复internal用户详情接口路由和KYC状态检查
问题1: /internal/users/:accountSequence/detail 返回404
原因: 路由顺序问题,通配路由在前拦截了请求
修复: 将 /detail 路由移到通配路由之前

问题2: planting-service 只接受 kycStatus='VERIFIED'
原因: identity-service 使用 REAL_NAME_VERIFIED 等状态
修复: 接受所有有效的KYC状态

同时:
- identity-service 返回 idCardNumber 用于合同签署
- planting-service 使用 idCardNumber

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 07:51:11 -08:00
hailin b3014744ab fix(identity-service): KYC成功后发布KYCVerified事件
之前实名认证成功后只更新数据库,没有发布事件,
导致planting-service无法收到通知来创建合同签署任务。

修改内容:
- 注入 EventPublisherService
- 查询时增加 accountSequence 字段
- 认证成功后发布 KYCVerifiedEvent 到 identity.KYCVerified topic

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 07:38:20 -08:00
hailin fd04de8696 fix(mobile-app): 增加合同签署页面重试时间
KYC 成功后后端通过 Kafka 异步创建合同任务,可能需要较长时间。
将重试从 5 次/500ms 改为 15 次/2s,总等待时间最多 30 秒。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 07:33:04 -08:00
hailin 6b72831cd9 feat(mobile-app): KYC成功后自动跳转合同签署页面
从认种流程进入KYC时传递orderNo参数:
- 认种页面 -> KYC Entry -> KYC ID 传递 orderNo
- KYC成功后如果有orderNo则跳转合同签署
- 直接进入KYC(无orderNo)则正常返回

修改文件:
- app_router.dart: KYC路由支持orderNo参数
- kyc_entry_page.dart: 接收并传递orderNo
- kyc_id_page.dart: 成功后判断是否跳转合同签署
- planting_location_page.dart: 跳转KYC时传递orderNo

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 07:07:43 -08:00
hailin 8163804f23 fix(contract-signing): 修复合同签署流程的持仓更新时机
问题:支付后直接更新持仓和开启挖矿,导致款还在冻结中树就种下去了

修复:
- planting-application.service: 支付时不再更新持仓和开启挖矿
- contract-signing.service: signContract 在事务里同时完成合同+持仓+挖矿
- contract-signing.service: handleExpiredTasks 超时也更新持仓+挖矿(钱扣总部)
- KYCVerifiedEvent 添加 accountSequence 字段
- kyc-verified-event.consumer 直接用事件里的 accountSequence

流程变为:支付冻结 → 签署合同 → [事务: 合同+持仓+挖矿] → 发事件

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 06:50:03 -08:00
hailin 2e0df30473 fix(migration): 移除 DO $$ 块,Prisma 不支持 PL/pgSQL
Prisma migrate deploy 只支持简单 SQL 语句

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 05:55:42 -08:00
hailin 7ce71ad27b fix(planting-service): 移除 Dockerfile 中的 db push 回退逻辑
db push 不使用迁移文件,会导致添加必填列时失败

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 05:47:46 -08:00
hailin 500e4381a6 fix(migration): 使迁移脚本幂等以支持重试
迁移脚本添加 IF NOT EXISTS 检查,避免重复执行时失败

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 05:39:38 -08:00
hailin 929ae335c5 feat(contract): 增强合同生成功能
- 添加 IdentityServiceClient 从 identity-service 获取用户 KYC 信息
- 只允许已完成实名认证的用户创建合同
- 添加 KycVerifiedEventConsumer 监听 KYC 完成事件
- 用户完成 KYC 后自动为其之前已支付的订单补创建合同
- PDF 生成器支持 AcroForm 表单字段填充(更可靠)
- 保留坐标定位方式作为后备方案
- 更新 PDF 模板为带表单字段版本

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 05:35:40 -08:00
hailin 0e93d2a343 feat(contract): 使用合同编号代替订单号
合同编号格式: accountSequence-yyyyMMddHHmm
例如: 10001-202512251003

修改内容:
- 数据库: 添加 contract_no 字段
- 后端: 聚合根、Repository、Service、PDF生成器支持 contractNo
- 前端: 显示合同编号代替订单号

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 04:58:39 -08:00
hailin 9cf1bbbbd3 fix(mobile-app): 合同签署页面添加重试机制解决竞态问题
前端在支付完成后立即请求合同签署任务,但后端 Kafka 事件可能还未完成
任务创建。添加最多5次重试,使用指数退避策略(500ms * attempt)。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 04:01:25 -08:00
hailin a7206eef2e fix(planting-service): 修复 BigInt userId 比较问题
- 使用 toString() 比较 BigInt 避免类型不匹配
- 添加调试日志帮助排查问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:59:27 -08:00
hailin 82ca233d54 fix(mobile-app): 签署成功后跳转到"我的"页面
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:55:23 -08:00
hailin 36e4e875bf fix(mobile-app): 修复签署成功后导航报错问题
- 签署成功后检查 canPop() 再决定返回方式
- 如果没有上一页则跳转到首页

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:54:18 -08:00
hailin 2d9e1b2d03 fix(planting-service): 修复合同签署任务创建的并发问题
- 将 upsert 改为 create + 重试机制
- 处理 P2002 唯一约束冲突时使用指数退避重试
- 确保并发创建时能正确返回已存在的记录

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:50:19 -08:00
hailin 2607907bad fix(mobile-app): 修复合同签署页面问题
- 修复 markScrollComplete/acknowledgeContract API 响应处理
  (后端返回 success:true 但无 data 时重新获取任务详情)
- 将合同签署页面的 USDT 改成绿积分

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:44:39 -08:00
hailin c657fb5a19 feat(planting-service): 实现合同签名和PDF云存储功能
- 添加 MinIO 存储服务,支持上传签名图片和已签署 PDF
- 添加 signedPdfUrl 字段到数据库模型
- 修改签署流程:生成 PDF、嵌入签名、上传到云存储
- 修复前端签署 API 响应处理

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:35:15 -08:00
hailin a2f021fe94 fix(mobile-app): 修复签署合同请求字段名与后端不匹配
- signatureImage → signatureBase64
- 添加 signatureHash 字段
- 将 deviceInfo 包装成对象格式 {deviceId, platform}
- 将 latitude/longitude 包装成 location 对象

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:20:27 -08:00
hailin accc043ff0 feat(mobile-app): 添加合同签署 API 详细调试日志
- 为 signContract、lateSignContract、markScrollComplete、acknowledgeContract 添加详细日志
- 记录请求参数(签名图片大小、IP、设备信息、位置)
- 记录响应状态码和完整响应数据
- 修复响应解析 bug:正确从 response.data['data'] 提取任务数据
- 增强错误日志,捕获堆栈信息便于调试

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:14:10 -08:00
hailin 846bf5b061 fix(mobile-app): 修复 getTask 解析响应格式错误
之前直接用 response.data 解析,应该取 response.data['data']。
这导致 expiresAt 等字段无法正确获取,倒计时每次都从 24 小时开始。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:09:31 -08:00
hailin 299de2005a fix(mobile-app): 修复待签署合同列表重复显示问题
之前同时调用 getPendingTasks 和 getUnsignedTasks 然后合并,
导致待签署的任务显示两次。现在只使用 getUnsignedTasks。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:07:24 -08:00
hailin cdd275479e fix(planting-service): 使用楷体 STKAITI.ttf 替换无效字体
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 02:56:01 -08:00
hailin 65ba75d8d1 fix(planting-service): 修复 fontkit 导入方式
使用 require 替代 ES import 解决 TypeScript 编译后 default export 问题

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 02:44:37 -08:00
hailin 6536ff9256 fix(planting-service): Dockerfile 添加 templates 目录复制
PDF 模板和字体文件需要复制到 Docker 容器中

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 02:41:22 -08:00
hailin c509daa353 feat(contract-signing): 使用 pdf-lib 实现专业 PDF 合同展示
后端改动:
- 添加 pdf-lib 和 @pdf-lib/fontkit 依赖
- 新建 PdfGeneratorService 使用 PDF 模板直接填充用户数据
- 添加中文字体支持 (NotoSansSC-Regular.ttf)
- 新增 GET /tasks/:orderNo/pdf 接口返回 PDF 文件
- 合同模板存放于 templates/contract-template.pdf

前端改动:
- 添加 flutter_pdfview 依赖
- 重写合同签署页面使用 PDFView 组件展示 PDF
- 下载 PDF 到临时目录后展示
- 滑动到最后一页自动标记已阅读

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 02:27:54 -08:00
hailin 2a85fcc7fa fix(mobile-app): 修复路由顺序避免 pending 被当成 orderNo
将 /contract-signing/pending 路由放在 /contract-signing/:orderNo 前面,
避免 GoRouter 将 "pending" 匹配为动态参数。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 01:08:27 -08:00
hailin c826da164c fix(mobile-app): 支付成功后跳转到合同签署页面
修改认种支付成功后的流程:
- 合同签署启用且已完成实名认证 → 跳转到合同签署页面
- 合同签署启用但未完成实名认证 → 弹窗提示去做实名认证
- 合同签署未启用 → 显示成功提示返回个人中心

符合设计流程: 支付(冻结) → 签合同 → 24小时内签署完成/超时取消

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 01:04:00 -08:00
hailin e7f2d69def fix(planting-service): 添加 P2002 错误捕获处理并发创建冲突
PostgreSQL 的 upsert 在高并发下仍可能出现唯一约束错误,
添加 try-catch 捕获 P2002 错误,发生冲突时直接查询返回已存在的记录。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:56:53 -08:00
hailin 68e269b602 fix(planting): 使用upsert解决合同签约任务创建的并发冲突
Kafka事件重复消费时,多个消费者同时创建签约任务会导致唯一约束冲突
改用upsert确保幂等性,如果orderNo已存在则返回现有记录

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:52:01 -08:00
hailin 0c6e73de85 fix(mobile-app): 修复实名认证响应解析层级错误
后端返回嵌套结构 { data: { data: {...} } },
前端需要双层解析才能获取实际数据

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:45:52 -08:00
hailin c14b87305c feat(kyc): 升级为三要素核验详版API,返回详细错误原因
- 从 Mobile3MetaSimpleVerify 改为 Mobile3MetaDetailVerify
- 新增 SubCode 详细错误码映射:
  - 201: 手机号与姓名、身份证号均不匹配
  - 202: 手机号与身份证号不匹配
  - 203: 手机号与姓名不匹配
  - 204: 其他不一致
  - 301: 查无记录

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:40:48 -08:00
hailin c3b50264cc fix(kyc): 修正阿里云手机号三要素核验的成功判断逻辑
阿里云 Mobile3MetaSimpleVerify 返回的 BizCode:
- 1: 校验一致 (成功)
- 2: 校验不一致 (失败)
- 3: 查无记录 (失败)

之前错误地将 BizCode=0 判断为成功,现改为 BizCode=1

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:28:29 -08:00
hailin 4b92fb36a3 debug(kyc): 添加阿里云API返回信息的详细日志
打印完整的response和ResultObject字段以便调试

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 00:20:45 -08:00