480 Commits

Author SHA1 Message Date
e9862a67ba fix: 修复资产卡列表未返回 realname_policy 字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m10s
buildDeviceResolveResponse 和 GetRealtimeStatus 中构建 BoundCardInfo 时
均遗漏了 RealnamePolicy 字段赋值,导致 resolve 和 realtime-status
两个接口的设备卡列表不返回实名认证策略。字段在 Model 和 DTO 中均
已定义,Service 层补充赋值即可。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-20 14:43:09 +08:00
868f5a8ef3 fix: 修复轮询停机连坐、实名逆转防抖及carrier_stopped原因写入缺失三个逻辑缺陷
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m37s
2026-04-20 11:24:56 +08:00
fd795d8742 feat: 新增设备切卡模式接口 SetSwitchMode
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m32s
2026-04-18 16:22:30 +08:00
2b3a9cb33f feat: 新增套餐使用记录实付金额快照字段 paid_amount
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m19s
- 新增迁移 000129:tb_package_usage 添加 paid_amount BIGINT 字段,存量数据通过 JOIN tb_order 回填
- PackageUsage Model 新增 PaidAmount *int64 字段
- 4 个写入点(order service 主套餐/加油包、auto_purchase 主套餐/加油包)赋值 order.ActualPaidAmount
- AssetPackageResponse DTO 新增 paid_amount 字段
- GetCurrentPackage / GetPackages 填充 paid_amount,接口直接返回购买价格无需 JOIN 订单表
2026-04-18 10:19:21 +08:00
2413c2fe14 feat: 新增批量获取文件下载预签名 URL 接口
新增 POST /api/admin/storage/batch-download-urls,支持一次传入最多 50 个 file_key,返回对应预签名下载 URL 映射。解决列表页批量展示图片需多次请求的问题。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-18 10:08:45 +08:00
28ac58ea18 feat: PollingRealnameHandler 新增设备级套餐实名激活联动
- 结构体新增 deviceSimBindingStore 字段,构造函数参数列表末尾追加
- 新增 triggerDeviceRealnameActivation:卡首次实名(0→1)时查询所属设备,
  若有绑定则提交 carrier_type=device 的 TaskTypePackageFirstActivation 任务
- 独立卡(无绑定设备)静默跳过,任务提交失败仅记录 Warn 日志不阻断流程
- registerPollingHandlers 传入 h.workerResult.Stores.DeviceSimBinding
- 修复「购买后某张卡实名」场景下设备级套餐永不激活的缺陷

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-18 09:30:50 +08:00
8e61cb1a54 fix: 购买时检查载体实名状态,已实名跳过 pending 直接激活
- iot_card 载体:扩展查询字段同时读取 real_name_status,已实名则保持 Active 不切换 pending
- device 载体:通过 GORM 子查询统计绑定卡中已实名数量,count>0 则直接激活
- 查询出错时保守默认 false,不阻断购买流程
- 修复「先实名后购买」场景下套餐永久 pending 及购买后不自动复机的双重缺陷

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-18 09:30:40 +08:00
6caf0f6141 feat: 新增全局操作密码功能,将线下充值验证从登录密码改为统一操作密码
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
- 新增 RedisSystemOperationPasswordKey 常量函数(pkg/constants/redis.go)
- 新增 operation_password Service(Set/IsSet/Verify,bcrypt 哈希存 Redis)
- 新增 SuperAdminHandler 及两个接口:
  - POST /api/admin/super-admin/operation-password(设置/重置,仅超级管理员)
  - GET /api/admin/super-admin/operation-password/status(查询是否已设置)
