86 Commits

Author SHA1 Message Date
44fb21eb6a 修复导入重试的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m53s
2026-07-02 15:13:22 +09:00
8f738ffbe8 导入的问题修复
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m51s
2026-07-02 13:04:36 +09:00
5c2ef97c24 相关问题优化以及新功能开发
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m57s
迁移 155- 157
2026-06-22 17:21:13 +09:00
3f21f7a7d6 让超时时间设置成60秒 2026-06-21 17:06:40 +08:00
Break
7ec84fbc0f 导出系统
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m50s
2026-06-15 15:28:29 +08:00
Break
c437593a8c 修复错误购买报错的问题,修复接口返回虚流量启动错误的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m48s
2026-06-11 14:51:26 +08:00
Break
5c779cb6e0 不允许购买第二个主套餐
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m50s
2026-06-10 15:24:26 +08:00
Break
6a70713b30 加分布式锁
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m0s
2026-06-09 10:54:13 +08:00
Break
944526d9ef 修复订单金额落库不对的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m17s
2026-06-01 11:21:29 +08:00
Break
6a3fffc46c 错误的套餐购买限制
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m48s
2026-05-29 09:44:48 +08:00
Break
0d96a94e5f 关于上游流量同步覆盖修复,以及新增redis同步迁移
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m25s
2026-05-27 10:59:19 +08:00
Break
bcbc290bad 卡新增imei字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m10s
2026-05-26 16:30:12 +08:00
af5a21ed1e 新增三个同步时间字段 2026-05-18 10:47:07 +08:00
d597a25c69 机卡分离复机接口
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m1s
2026-05-14 09:50:48 +08:00
8f3a68a673 新增上游的停机原因
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m5s
2026-05-12 11:13:04 +08:00
b7369a9c71 修复并发,暂时的,不够完整,后续还是需要重新设计,这个太乱了,傻逼AI
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m22s
2026-05-11 17:19:40 +08:00
98ff88d5c3 开放接口,修复上游同步不对的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m55s
2026-05-11 11:20:48 +08:00
a9eaf1d697 修复缓存没有更新的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m13s
2026-05-11 10:38:52 +08:00
21b73a750d c端当前套餐开始时间过期时间,以及excel导入字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m55s
2026-05-06 09:57:58 +08:00
8a3c45c577 设备导入卡槽不对的问题 2026-04-30 11:56:09 +08:00
66e12e9629 订单相关以及佣金相关修复
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m57s
2026-04-30 09:52:39 +08:00
37b4483183 赠送套餐逻辑
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m55s
2026-04-28 17:40:06 +08:00
fe4c545308 修正数据
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m55s
2026-04-27 18:10:08 +08:00
60debb7505 统一导出任务
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m4s
2026-04-27 09:47:03 +08:00
a887f91686 修复卡轮训的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 10m14s
2026-04-26 12:41:16 +08:00
f177c26016 快照订单号以及退款订单号
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m27s
2026-04-23 17:14:10 +08:00
a207c51bfb 修复设备套餐流量不同步的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m32s
2026-04-22 18:04:53 +08:00
e27758cce3 修复新卡导入时没有正确填写停机原因的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m45s
2026-04-22 16:41:33 +08:00
e049080f6c 分裂iccid长度
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m47s
2026-04-21 10:55:12 +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
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
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
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
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
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
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
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
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
42c5ec912f feat: 技术债务清理(支付配置动态化、API文档补全、轮询常量提取、废弃代码清理)
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m13s
2026-04-14 11:11:15 +08:00
2a7ac3f86e fix: 修复轮询系统缓存不一致和可观测性问题
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
- OnCardStatusChanged/Enabled/Disabled 添加 InvalidateCardCache,
  解决 Refresh API 更新 DB 后 polling 缓存仍为旧值的 bug
- AssetResolveResponse 的 enable_polling/network_status 去掉
  omitempty,解决 false/0 时字段从响应中消失的问题
