hailin
724fb08be4
fix(contribution): 发布过期份额同步事件 + 管理后台/挖矿app状态显示
...
- contribution-service: swapContributionForMerge 作废旧份额记录后,
立即发布 ContributionRecordSynced outbox 事件(isExpired=true),
mining-admin-service 收到后 upsert syncedContributionRecord
- mining-admin-web: 算力记录状态列改为绿色"有效"/红色"无效"
- mining-app: 贡献值记录卡片始终显示有效/无效状态标签
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 11:35:55 -08:00
hailin
97f8b7339f
fix(auth): LOGIN 能力禁用后强制下线已登录用户
...
## 问题
管理员在后台禁用用户的 LOGIN 能力后,该用户仍然可以正常使用 mining-app。
原因是 LOGIN 检查只在登录/刷新 token 时执行,已持有有效 JWT(7天有效期)
的用户不会被影响,直到 token 过期才会被拦截。
## 修复
### 后端 - JwtAuthGuard (auth-service)
- 在 JWT 验证通过后,增加 LOGIN 能力实时检查
- 调用 CapabilityService.isCapabilityEnabled() 查询 Redis 缓存
- LOGIN 被禁用时返回 403 ForbiddenException("您的账户已被限制登录")
- 采用 fail-open 策略:Redis/DB 查询失败时放行,不影响正常用户
- 每次认证请求多一次 Redis GET(<1ms),对当前用户规模无性能影响
### 前端 - mining-app API Client
- 新增 onLoginDisabled 全局回调(类似现有的 onUnauthorized)
- Dio 拦截器检测 403 响应中包含"限制登录"关键词时触发回调
- 回调执行:清除用户状态 + 跳转登录页(与 401 处理一致)
## 影响范围
- 所有使用 @UseGuards(JwtAuthGuard) 的端点都会实时检查 LOGIN 能力
- 管理员禁用 LOGIN 后,用户下一次 API 请求即被拦截并强制下线
- 不影响公开端点(登录、注册等不经过 JwtAuthGuard 的接口)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 05:01:37 -08:00
hailin
fe9a30df85
feat(mining-app): 接入 capabilitiesProvider 实现 UI 层能力适配
...
Phase 5 补充:在 mining-app Flutter 前端关键页面接入 capability 检查,
被禁用的功能按钮置灰并显示 SnackBar 提示,后端 403 拦截作为兜底。
修改的页面及对应能力:
- send_shares_page: P2P_SEND → "确认发送"按钮
- receive_shares_page: P2P_RECEIVE → 顶部限制提示横幅
- c2c_market_page: C2C → "发布"按钮 + "接单"弹窗入口
- c2c_publish_page: C2C → "发布买入/卖出"按钮
- trading_page: TRADING → "确认交易"按钮
- edit_profile_page: PROFILE_EDIT → "保存"操作
- team_page: VIEW_TEAM → 页面数据加载前检查
设计原则:
- 不阻断页面浏览,只阻断操作
- fail-open: 能力获取失败时默认全部开启
- 禁用时点击按钮弹出 SnackBar 提示"您的XX功能已被限制"
- 沿用现有 disabled 按钮样式(.withOpacity(0.4))
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 01:36:24 -08:00
hailin
55cfc96464
feat(capability): 实现用户能力权限控制系统(Capability-based Permission)
...
借鉴 Stripe Capability 模型,实现 13 项细粒度用户功能权限控制:
LOGIN, TRADING, C2C, TRANSFER_IN/OUT, P2P_SEND/RECEIVE,
MINING_CLAIM, KYC, PROFILE_EDIT, VIEW_ASSET/TEAM/RECORDS
## 架构设计
- auth-service 为能力数据唯一写入点(DB + Redis DB14 缓存)
- 下游服务通过独立 ioredis 客户端直连 Redis DB14 检查能力(~1ms)
- 默认全部开启(fail-open):无缓存/Redis 故障 = 允许通行
- Guard 执行顺序:JwtAuthGuard → CapabilityGuard
## Phase 1: auth-service 核心
- Prisma Schema: UserCapability + CapabilityLog 两张表
- Domain: Capability 枚举, CapabilityMap 类型, Repository 接口
- Infrastructure: PrismaCapabilityRepository(含 $transaction 原子操作)
- Application: CapabilityService(Redis 缓存优先 → DB fallback → 写回 Redis TTL 1h)
- Scheduler: 每 60 秒扫描到期限制自动恢复(Redis 分布式锁防重复)
- API: GET /auth/user/capabilities (JWT), Internal CRUD API (服务间)
- 登录/refreshToken 均增加 LOGIN 能力检查
## Phase 2: 下游 CapabilityGuard
- trading-service: 14 个端点标注(TRADING/C2C/TRANSFER/P2P_SEND/VIEW_ASSET)
- contribution-service: 3 个端点标注(VIEW_RECORDS/VIEW_TEAM)
- mining-service: Guard 注册 + JwtAuthGuard accountSequence 兼容修复
- auth-service: KYC 端点标注(controller 级别 UseGuards)
## Phase 3: mining-admin-service
- CapabilityAdminService: 代理 auth-service internal API + 本地 AuditLog
- CapabilityController: Admin CRUD + 批量设置 + 变更日志查询
## Phase 4: mining-admin-web
- capability-management.tsx: 分组 Switch 开关 + 禁用 Dialog(原因+到期时间)+ 变更日志分页
- React Query hooks: useCapabilities/useSetCapability/useCapabilityLogs
- 用户详情页新增"权限管理"Tab
## Phase 5: mining-app (Flutter)
- CapabilityMap 数据模型 + ForbiddenException 异常类
- api_client.dart: 403 响应适配 ExceptionFilter 包装格式
- capabilitiesProvider: 登录后获取能力列表,fail-open 降级
## 审计修复
- CRITICAL: users.api.ts capability 方法移入 usersApi 对象内部
- P0: Flutter 403 解析路径适配 {error:{code,message}} 实际格式
- P0: 批量接口 operatorId 提升到 body 顶层匹配 auth-service 契约
- P1: mining-service JwtAuthGuard accountSequence fallback payload.sub
- P1: refreshCache 加 try/catch 防止 Redis 故障导致 500
- P1: processExpiredRestrictions 改用 upsertWithLog 事务方法
- P1: C2C upload-proof 补加 @RequireCapability('C2C')
- HIGH: internal.controller.ts 新增 capability 枚举校验
- HIGH: admin capability.controller.ts adminId fallback + query params 类型修复
- MEDIUM: setCapability 改用 $transaction 保证 upsert+log 原子性
## 部署注意
- 需运行: cd auth-service && npx prisma migrate dev --name add_user_capabilities
- 需配置: mining-admin-service .env AUTH_SERVICE_URL=http://auth-service:3010
## 待后续处理(P2)
- P2P_RECEIVE 需在业务逻辑层检查(收款方无主动请求)
- MINING_CLAIM/PROFILE_EDIT 待对应端点实现后标注
- getCapabilities 返回 Map 转 Array 丢失 reason/expiresAt 详细字段
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:19:56 -08:00
hailin
19f350b8e3
fix(mining-app): 全网兑换销毁量改为保留8位小数
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 09:54:53 -08:00
hailin
c293309bdf
fix(mining-app): 全网兑换销毁量保留4位小数
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 09:53:47 -08:00
hailin
a39af93063
fix(mining-app): 全网兑换销毁量改用circulationPool+保留小数格式
...
根据业务需求,"全网兑换销毁量"应显示流通池总数量(全网卖出量),
而非SELL_BURN销毁总量。同时将formatIntWithCommas改为formatWithCommas
以保留小数位,避免小数值被截断显示为0。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 09:53:14 -08:00
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
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
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
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
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
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
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
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
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
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
hailin
8e63547a3e
fix(transfer): 修复积分股划转到分配账户失败问题
...
后端:
- transfer.service.ts: Error → BadRequestException,业务错误返回HTTP 400而非500
- transfer.controller.ts: Error → UnauthorizedException,正确返回HTTP 401
- 错误信息改为中文:余额不足、账户不存在等提示更明确
前端:
- asset_display.dart: 新增 tradingAvailableShares 计算属性(总可用 - 挖矿可用)
- trading_page.dart: 划转弹窗显示可用余额(扣除冻结)而非总余额
- trading_page.dart: 划转失败时显示后端具体错误信息而非通用提示
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 06:24:35 -08:00
hailin
03cc5bc324
fix(mining-app): QR码解析加固 + debugPrint排查
...
- 清除不可见字符(BOM/零宽空格)
- 三级宽松解析:正则→Uri.parse→兜底phone=提取
- 添加 [QR_SCAN] 调试日志定位实际扫码值
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 05:54:34 -08:00
hailin
8c31dee000
fix(c2c): 修复买方待付款页面灰色无法操作问题
...
根因: c2c_order_model.dart 的 _parsePaymentMethod 不识别 GREEN_POINTS,
导致 paymentMethod=null → hasPaymentInfo=false → 收款信息卡片隐藏 → 页面不可操作
前端修复:
- C2cPaymentMethod 枚举增加 greenPoints,解析器支持 GREEN_POINTS
- 支持逗号分隔的多支付方式字符串(取第一个作为主要方式)
- 订单详情页增加绿积分图标和卖方 Kava 地址显示(买方可复制)
后端修复:
- takeOrder() 接买单时自动获取卖方 Kava 地址写入 sellerKavaAddress
- 买方在订单详情页可看到卖方 Kava 地址用于转绿积分
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 05:41:14 -08:00
hailin
9e83127113
fix(mining-app): C2C"我的"列表待接单订单增加取消按钮
...
在我的订单卡片上直接显示取消按钮(PENDING状态),
弹出确认对话框后调用 cancelOrder API
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:46:50 -08:00
hailin
7c416adecd
feat(mining-app): P2P转出记录显示手续费及合计扣除
...
- P2pTransferModel 新增 fee 字段解析
- 转出卡片聚合显示:转账金额 + 手续费 + 合计扣除
- 转入卡片保持只显示转账金额
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:45:37 -08:00
hailin
7d548dac4e
fix(mining-app): C2C接单验证收款信息 + 数字显示优化
...
- 接BUY单时验证收款账号和姓名必填,仅绿积分时自动使用账户ID
- 所有C2C价格/数量/金额显示改用formatCompact,去掉多余小数位
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:31:08 -08:00
hailin
b50091eb1e
fix(mining-app): C2C 发布页"积分值金额"改为"绿积分数量"
...
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:09:17 -08:00