- AgentRecharge.OfflinePay 操作密码验证从"查当前用户登录密码"改为"全局操作密码 Verify"
- Bootstrap/路由/文档生成器同步注册
2026-04-18 09:06:33 +08:00
ad30f5d41b feat: 代理充值支持线下支付凭证上传与存储
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 18:29:06 +08:00
1033d7666b 修复主账号问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m6s
2026-04-17 18:07:29 +08:00
c5ed040359 feat: 后台管理新增 UpdateRealnameMode 接口并注册路由 PATCH /api/admin/assets/:identifier/realname-mode
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 17:32:18 +08:00
363e0efb34 feat: C 端充值、购买、实名链接接口接入实名策略拦截(before_order/after_order)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 17:31:21 +08:00
1363797378 feat: 导入 Service 和 Worker 传递 realname_policy 写入资产记录
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 17:31:01 +08:00
71498883b5 feat: iot_card/device Service 新增 UpdateRealnamePolicy 方法(含幂等检查)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 17:30:13 +08:00
1d75a4c31a feat: asset Service 新增 GetEffectiveRealnamePolicy 策略判断及 HasValidRechargeOrPaidOrder 检查逻辑
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 17:29:32 +08:00
89eec1406a feat: iot_card/device Store 新增 UpdateRealnamePolicy 方法
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 17:28:58 +08:00
9a625f51ef feat: C 端查询及设备导入接口 DTO 新增 realname_policy 字段
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 17:28:20 +08:00
2d6456c4a3 feat: 后台管理查询接口 DTO 新增 realname_policy 字段
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 17:27:10 +08:00
9bd1d60e85 feat: 四个 Model 新增 realname_policy 字段(含 gorm 标签和中文注释)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-17 17:26:20 +08:00
e0a37f4a11 fix: verify-asset 接口增加卡绑定设备校验
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m29s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 14:49:11 +08:00
0a2961ecd6 fix: 支付回调补写 actual_paid_amount 字段,从支付平台回调中提取实付金额
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m48s
- HandlePaymentCallback 新增 actualPaidAmount int64 参数,Updates 写入 actual_paid_amount
- 微信 V2 回调从 TotalFee 字符串解析分值;V3 直接使用 TotalAmount
- 支付宝回调优先取 buyer_pay_amount(实付),回退 total_amount,元转分使用 math.Round
- 富友回调从 OrderAmt 字符串解析分值
- dispatchWechatCallback 同步增加 paidAmount 参数透传
2026-04-17 11:12:35 +08:00
fa554c3930 feat: 注册 C 端微信 JSSDK 配置接口路由及文档生成
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m35s
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-16 18:38:43 +08:00
1125701329 feat: 新增 C 端微信 JSSDK 签名配置接口 Handler
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-16 18:38:20 +08:00
ed1facc1b8 feat: 公众号服务新增 GetJSSDKConfig 方法及 JSSDK 配置 DTO
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-16 18:37:59 +08:00
0cba6fd6d5 fix: 修复轮询缓存竞态导致流量增量重复计全量的问题
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
getCardWithCache 在缓存 miss 时将 writeCardToCache 由异步协程改为同步调用。
原实现中协程可能在 updateCardCache 之后才被调度执行,将
last_gateway_reading_mb 覆盖回 DB 旧值(0),导致下次轮询
increment = gatewayFlowMB - 0 = 全量,触发套餐流量重复扣减。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-16 18:33:46 +08:00
aef20d2ab1 fix: 修复禁用所有轮询配置重启后再启用无法工作的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m23s
- 新增 RedisPollingConfigChangedChannel 常量,用于跨进程配置变更通知
- ConfigService 注入 Redis,Create/Delete/UpdateStatus 后发布 Pub/Sub 事件
- PollingConfigManager 新增 WatchChanges() 方法,收到通知立即刷新内存缓存
- PollingInitializer 新增 Restart() 方法,支持初始化完成后安全重启(CAS 防并发)
- Worker 订阅配置变更事件,configs 从空变为非空时触发 Initializer.Restart()

根因:启动时所有配置禁用导致分片队列为空,Initializer 是一次性的,
之后启用配置只更新 DB 但不重建队列,调度器无卡可处理
2026-04-16 17:32:43 +08:00
0ec16d4afa fix: 实名轮询防止上游接口故障时误降级已实名状态
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m34s
Gateway 返回 data=null 时 sonic 解析为零值结构体(ICCID="" RealStatus=false),
导致已实名卡被误判为未实名并触发停机。