- Scheduler/Initializer/PackageHandler 增加 INFO 级别日志,
  可通过日志判断轮询是否工作、处理了哪些卡
2026-04-10 15:52:38 +08:00
cd807e58e3 feat: Excel 导入按列位置读取,IoT 卡导入支持卡业务类型
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m28s
- 重写 parseCardRows:移除列名识别,固定跳过第1行表头,按 col0=ICCID、
  col1=MSISDN、col2=VirtualNo 取值,VirtualNo 升级为必填字段
- 重写 ParseDeviceExcel:移除 buildDeviceColumnIndex,IMEI 调整至第5列
  新增 MaxSimSlots 范围校验 [1,4],整行为空时不计入 total
- 删除 findCardColumns 和 buildDeviceColumnIndex 两个冗余函数
- ImportIotCardRequest 新增 card_category 字段(normal/industry,默认 normal)
- IotCardImportTask model 新增 card_category 字段
- 迁移 000111:tb_iot_card_import_task 新增 card_category 列
- CreateImportTask 将 req.CardCategory 写入任务,空串兜底 normal
- processBatch 改用 task.CardCategory 替代写死的 CardCategoryNormal
- ImportTaskResponse 新增 card_category 字段返回

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 17:16:31 +08:00
c1cec0aede fix: 修复C端订单差价佣金计算错误及自动购包订单系列ID缺失问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m11s
- C端普通订单(createPackageOrder)创建时未设置 SellerCostPrice,
  导致底层店铺得到整个零售价作为差价佣金,上级代理链无法获得任何佣金。
  修复:在 createPackageOrder 中查询卖家成本价并写入订单字段。

- purchase_validation 新增 GetCostPrice 方法,供 C 端订单查询代理渠道成本价。

- auto_purchase 自动购包订单未设置 SeriesID 和 SellerCostPrice,
  导致差价佣金计算被整体跳过。修复:在 ProcessTask 中从卡/设备获取
  SeriesID,从套餐分配记录获取 SellerCostPrice,传入 buildOrderAndItems。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 13:35:13 +08:00
e9df1e7ded feat: IoT卡新增绑定设备虚拟号快照字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m28s
- tb_iot_card 新增 device_virtual_no 字段,存储绑定设备的虚拟号快照
- 列表/详情接口响应新增 device_virtual_no 字段
- 列表接口 is_standalone 改为可选参数(不传返回全部卡)
- 移除列表接口 virtual_no 查询参数
- 绑卡/解绑时同步更新 device_virtual_no 快照
- 设备导入时批量写入 device_virtual_no 快照
- 归档 feat-iot-card-device-virtual-no 变更提案

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 10:50:46 +08:00
78d6aded9b fix: 修复IoT卡导入时未写入carrier_type和carrier_name字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m21s
processBatch 构建 IotCard 时只写了 CarrierID,遗漏了 CarrierType 和 CarrierName,
导致导入后所有卡的运营商名称和运营商类型为空,影响 /api/admin/iot-cards/standalone
和 /api/admin/assets/resolve/{identifier} 接口返回结果

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 11:56:57 +08:00
14a8ea5a2c fix: 单卡导入虚拟号改为可选,非空时保证全局唯一
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m26s
2026-04-08 10:45:23 +08:00
80c6f6c756 feat: 资产标识符标准化、资产历史订单查询及导入虚拟号强制验证
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m21s
主要变更:
- 新增 AssetIdentifier 模型及 Store,统一管理资产标识符(ICCID/IMEI/SN 等)
- 新增迁移:asset_identifier 表、order 表新增 asset_identifier 字段、iot_card.virtual_no NOT NULL 约束
- 资产 Handler/Service/Route 全面重构,支持标识符路由查询与解析
- 新增资产历史订单查询接口,支持跨设备/卡/钱包维度的订单聚合
- 设备与物联卡导入任务强制校验虚拟号,缺失时直接拒绝
- Excel 工具函数优化,前端导入指引文档同步更新
- 归档三个 OpenSpec 提案:asset-identifier-standardization、asset-historical-orders、import-mandatory-virtual-no
- 更新 OpenAPI 文档及相关 DTO

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-07 17:39:36 +08:00
434a8b0349 feat: 轮询系统重构(分片队列 + 停复机统一 + Handler 拆分)
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m46s
【核心变更】

