chore: 初始开源发布

iotlcm-worker-svr:异步执行中枢(RabbitMQ 消费者 + 全量同步编排)。

- Go module:iotlcm-worker-svr → git.5iot.com/iotlcm-public/iotlcm-worker-svr(214 文件)
- 凭据与内部标识脱敏:MySQL/Redis 凭据、私网与生产 IP、内网域名、
  库名 xiujie_admin → iotlcm、哨兵名占位
- 159 处真实手机号 → 合法 11 位编造号(保留号段与后 4 位,维持互异,
  不破坏「校验 MSISDN 格式」等测试断言)
- 移除内部资产:CI 触发器、Jenkins 触发测试文档、预演门禁与镜像
  digest 记录
- Dockerfile 改用公共基础镜像(golang:1.25-alpine → alpine:3.23),
  移除写死的 git 凭据
- README 重写(架构/全量同步模型/配置/已知失败),补 Apache-2.0
  LICENSE,LF 行尾 + .gitattributes

已知:3 个测试包在源仓同一提交上同样失败(client/upstream、
service/allocate、service/inbound),属既有缺陷,本仓未引入亦未修复。
This commit is contained in:
MiFaZhan
2026-10-22 16:37:56 +08:00
commit 2bec257289
361 changed files with 71524 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
package consts
// BatchSubBatchSize 是批量开停数据 / 停复机执行时,单个上游通道每次请求携带的卡数量上限。
// 原来一个通道整组一次性发给 upstream-chan,大批量会触发 worker 侧 HTTP 超时(默认 2 分钟上限)导致整批失败。
// 按此值拆分为多个小请求后,每个请求都能在超时上限内返回。
const BatchSubBatchSize = 100
// BatchSubBatchConcurrency 是同一通道内子批次的并发度,受信号量限制:
// 即最多同时向上游发起 BatchSubBatchConcurrency 个请求,等价于最多同时发起同样数量的运营商调用,
// 既避免串行过慢,也避免无节制并发打爆运营商限流。如需更保守可调小该值。
const BatchSubBatchConcurrency = 5
+154
View File
@@ -0,0 +1,154 @@
package consts
func FormalPackageTypes() []int { return []int{PackageTypeCard, PackageTypePool} }
func IsAddPackageType(packageType int) bool {
return packageType == PackageTypeCardAddPackage || packageType == PackageTypePoolAddPackage
}
const (
BatchTypeInbound = 1
BatchTypeAllocate = 3
BatchTypeCardAddPackage = 11
BatchTypePoolAddPackage = 12
BatchTypeSimCardStart = 103
BatchTypeSimCardStop = 104
BatchTypeSimCardRestart = 105
BatchTypeSimCardCancel = 106
BatchTypeSimCardUnsub = 108
BatchTypeDataCut = 107
BatchTypeDataStart = 109
BatchTypeDataStop = 110
BatchTypeSimWarningConfig = 40
BatchTypeTrafficCutoffConfig = 41
BatchTypeTrafficCutoff = BatchTypeTrafficCutoffConfig // Deprecated: use BatchTypeTrafficCutoffConfig.
// 异步续费/变更扩展
BatchTypePrepare = 4 // 预处理(renew/change 共用 prepare)
BatchTypeRenew = 101 // 卡续费
BatchTypeChange = 102 // 卡变更套餐
// t_sim_card_bind_pkg.package_type 中,只有正式卡套餐和池套餐参与续费/变更判断。
PackageTypeCard = 101
PackageTypePool = 102
PackageTypeCardAddPackage = 103
PackageTypePoolAddPackage = 104
BatchSourceTypeBatchSelect = 0
BatchSourceTypeRange = 1
BatchSourceTypeBatchInput = 2
BatchSourceTypeFile = 3
BatchSourceTypeScheduled = 4
BatchSourceTypeExcel = BatchSourceTypeFile
BatchSourceTypeInput = BatchSourceTypeBatchInput
BatchNoPrefixCardAddPackage = "ADP"
BatchNoPrefixPoolAddPackage = "PAP"
SimCardStatusOperTypeStop = "0"
SimCardStatusOperTypeStart = "1"
RestartPhaseCreated = "created"
RestartPhaseWaitingResume = "waiting_resume"
RestartPhaseResuming = "resuming"
RestartPhaseFinished = "finished"
SimBossCardStatusActivated = 2
SimBossCardStatusStopped = 4
SimBossCardStatusCanceled = 9
SimApnOperTypeOpen = "0"
SimApnOperTypeStop = "1"
SimApnNameDefault = "CMIOT"
SimDataServiceStatusEnabled = 1
SimDataServiceStatusDisabled = 0
BatchAsyncStatusPending = 1
BatchAsyncStatusProcessing = 2
BatchAsyncStatusSuccess = 3
BatchAsyncStatusFailed = 4
BatchAsyncStatusPartialSuccess = 5
BatchRunResultPending = 0
BatchRunResultRunning = 1
BatchRunResultSuccess = 2
BatchRunResultFailed = 3
BatchRunResultPartialSuccess = 4
BatchDetailStatusPending = 0
BatchDetailStatusRunning = 1
BatchDetailStatusSuccess = 2
BatchDetailStatusFailed = 3
ResourceTypeExcel = 1
DownloadStatusGenerated = 1
ResourceExportSceneCardAddPackage = 11
ResourceExportScenePoolAddPackage = 12
// 卡套餐有效状态
PackageStatusNone = 0
PackageStatusPending = 1
PackageStatusEffective = 2
PackageStatusExpired = 3
// 订购记录有效状态(t_sim_card_bind_pkg.effective_status)
EffectiveStatusPending = 0
EffectiveStatusEffective = 1
EffectiveStatusExpired = 2
EffectiveStatusTerminated = 3
EffectiveStatusVoided = 4
// 退订状态(t_order.return_status)
OrderReturnStatusNone = 0
OrderReturnStatusSuccess = 4
OrderReturnStatusPartial = 3
// Renew/change order contract. These values mirror the Admin cardpackage
// domain and the production t_order/t_order_item enum contract.
OrderTypeCardSubscribe = 1
OrderTypeCardRenew = 2
OrderTypeCardChange = 3
OrderStatusCompleted = 5
CustomerTypeAgent = 1
PayTypeOffline = 3
PayTypeBalance = 4
PayStatusPaid = 2
ProductTypeCard = 1
PayModeYearMonth = 1
ShippingMethodNone = 3
PackageBusinessTypeSubscribe = 0
PackageBusinessTypeChange = 1
PackageBusinessTypeRenew = 2
ResourceBatchDownloadTaskSimCardAddPackage = "单卡加油包结果"
ResourceBatchDownloadTaskSimPoolAddPackage = "流量池加油包结果"
SimCardAddPackageMaxFileSize = 50 << 20
SimPoolAddPackageMaxFileSize = 50 << 20
SimCardAddPackageSubDirImportExcel = "sim-card-add-package/import"
SimCardAddPackageSubDirResultExcel = "sim-card-add-package/result"
SimPoolAddPackageSubDirImportExcel = "sim-pool-add-package/import"
SimPoolAddPackageSubDirResultExcel = "sim-pool-add-package/result"
// 续费/变更结果目录
SimCardRenewResultSubDir = "sim-card-renew/result"
SimCardChangeResultSubDir = "sim-card-change/result"
// 续费/变更结果任务名(沿用 Admin 约定)
ResultTaskSimCardRenew = "卡续费结果"
ResultTaskSimCardChange = "卡变更套餐结果"
ResultTaskSimCardPrepare = "卡续费/变更预处理结果"
)
// RenewPriceSource 续费/变更价格来源
const (
RenewPriceSourceSystem = "system"
RenewPriceSourceAgentDefault = "agentDefault"
RenewPriceSourceTarget = "target"
)
+42
View File
@@ -0,0 +1,42 @@
package consts
import "strings"
const (
BillingMethodMonth = 1
BillingMethodYear = 2
RenewDurationUnitMonth = "month"
RenewDurationUnitYear = "year"
)
func BillingMethodDurationUnit(billingMethod int) string {
if billingMethod == BillingMethodMonth {
return RenewDurationUnitMonth
}
return RenewDurationUnitYear
}
func NormalizeRenewDurationUnit(unit string) string {
if strings.EqualFold(strings.TrimSpace(unit), RenewDurationUnitMonth) {
return RenewDurationUnitMonth
}
return RenewDurationUnitYear
}
func RenewDurationUnitText(unit string) string {
if NormalizeRenewDurationUnit(unit) == RenewDurationUnitMonth {
return "个月"
}
return "年"
}
func DurationValueToMonths(unit string, value int) int {
if value <= 0 {
return 0
}
if NormalizeRenewDurationUnit(unit) == RenewDurationUnitMonth {
return value
}
return value * 12
}
+31
View File
@@ -0,0 +1,31 @@
package consts
const (
QueueTrafficUsageDailyRetry = "iotlcm.traffic_usage.daily.retry"
QueueTrafficUsageMonthlyRetry = "iotlcm.traffic_usage.monthly.retry"
QueueTrafficUsageMonthlyStart = "iotlcm.traffic_usage.monthly.start"
// QueueTrafficUsageDailyStart carries one command per full daily usage run.
// Admin publishes it; Worker owns the card scan and Redis production.
QueueTrafficUsageDailyStart = "iotlcm.traffic_usage.daily.start"
// QueueTrafficUsageMonthlyHistoryStart carries one command per full monthly
// usage history run, which writes the TDengine monthly table. It is distinct
// from QueueTrafficUsageMonthlyStart, which fills the MySQL current-month
// snapshot.
QueueTrafficUsageMonthlyHistoryStart = "iotlcm.traffic_usage.monthly_history.start"
QueueSimStatusQueueStart = "iotlcm.sim_status.queue.start"
QueueSimStatusQueueTask = "iotlcm.sim_status.queue.task"
QueueImeiQueueStart = "iotlcm.imei.queue.start"
QueueWorkOrderAutoClose = "iotlcm.work_order.auto_close"
QueueBalanceRechargeTimeout = "iotlcm.balance.recharge.timeout"
QueueBalanceRechargeDelay = "iotlcm.balance.recharge.delay"
QueueWorkerDiagnostic = "iotlcm.worker.diagnostic"
QueueBatchExecute = "iotlcm.batch.execute"
QueueBatchExecuteRetry = "iotlcm.batch.execute.retry"
QueueBatchExecuteDeadLetter = "iotlcm.batch.execute.dlq"
QueueBatchRestartResumeDelay = "iotlcm.batch.restart.resume.delay"
QueuePackageCustomerSync = "iotlcm.package_customer.sync"
QueueChannelRefresh = "iotlcm.channel.refresh"
// QueueBalanceRechargeDeadLetter 保存重试次数耗尽后仍失败的充值超时消息,
// 供人工排查(例如支付宝凭据未配置导致的永久失败),不再自动重投。
QueueBalanceRechargeDeadLetter = "iotlcm.balance.recharge.dlq"
)