通过检查响应中 ICCID 是否回填来判断数据有效性:
- ICCID 为空:视为上游接口故障,重新入队,不更新实名状态
- ICCID 有值:响应有效,正常处理(含合法的未实名降级)
2026-04-16 16:48:14 +08:00
2d0b4e9bc0 fix: 充值订单列表按当前登录资产过滤,修复越权查看其他资产数据的漏洞
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-16 15:56:43 +08:00
520b126ecf feat: JWT Claims 新增资产字段,登录 token 携带当前资产上下文
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-16 15:55:41 +08:00
5d9be1d7e4 fix: 修正轮询配置多匹配逻辑,支持同卡匹配多个配置并按 priority 合并 interval
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m27s
核心变更:
- MatchConfig 改为 MatchConfigs,返回所有匹配配置
- MergedTaskIntervals 按 task type 合并各配置,选取最高优先级(非 nil 且最小 priority 值)
- hasAnyEnabledInterval 过滤所有 interval 均为 NULL 的配置
- calcInitialDelay 重构为纯函数,接收 interval 参数
- 移除 getEnabledTaskTypes 和 getIntervalByTaskType(被 MergedTaskIntervals 替代)
- scheduler.go 新增心跳 key + 顶层 panic recovery + Init 完成守卫
- initializer.go 批量失败日志升级为 Error,逐条检查 Pipeline 命令错误
- 数据迁移:禁用 id=29 的轮询配置(所有 interval 均为 NULL)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 14:27:47 +08:00
5065d925ad fix: 修正套餐激活和时间字段nullable问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m33s
核心变更:
1. Model层时间字段改为*time.Time并设为nullable
   - PackageUsage.ActivatedAt/ExpiresAt
   - PersonalCustomerDevice/ICCID/Phone.LastUsedAt/VerifiedAt

2. 数据库迁移:
   - activated_at/expires_at列移除NOT NULL约束
   - 清洗零值记录(status=0且activated_at<'2000-01-01')

3. 新增ActivateSpecificPackage方法:精准激活指定套餐,
   修复HandlePackageQueueActivation从"查找过期包"改为直接激活payload指定套餐

4. 新增孤儿套餐恢复扫描:Worker启动或每次套餐检查时,
   自动发现并恢复无status=1主套餐的孤儿载体

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 11:14:39 +08:00
97d6319b64 fix: 修正 HasValidByCarrier 有效套餐定义,仅 status=Active 才算有效
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m43s
修复Bug:原代码将 Pending(0) 也算作有效套餐,导致待生效套餐的卡
不会被触发停机指令。现改为仅生效中(Active)才算有效套餐。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 18:14:50 +08:00
0a27a78d97 fix: 修正强充订单状态映射错误,0-based DB 常量正确映射为 1-based 客户端状态
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 48s
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 14:58:37 +08:00
647d78309d feat: 将卡状态任务类型接入队列管理、生命周期和初始化器
queue_manager.go: allTaskTypes 追加 TaskTypePollingCardStatus,注释更正为5个队列
lifecycle_service.go: getEnabledTaskTypes 和 calcInitialDelay 新增 card_status 条件
initializer.go: initBatch 新增 CardStatusCheckInterval 块,以 LastCardStatusCheckAt 为基准写入分片队列

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 12:22:42 +08:00
c7f486ae09 feat: 新增 PollingCardStatusHandler 及工具函数卡状态支持
polling_cardstatus_handler.go: 新文件,实现卡开停机状态轮询
  - Gateway QueryCardStatus → 停机/0,其他/1
  - 状态变化时写 DB + 更新缓存 + 触发 EvaluateAndAct
  - verbose log 位于 gateway 块内