1. 停复机逻辑统一(StopResumeService)
   - 新增 EvaluateAndAct 统一入口,封装三条件停复机判断
   - 停机条件:无套餐(no_package) / 流量耗尽(traffic_exhausted) / 未实名(not_realname)
   - 复机条件:stop_reason 合规 + 有套餐且未耗尽 + 已实名或行业卡
   - 修复设备套餐 Bug:hasValidPackage 按 device_id 查套餐,而非仅 iot_card_id
   - 设备维度停复机加幂等锁(Redis SetNX,TTL 30s),防止多卡并发重复调 Gateway

2. Redis 分片队列(PollingQueueManager)
   - 新建 queue_manager.go,封装所有轮询 Redis 操作
   - 16 分片 Sorted Set,Key 格式:polling:shard:{shardID}:queue:{taskType}
   - Lua 脚本原子出队(ZRANGEBYSCORE + 分批 ZREM),消除竞态窗口
   - 新增背压检测:队列深度超 50 万时 Scheduler 跳过该分片
   - RemoveFromAllQueues 覆盖 4 种任务类型(含 protect)

3. Handler 拆分(polling_handler.go 1360行 → 5个专注文件)
   - polling_base.go:共享基类(并发控制/卡缓存/重入队)
   - polling_realname_handler.go:实名采集,实名 0→1 时立即触发复机
   - polling_carddata_handler.go:流量采集,保留跨月边界检测逻辑
   - polling_package_handler.go:套餐采集,委托 EvaluateAndAct 决策
   - polling_protect_handler.go:保护期一致性检查,保护期内强制修正

4. 配置管理(PollingConfigManager)
   - 新建 config_manager.go,从 scheduler.go 提取配置职责
   - 内存缓存 + 5 分钟定时刷新,刷新失败保留原缓存
   - 修复 getCardCondition:停机卡返回 suspended,不再错配 activated 配置

5. 渐进式初始化(CardInitializer)
   - 新建 initializer.go,分批加载(每批 10 万),批次间 sleep 500ms
   - 过滤 enable_polling=false 的卡,初始化完成前 Scheduler 不出队

6. 卡生命周期服务(PollingLifecycleService)
   - 新建 lifecycle_service.go,替代已删除的 callbacks.go 和 api_callback.go
   - OnCardCreated/OnCardEnabled/OnCardStatusChanged 入队前检查 enable_polling

7. Scheduler 精简(1000+行 → 227行)
   - 保留纯调度循环:scheduleLoop + processShardSchedule + enqueueBatch
   - 保留每 10 秒触发套餐过期检测和流量重置
   - 移除所有 DB 操作、配置加载、卡初始化逻辑

8. 轮询管控 API(enable_polling)
   - 新增 PUT /api/admin/assets/:id/polling-status 接口
   - 支持对设备/卡维度开关轮询,关闭后从所有分片队列移除

9. 数据库迁移
   - 000103:tb_device 新增 enable_polling 字段(boolean, NOT NULL, DEFAULT true)
   - 000104:新增 suspended 轮询配置,为 activated 配置补全 protect_check_interval

【文件统计】
- 新增:19 个文件(handler × 5、polling 组件 × 4、迁移 × 3 等)
- 修改:20 个文件(bootstrap 注入、store 接口、monitoring 适配分片等)
- 删除:3 个文件(polling_handler.go、callbacks.go、api_callback.go)

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-07 12:27:04 +08:00