polling_utils.go: getIntervalByTaskType 新增 TaskTypePollingCardStatus case

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 12:22:34 +08:00
71559547b6 feat: 为四种现有轮询 Handler 添加 verbose log 输出
realname: verbose log 移入 gateway 块内,避免 gateway=nil 时输出零值
carddata: 添加 && h.gateway != nil 门卫,确保仅 gateway 查询成功时输出
package: verbose log 在 freshCard 加载后、EvaluateAndAct 之前输出
protect: 引入 actionTaken 变量,字段名 network_status → network_status_at_check,新增 action_taken

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 12:22:25 +08:00
6292443f69 feat: PollingBase 新增 verboseLog 支持,Worker 传入配置
polling_base.go: PollingBase.verboseLog bool 字段,NewPollingBase 新增参数
main.go: cfg.Polling.VerboseLog 作为第6个参数传入 NewPollingBase

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 12:22:16 +08:00
97c196b7c6 feat: PollingConfig DTO 和 Service 支持卡状态检查间隔
dto: 新增 CardStatusCheckInterval 字段(validate min=30,description 含枚举说明)
config_service.go: 创建/更新/响应映射均支持 CardStatusCheckInterval

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 12:22:09 +08:00
cb328f3ec2 feat: PollingConfig 和 IotCard 模型新增卡状态检查字段
polling.go: CardStatusCheckInterval *int(card_status_check_interval)
iot_card.go: LastCardStatusCheckAt *time.Time(last_card_status_check_at)

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 12:22:01 +08:00
dd408fcdca 日志输出 2026-04-15 11:17:09 +08:00
516bb92a16 refactor: 删除 enterprise_device service 中无路由接入的死代码方法
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
ListDevicesForEnterprise、GetDeviceDetail、SuspendCard、ResumeCard、validateCardOperation 均无对应路由和 Handler 调用,且 SuspendCard/ResumeCard 仅修改本地 DB 未调 Gateway,存在错误实现风险。统一使用 iot_card stop_resume_service 处理停复机。

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 11:16:36 +08:00
023a4309eb fix: 修正 realtime-status 路由文档描述,补充说明设备类型会实时调 Gateway
原描述误写为不调网关,实际 GetRealtimeStatus 对设备类型会调用 SyncDeviceInfo 接口。

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 11:16:01 +08:00
b972a776d9 重构充值订单模块:用 tb_recharge_order + tb_payment 替换 tb_asset_recharge_record
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m32s
- 新增 RechargeOrder 和 Payment 模型及对应 Store
- 新增 ClientRechargeOrderHandler 提供充值订单列表/详情接口
- 修改 client_wallet.go 使用新表读写充值数据
- 修改 callback/payment.go 将 CRCH 订单路由到 rechargeOrderService
- 修改 client_order/service.go 的强充流程使用新表
- 修改 auto_purchase.go 从 tb_recharge_order 读取 linked_package_ids
- 修改 order/service.go 的 WalletPay 使用 tb_payment 记录
- 修改 wechat_config_store.go 从 tb_recharge_order 统计待支付充值数
- 移除 AssetRechargeStore 和 AssetRechargeRecord 的注册引用
- 修复文档生成器缺失 ClientRechargeOrder handler
- 状态枚举改为 0-based: Pending=0, Paid=1, Closed=2, Refunded=3
2026-04-15 11:00:32 +08:00
8706247436 fix: 资产解析接口 BoundCardInfo 添加运营商字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m18s
2026-04-14 17:10:28 +08:00
8154a61453 fix: 移除 standaloneListColumns 中已废弃的分佣字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m51s
迁移 000116 已从 tb_iot_card 删除 first_commission_paid 和 accumulated_recharge
两列,但 standaloneListColumns 未同步清理,导致 SELECT 查询报列不存在错误。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 12:40:04 +08:00
7cdb66cbe4 refactor: 统一状态名称映射为公共函数,清理废弃换卡/商户类型常量和模型 2026-04-14 11:51:58 +08:00
5410181e77 修复:C端资产信息接口 lan_ip 字段无值时不返回的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m17s
去掉 DeviceRealtimeInfo.LANIP 的 omitempty 标签,
确保 device_realtime.lan_ip 始终出现在响应中(无值时返回 null)
2026-04-14 11:49:17 +08:00
548ec0cd6b feat: 补全 _name 字段公共映射函数,修正实名认证注释 2026-04-14 11:44:23 +08:00
c35542f911 feat: 补全客户端订单和资产 DTO _name 字段,修复代码格式 2026-04-14 11:19:57 +08:00
42c5ec912f feat: 技术债务清理(支付配置动态化、API文档补全、轮询常量提取、废弃代码清理)
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m13s
2026-04-14 11:11:15 +08:00