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 model
// ChannelRefreshMessage requests an asynchronous refresh of channel instances.
// The payload is shared with admin-svr's publisher.
type ChannelRefreshMessage struct {
Type string `json:"type"`
ChanKey string `json:"chanKey,omitempty"`
TempKey string `json:"tempKey,omitempty"`
OldChanKey string `json:"oldChanKey,omitempty"`
NewChanKey string `json:"newChanKey,omitempty"`
}
+32
View File
@@ -0,0 +1,32 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// BatchDetail is the golang structure of table batch_detail for DAO operations like Where/Data.
type BatchDetail struct {
g.Meta `orm:"table:batch_detail, do:true"`
Id any // 主键ID
BatchNo any // 批次编号
BatchType any // 批次类型 枚举(与主表一致)
DetailStatus any // 明细异步处理状态 0-待处理 1-处理中 2-成功 3-失败
BlankOutStatus any // 作废状态 0-是 1-否
RowNo any // 行号
ItemId any // 项ID:卡ICCID/设备编码
ErrorCode any // 异常编码
ErrorReason any // 异常原因
Snapshot *gjson.Json // 信息快照
TenantId any // 租户ID
CreatedDept any // 创建部门ID
CreatedBy any // 创建者ID
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者ID
UpdatedAt *gtime.Time // 更新时间
}
+47
View File
@@ -0,0 +1,47 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// BatchMain is the golang structure of table batch_main for DAO operations like Where/Data.
type BatchMain struct {
g.Meta `orm:"table:batch_main, do:true"`
Id any // 主键ID
BatchNo any // 批次编号
OrderSn any // 订单编号
BatchType any // 批次类型 枚举
BatchStatus any // 批次状态 枚举
BatchAsyncStatus any // 异步处理状态
SourceType any // 来源方式 枚举
SourceBatchNo any // 来源批次编号
SourceOssId any // 源文件OSS ID
ResultOssId any // 结果文件OSS ID
IsCrossDept any // 是否跨级操作机构
TargetDeptId any // 目标机构编号
DeptId any // 机构编号
TotalCount any // 总数量
ValidCount any // 有效数量
SuccessCount any // 成功数量
FailCount any // 失败数量
RunResult any // 运行结果
FailReason any // 失败原因
BatchInfo *gjson.Json // 批次信息:入库/出库展示字段
Remark *gjson.Json // 备注扩展字段
StartTime *gtime.Time // 开始时间
EndTime *gtime.Time // 结束时间
TenantId any // 租户ID
CreatedDept any // 创建部门ID
CreatedBy any // 创建者ID
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者ID
UpdatedAt *gtime.Time // 更新时间
SourceChannel any // 发起渠道:console/mini_program/api/system/legacy
ExecutionMode any // 操作规模:0未知1单卡2批量
}
+39
View File
@@ -0,0 +1,39 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// SysDept is the golang structure of table sys_dept for DAO operations like Where/Data.
type SysDept struct {
g.Meta `orm:"table:sys_dept, do:true"`
DeptId any // 部门id
TenantId any // 租户编号
ParentId any // 父部门id
Ancestors any // 祖级列表
DeptKey any // 机构编号
DeptName any // 部门名称
DeptType any // 部门类型(0:部门 1:公司)
DeptCategory any // 部门类别编码
OrderNum any // 显示顺序
Leader any // 负责人
Phone any // 联系电话
Email any // 邮箱
Status any // 部门状态(0正常 1停用)
CreditCode any // 统一社会信用代码
AreaCode any // 行政区域代码
Address any // 地址
DeptRole any // 机构默认角色ID
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
DeletedBy any // 删除人
DeletedAt *gtime.Time // 删除时间
}
+32
View File
@@ -0,0 +1,32 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// SysOss is the golang structure of table sys_oss for DAO operations like Where/Data.
type SysOss struct {
g.Meta `orm:"table:sys_oss, do:true"`
OssId any // 对象存储主键
TenantId any // 租户编号
FileName any // 文件名
OriginalName any // 原名
FileSuffix any // 文件后缀名
Path any // 存储路径
Url any // URL地址
CreatedDept any // 创建部门
CreatedAt *gtime.Time // 创建时间
CreatedBy any // 创建者
UpdatedAt *gtime.Time // 更新时间
UpdatedBy any // 更新者
Service any // 服务商
Md5 any // 文件MD5
FileSize any // 文件大小
FileCrc16 any // 文件Crc16
FileSum any // 文件校验和
}
+31
View File
@@ -0,0 +1,31 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TMessageLog is the golang structure of table t_message_log for DAO operations like Where/Data.
type TMessageLog struct {
g.Meta `orm:"table:t_message_log, do:true"`
MessageLogId any // 主键ID
MessageType any // 消息类型
SendUserType any // 发送用户类型
UserIds *gjson.Json // 接收用户ID集合(JSON数组)
MessageTitle any // 消息标题
MessageContent any // 消息内容
MessageLink any // 跳转链接地址
SendTime *gtime.Time // 发送时间
IsRecall any // 是否撤回
TenantId any // 租户ID
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
}
@@ -0,0 +1,48 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TResourceBatchDownload is the golang structure of table t_resource_batch_download for DAO operations like Where/Data.
type TResourceBatchDownload struct {
g.Meta `orm:"table:t_resource_batch_download, do:true"`
Id any // 主键ID
BatchNo any // 批次编号(全局唯一)
TaskName any // 任务名称
ResourceType any // 资源类型 枚举
ExportScene any // 导出场景 枚举
QueryParams *gjson.Json // 导出查询条件快照
TotalCount any // 预计导出总条数
SuccessCount any // 已成功导出条数
FailCount any // 失败条数
DownloadStatus any // 下载状态 枚举
OssId any // OSS文件ID
FileName any // 导出文件名
FileExt any // 文件扩展名
FileUrl any // 文件访问地址
FilePath any // 服务器本地路径
FileSize any // 文件大小(字节)
FileMd5 any // 文件MD5
DownloadCount any // 下载次数
LastDownloadTime *gtime.Time // 最后下载时间
MaxDownloadCount any // 最大下载次数限制
ErrorMessage any // 失败原因
DeptId any // 所属机构ID
StartTime *gtime.Time // 任务开始时间
FinishTime *gtime.Time // 任务完成时间
ExpireTime *gtime.Time // 文件过期时间
Remark any // 备注
TenantId any // 租户ID
CreatedDept any // 创建部门ID
CreatedBy any // 创建者ID
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者ID
UpdatedAt *gtime.Time // 更新时间
}
@@ -0,0 +1,72 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TSimCardCancellation is the golang structure of table t_sim_card_cancellation for DAO operations like Where/Data.
type TSimCardCancellation struct {
g.Meta `orm:"table:t_sim_card_cancellation, do:true"`
Id any // 主键ID
Iccid any // ICCID
Msisdn any // MSISDN/卡号
Imsi any // IMSI
Imei any // IMEI
RegionCode any // 归属地
DeptId any // 渠道客户ID
CurrentPackageCode any // 当前套餐编号
PackageStatus any // 套餐状态:0 无套餐,1待生效,2生效中,3已过期
AccessType any // 接入方式:ipv4、ipv6、ipv4_ipv6
BossCardStatus any // 运营商卡状态 枚举
CancelBatchNo any // 系统销户批次号
CancelledAt *gtime.Time // 系统销户完成时间
CardType any // 卡类型 枚举
BossOpenAt *gtime.Time // 运营商开户日期
BossActivateAt *gtime.Time // 运营商激活日期
IsBossActivateEnabled any // 是否按运营商激活减去赠送时长方:1是,0否
InboundBatchNo any // 入库批次
OutboundBatchNo any // 出库批次
AllocationBatchNo any // 划拨批次
IsFlowPool any // 是否为池卡:1是,0否
FlowPoolCode any // 流量池编号
FlowPkgBeginAt *gtime.Time // 当前套餐生效时间
FlowPkgPresentAt *gtime.Time // 套餐赠送结束时间
FlowPkgRealPresentAt *gtime.Time // 实际赠送结束时间
FlowPkgEndAt *gtime.Time // 当前套餐预计到期时间
DataServiceStatus any // 数据服务状态:0启用,1停用
PackageTotalFlowMb any // 套餐总流量MB
UsedFlowMb any // 已用流量MB
TrafficCutoffStatus any // 达量断网配置状态:0未配置,1已开启,2已关闭
TrafficCutoffThreshold any // 达量断网阈值
SmsServiceStatus any // 短信服务状态:0启用,1停用
PackageTotalSms any // 套餐短信总条数
UsedSms any // 已用短信条数
VoiceServiceStatus any // 语音服务状态:0启用,1停用
PackageTotalVoice any // 套餐语音总分钟数
UsedVoice any // 已用语音分钟数
RoamServiceStatus any // 国漫服务状态:0启用,1停用
PackageTotalRoamFlowMb any // 套餐国际流量MB
UsedRoamFlowMb any // 已用国际流量MB
StatusSyncTime *gtime.Time // 状态最后一次同步时间
FlowSyncTime *gtime.Time // 流量最后一次同步时间
SmsSyncTime *gtime.Time // 短信最后一次同步时间
VoiceSyncTime *gtime.Time // 语音最后一次同步时间
RoamSyncTime *gtime.Time // 国漫最后一次同步时间
ExtraFeeEnabled any // 是否收取附加费:0是,1否
ExtraFeeMultiple any // 附加费用倍数
ExtraFee any // 附加金额
ChanKey any // 通道编号
NetModel any // 网络类型 枚举
Remark any // 备注
TenantId any // 租户ID
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
}
+73
View File
@@ -0,0 +1,73 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TSimCardInfo is the golang structure of table t_sim_card_info for DAO operations like Where/Data.
type TSimCardInfo struct {
g.Meta `orm:"table:t_sim_card_info, do:true"`
Id any // 主键ID
Iccid any // ICCID
Msisdn any // MSISDN/卡号
Imsi any // IMSI
Imei any // IMEI
RegionCode any // 归属地
DeptId any // 渠道客户ID
CurrentPackageCode any // 当前套餐编号
PackageStatus any // 套餐状态:0 无套餐,1待生效,2生效中,3已过期
AccessType any // 接入方式:ipv4、ipv6、ipv4_ipv6
BossCardStatus any // 运营商卡状态 枚举
CardType any // 卡类型 枚举
BossOpenAt *gtime.Time // 运营商开户日期
BossActivateAt *gtime.Time // 运营商激活日期
IsBossActivateEnabled any // 是否按运营商激活减去赠送时长方:1是,0否
InboundBatchNo any // 入库批次
OutboundBatchNo any // 出库批次
AllocationBatchNo any // 划拨批次
IsFlowPool any // 是否为池卡:1是,0否
FlowPoolCode any // 流量池编号
OutStockTime *gtime.Time // 出库时间
FlowPkgBeginAt *gtime.Time // 当前套餐生效时间
FlowPkgPresentAt *gtime.Time // 套餐赠送结束时间
FlowPkgRealPresentAt *gtime.Time // 实际赠送结束时间
FlowPkgEndAt *gtime.Time // 当前套餐预计到期时间
DataServiceStatus any // 数据服务状态:1启用、0禁用
PackageTotalFlowMb any // 套餐总流量MB
UsedFlowMb any // 已用流量MB
TrafficCutoffStatus any // 达量断网配置状态:0未配置,1已开启,2已关闭
TrafficCutoffThreshold any // 达量断网阈值
SmsServiceStatus any // 短信服务状态:1启用、0禁用
PackageTotalSms any // 套餐短信总条数
UsedSms any // 已用短信条数
VoiceServiceStatus any // 语音服务状态:1启用、0禁用
PackageTotalVoice any // 套餐语音总分钟数
UsedVoice any // 已用语音分钟数
RoamServiceStatus any // 国漫服务状态:1启用、0禁用
PackageTotalRoamFlowMb any // 套餐国际流量MB
UsedRoamFlowMb any // 已用国际流量MB
StatusSyncTime *gtime.Time // 状态最后一次同步时间
FlowSyncTime *gtime.Time // 流量最后一次同步时间
SmsSyncTime *gtime.Time // 短信最后一次同步时间
VoiceSyncTime *gtime.Time // 语音最后一次同步时间
RoamSyncTime *gtime.Time // 国漫最后一次同步时间
ImeiSyncTime *gtime.Time // IMEI 最后一次轮询同步时间
ImeiUpdateTime *gtime.Time // IMEI 值最后一次实际变更时间
ExtraFeeEnabled any // 是否收取附加费:1是,0否
ExtraFeeMultiple any // 附加费用倍数
ExtraFee any // 附加金额
ChanKey any // 通道编号
NetModel any // 网络类型:4G、5G、NB-IoT
Remark any // 备注
TenantId any // 租户ID
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
}
@@ -0,0 +1,15 @@
package do
import "github.com/gogf/gf/v2/frame/g"
// TSimCardTrafficCutoffConfig contains writable traffic-cutoff extension fields.
type TSimCardTrafficCutoffConfig struct {
g.Meta `orm:"table:t_sim_card_info, do:true"`
DataServiceStatus any `orm:"data_service_status"`
StatusSyncTime any `orm:"status_sync_time"`
TrafficCutoffStatus any `orm:"traffic_cutoff_status"`
TrafficCutoffThreshold any `orm:"traffic_cutoff_threshold"`
TrafficCutoffCrossMonthHold any `orm:"traffic_cutoff_cross_month_hold"`
TrafficCutoffTriggeredAt any `orm:"traffic_cutoff_triggered_at"`
UpdatedBy any `orm:"updated_by"`
}
@@ -0,0 +1,19 @@
package do
import (
"reflect"
"strings"
"testing"
)
func TestTSimCardTrafficCutoffConfigUsesDoMetadata(t *testing.T) {
modelType := reflect.TypeOf(TSimCardTrafficCutoffConfig{})
metaField, ok := modelType.FieldByName("Meta")
if !ok {
t.Fatal("TSimCardTrafficCutoffConfig must embed g.Meta")
}
ormTag := metaField.Tag.Get("orm")
if !strings.Contains(ormTag, "table:t_sim_card_info") || !strings.Contains(ormTag, "do:true") {
t.Fatalf("unexpected g.Meta orm tag: %q", ormTag)
}
}
+37
View File
@@ -0,0 +1,37 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TSimFlowPool is the golang structure of table t_sim_flow_pool for DAO operations like Where/Data.
type TSimFlowPool struct {
g.Meta `orm:"table:t_sim_flow_pool, do:true"`
Id any // 主键ID
FlowPoolCode any // 流量池编号
DeptId any // 客户编号
PackageCodes *gjson.Json // 套餐编号列表(冗余)
PoolPackageCode any // 池套餐编码
CardCount any // 关联卡数量
CardFlowMb any // 套餐卡流量MB
PoolPackageFlowMb any // 套内总流量MB
AddOnFlowMb any // 加油包总流量MB
TotalFlowMb any // 总流量MB(套内+加油包)
UsedFlowMb any // 已使用流量MB
RemainFlowMb any // 剩余流量MB
LastStatTime *gtime.Time // 最后流量统计时间
PoolStatus any // 状态:0 正常、1 停用、2 锁定
Remark any // 备注
TenantId any // 租户ID
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
}
+25
View File
@@ -0,0 +1,25 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TUserMessage is the golang structure of table t_user_message for DAO operations like Where/Data.
type TUserMessage struct {
g.Meta `orm:"table:t_user_message, do:true"`
MessageId any // 主键ID
MessageLogId any // 消息日志ID
UserId any // 用户ID
IsRead any // 是否已读
TenantId any // 租户ID
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
}
+38
View File
@@ -0,0 +1,38 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TWarnConfig is the golang structure of table t_warn_config for DAO operations like Where/Data.
type TWarnConfig struct {
g.Meta `orm:"table:t_warn_config, do:true"`
Id any // 主键ID
TenantId any // 租户ID
BatchNo any // 批次编号
ItemType any // 对象类型:1卡,2流量池
ItemId any // 对象ID:单卡为t_sim_card_info.id,流量池为t_sim_flow_pool.id
ItemCode any // 对象编码快照:ICCID/MSISDN/流量池编码
WarnUnit any // 预警单位:1MB,2百分比,3天数,4月数
FirstWarn any // 第一档预警阈值,单位由warn_unit决定
SecondWarn any // 第二档预警阈值,单位由warn_unit决定
ThirdWarn any // 第三档预警阈值,单位由warn_unit决定
WarnMethods any // 预警方式:0短信,1邮箱,2电话,3平台消息;多选逗号分隔
WarnPhones any // 预警手机号,多个逗号分隔
WarnEmails any // 预警邮箱,多个逗号分隔
AutoAction any // 自动动作:0无,2断网;第一期只保存配置不自动执行
IsEnabled any // 是否启用:1启用,0停用
WxTemplateId any // 微信订阅消息模板ID
Remark any // 备注
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
AppNotifyEnabled any // 是否开启小程序预警通知:0关闭,1开启
}
+39
View File
@@ -0,0 +1,39 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TWarnLog is the golang structure of table t_warn_log for DAO operations like Where/Data.
type TWarnLog struct {
g.Meta `orm:"table:t_warn_log, do:true"`
Id any // 主键ID
TenantId any // 租户ID
ConfigId any // 预警配置ID
ItemType any // 对象类型:1单卡,2流量池
ItemId any // 对象ID:单卡为t_sim_card_info.id,流量池为t_sim_flow_pool.id
ItemCode any // 对象编码快照:ICCID/MSISDN/流量池编码
WarnStage any // 触发档位:1第一档,2第二档,3第三档
WarnLevel any // 预警级别:1提示,2注意,3警告,4危险,5紧急
WarnUnit any // 预警单位/维度:1MB,2百分比,3天数,4月数
ThresholdValue any // 触发阈值,单位由warn_unit决定
ActualValue any // 触发时实际值,单位由warn_unit决定
TotalFlowMb any // 触发时总流量MB;流量类预警使用
RemainFlowMb any // 触发时剩余流量MB;流量类预警使用
WarnMethods any // 实际预警方式快照
WarnPhones any // 实际预警手机号快照
WarnEmails any // 实际预警邮箱快照
MessageLogId any // 平台消息ID;聚合通知时可能为空
WarnTime *gtime.Time // 预警时间
Remark any // 备注
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
}
+45
View File
@@ -0,0 +1,45 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TWoMain is the golang structure of table t_wo_main for DAO operations like Where/Data.
type TWoMain struct {
g.Meta `orm:"table:t_wo_main, do:true"`
Id any // 主键ID
WoNo any // 工单编号
WoType any // 工单类型 0卡,1模组,2设备,3订单,4余额,5提现
RelatedId any // 关联业务ID
Title any // 工单标题
Content any // 问题描述
Attachment any // 附件
CreatorType any // 创建人类型:1终端用户,2代理商
CreatorDeptId any // 创建机构ID
CreatorUserId any // 创建用户ID
CreatorName any // 创建人姓名
CreatorPhone any // 创建人手机号
AssignDeptId any // 分派方机构ID
AssignUserId any // 分派人用户ID
CurrentStatus any // 当前处理状态:1已分派,2处理中,3已解决,4已完结_关单,5已取消
HandlerDeptId any // 处理方机构ID
HandlerUserId any // 处理人用户ID
FirstResponseTime *gtime.Time // 首次响应时间
ResolveTime *gtime.Time // 确认时间
CloseTime *gtime.Time // 关闭时间
SatisfactionLevel any // 满意度:1-5分
EvalContent any // 评价内容
EvalTime *gtime.Time // 评价时间
Remark any // 备注
TenantId any // 租户ID
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
}
+30
View File
@@ -0,0 +1,30 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// TWoRecord is the golang structure of table t_wo_record for DAO operations like Where/Data.
type TWoRecord struct {
g.Meta `orm:"table:t_wo_record, do:true"`
Id any // 主键ID
WoNo any // 工单编号
OperationType any // 操作类型:0创建,1分派,2处理,3完成,4关单,5取消
OperationDeptId any // 操作机构ID
OperationUserId any // 操作用户ID
TargetDeptId any // 目标部门ID
TargetUserId any // 目标用户ID
BeforeStatus any // 变更前状态
AfterStatus any // 变更后状态
TenantId any // 租户ID
CreatedDept any // 创建部门
CreatedBy any // 创建者
CreatedAt *gtime.Time // 创建时间
UpdatedBy any // 更新者
UpdatedAt *gtime.Time // 更新时间
}
+30
View File
@@ -0,0 +1,30 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gtime"
)
// BatchDetail is the golang structure for table batch_detail.
type BatchDetail struct {
Id int64 `json:"id" orm:"id" description:"主键ID"`
BatchNo string `json:"batchNo" orm:"batch_no" description:"批次编号"`
BatchType int `json:"batchType" orm:"batch_type" description:"批次类型 枚举(与主表一致)"`
DetailStatus int `json:"detailStatus" orm:"detail_status" description:"明细异步处理状态 0-待处理 1-处理中 2-成功 3-失败"`
BlankOutStatus int `json:"blankOutStatus" orm:"blank_out_status" description:"作废状态 0-是 1-否"`
RowNo int `json:"rowNo" orm:"row_no" description:"行号"`
ItemId string `json:"itemId" orm:"item_id" description:"项ID:卡ICCID/设备编码"`
ErrorCode string `json:"errorCode" orm:"error_code" description:"异常编码"`
ErrorReason string `json:"errorReason" orm:"error_reason" description:"异常原因"`
Snapshot *gjson.Json `json:"snapshot" orm:"snapshot" description:"信息快照"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门ID"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者ID"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者ID"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
}
+45
View File
@@ -0,0 +1,45 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gtime"
)
// BatchMain is the golang structure for table batch_main.
type BatchMain struct {
Id int64 `json:"id" orm:"id" description:"主键ID"`
BatchNo string `json:"batchNo" orm:"batch_no" description:"批次编号"`
OrderSn string `json:"orderSn" orm:"order_sn" description:"订单编号"`
BatchType int `json:"batchType" orm:"batch_type" description:"批次类型 枚举"`
BatchStatus int `json:"batchStatus" orm:"batch_status" description:"批次状态 枚举"`
BatchAsyncStatus int `json:"batchAsyncStatus" orm:"batch_async_status" description:"异步处理状态"`
SourceType int `json:"sourceType" orm:"source_type" description:"来源方式 枚举"`
SourceBatchNo string `json:"sourceBatchNo" orm:"source_batch_no" description:"来源批次编号"`
SourceOssId int64 `json:"sourceOssId" orm:"source_oss_id" description:"源文件OSS ID"`
ResultOssId int64 `json:"resultOssId" orm:"result_oss_id" description:"结果文件OSS ID"`
IsCrossDept int `json:"isCrossDept" orm:"is_cross_dept" description:"是否跨级操作机构"`
TargetDeptId int64 `json:"targetDeptId" orm:"target_dept_id" description:"目标机构编号"`
DeptId int64 `json:"deptId" orm:"dept_id" description:"机构编号"`
TotalCount int `json:"totalCount" orm:"total_count" description:"总数量"`
ValidCount int `json:"validCount" orm:"valid_count" description:"有效数量"`
SuccessCount int `json:"successCount" orm:"success_count" description:"成功数量"`
FailCount int `json:"failCount" orm:"fail_count" description:"失败数量"`
RunResult int `json:"runResult" orm:"run_result" description:"运行结果"`
FailReason string `json:"failReason" orm:"fail_reason" description:"失败原因"`
BatchInfo *gjson.Json `json:"batchInfo" orm:"batch_info" description:"批次信息:入库/出库展示字段"`
Remark *gjson.Json `json:"remark" orm:"remark" description:"备注扩展字段"`
StartTime *gtime.Time `json:"startTime" orm:"start_time" description:"开始时间"`
EndTime *gtime.Time `json:"endTime" orm:"end_time" description:"结束时间"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门ID"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者ID"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者ID"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
SourceChannel string `json:"sourceChannel" orm:"source_channel" description:"发起渠道:console/mini_program/api/system/legacy"`
ExecutionMode uint `json:"executionMode" orm:"execution_mode" description:"操作规模:0未知1单卡2批量"`
}
+37
View File
@@ -0,0 +1,37 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// SysDept is the golang structure for table sys_dept.
type SysDept struct {
DeptId int64 `json:"deptId" orm:"dept_id" description:"部门id"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户编号"`
ParentId int64 `json:"parentId" orm:"parent_id" description:"父部门id"`
Ancestors string `json:"ancestors" orm:"ancestors" description:"祖级列表"`
DeptKey string `json:"deptKey" orm:"dept_key" description:"机构编号"`
DeptName string `json:"deptName" orm:"dept_name" description:"部门名称"`
DeptType int `json:"deptType" orm:"dept_type" description:"部门类型(0:部门 1:公司)"`
DeptCategory string `json:"deptCategory" orm:"dept_category" description:"部门类别编码"`
OrderNum int `json:"orderNum" orm:"order_num" description:"显示顺序"`
Leader int64 `json:"leader" orm:"leader" description:"负责人"`
Phone string `json:"phone" orm:"phone" description:"联系电话"`
Email string `json:"email" orm:"email" description:"邮箱"`
Status string `json:"status" orm:"status" description:"部门状态(0正常 1停用)"`
CreditCode string `json:"creditCode" orm:"credit_code" description:"统一社会信用代码"`
AreaCode string `json:"areaCode" orm:"area_code" description:"行政区域代码"`
Address string `json:"address" orm:"address" description:"地址"`
DeptRole int64 `json:"deptRole" orm:"dept_role" description:"机构默认角色ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:"删除人"`
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"删除时间"`
}
+30
View File
@@ -0,0 +1,30 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// SysOss is the golang structure for table sys_oss.
type SysOss struct {
OssId int64 `json:"ossId" orm:"oss_id" description:"对象存储主键"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户编号"`
FileName string `json:"fileName" orm:"file_name" description:"文件名"`
OriginalName string `json:"originalName" orm:"original_name" description:"原名"`
FileSuffix string `json:"fileSuffix" orm:"file_suffix" description:"文件后缀名"`
Path string `json:"path" orm:"path" description:"存储路径"`
Url string `json:"url" orm:"url" description:"URL地址"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
Service string `json:"service" orm:"service" description:"服务商"`
Md5 string `json:"md5" orm:"md5" description:"文件MD5"`
FileSize int `json:"fileSize" orm:"file_size" description:"文件大小"`
FileCrc16 int `json:"fileCrc16" orm:"file_crc16" description:"文件Crc16"`
FileSum int `json:"fileSum" orm:"file_sum" description:"文件校验和"`
}
+29
View File
@@ -0,0 +1,29 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gtime"
)
// TMessageLog is the golang structure for table t_message_log.
type TMessageLog struct {
MessageLogId uint64 `json:"messageLogId" orm:"message_log_id" description:"主键ID"`
MessageType uint `json:"messageType" orm:"message_type" description:"消息类型"`
SendUserType uint `json:"sendUserType" orm:"send_user_type" description:"发送用户类型"`
UserIds *gjson.Json `json:"userIds" orm:"user_ids" description:"接收用户ID集合(JSON数组)"`
MessageTitle string `json:"messageTitle" orm:"message_title" description:"消息标题"`
MessageContent string `json:"messageContent" orm:"message_content" description:"消息内容"`
MessageLink string `json:"messageLink" orm:"message_link" description:"跳转链接地址"`
SendTime *gtime.Time `json:"sendTime" orm:"send_time" description:"发送时间"`
IsRecall uint `json:"isRecall" orm:"is_recall" description:"是否撤回"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
}
@@ -0,0 +1,46 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gtime"
)
// TResourceBatchDownload is the golang structure for table t_resource_batch_download.
type TResourceBatchDownload struct {
Id int64 `json:"id" orm:"id" description:"主键ID"`
BatchNo string `json:"batchNo" orm:"batch_no" description:"批次编号(全局唯一)"`
TaskName string `json:"taskName" orm:"task_name" description:"任务名称"`
ResourceType int `json:"resourceType" orm:"resource_type" description:"资源类型 枚举"`
ExportScene int `json:"exportScene" orm:"export_scene" description:"导出场景 枚举"`
QueryParams *gjson.Json `json:"queryParams" orm:"query_params" description:"导出查询条件快照"`
TotalCount int `json:"totalCount" orm:"total_count" description:"预计导出总条数"`
SuccessCount int `json:"successCount" orm:"success_count" description:"已成功导出条数"`
FailCount int `json:"failCount" orm:"fail_count" description:"失败条数"`
DownloadStatus int `json:"downloadStatus" orm:"download_status" description:"下载状态 枚举"`
OssId int64 `json:"ossId" orm:"oss_id" description:"OSS文件ID"`
FileName string `json:"fileName" orm:"file_name" description:"导出文件名"`
FileExt string `json:"fileExt" orm:"file_ext" description:"文件扩展名"`
FileUrl string `json:"fileUrl" orm:"file_url" description:"文件访问地址"`
FilePath string `json:"filePath" orm:"file_path" description:"服务器本地路径"`
FileSize int64 `json:"fileSize" orm:"file_size" description:"文件大小(字节)"`
FileMd5 string `json:"fileMd5" orm:"file_md5" description:"文件MD5"`
DownloadCount int `json:"downloadCount" orm:"download_count" description:"下载次数"`
LastDownloadTime *gtime.Time `json:"lastDownloadTime" orm:"last_download_time" description:"最后下载时间"`
MaxDownloadCount int `json:"maxDownloadCount" orm:"max_download_count" description:"最大下载次数限制"`
ErrorMessage string `json:"errorMessage" orm:"error_message" description:"失败原因"`
DeptId int64 `json:"deptId" orm:"dept_id" description:"所属机构ID"`
StartTime *gtime.Time `json:"startTime" orm:"start_time" description:"任务开始时间"`
FinishTime *gtime.Time `json:"finishTime" orm:"finish_time" description:"任务完成时间"`
ExpireTime *gtime.Time `json:"expireTime" orm:"expire_time" description:"文件过期时间"`
Remark string `json:"remark" orm:"remark" description:"备注"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门ID"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者ID"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者ID"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
}
@@ -0,0 +1,70 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// TSimCardCancellation is the golang structure for table t_sim_card_cancellation.
type TSimCardCancellation struct {
Id int64 `json:"id" orm:"id" ` // 主键ID
Iccid string `json:"iccid" orm:"iccid" ` // ICCID
Msisdn string `json:"msisdn" orm:"msisdn" ` // MSISDN/卡号
Imsi string `json:"imsi" orm:"imsi" ` // IMSI
Imei string `json:"imei" orm:"imei" ` // IMEI
RegionCode string `json:"regionCode" orm:"region_code" ` // 归属地
DeptId int64 `json:"deptId" orm:"dept_id" ` // 渠道客户ID
CurrentPackageCode string `json:"currentPackageCode" orm:"current_package_code" ` // 当前套餐编号
PackageStatus int `json:"packageStatus" orm:"package_status" ` // 套餐状态:0 无套餐,1待生效,2生效中,3已过期
AccessType int `json:"accessType" orm:"access_type" ` // 接入方式:ipv4、ipv6、ipv4_ipv6
BossCardStatus int `json:"bossCardStatus" orm:"boss_card_status" ` // 运营商卡状态 枚举
CancelBatchNo string `json:"cancelBatchNo" orm:"cancel_batch_no" ` // 系统销户批次号
CancelledAt *gtime.Time `json:"cancelledAt" orm:"cancelled_at" ` // 系统销户完成时间
CardType int `json:"cardType" orm:"card_type" ` // 卡类型 枚举
BossOpenAt *gtime.Time `json:"bossOpenAt" orm:"boss_open_at" ` // 运营商开户日期
BossActivateAt *gtime.Time `json:"bossActivateAt" orm:"boss_activate_at" ` // 运营商激活日期
IsBossActivateEnabled int `json:"isBossActivateEnabled" orm:"is_boss_activate_enabled" ` // 是否按运营商激活减去赠送时长方:1是,0否
InboundBatchNo string `json:"inboundBatchNo" orm:"inbound_batch_no" ` // 入库批次
OutboundBatchNo string `json:"outboundBatchNo" orm:"outbound_batch_no" ` // 出库批次
AllocationBatchNo string `json:"allocationBatchNo" orm:"allocation_batch_no" ` // 划拨批次
IsFlowPool int `json:"isFlowPool" orm:"is_flow_pool" ` // 是否为池卡:1是,0否
FlowPoolCode string `json:"flowPoolCode" orm:"flow_pool_code" ` // 流量池编号
FlowPkgBeginAt *gtime.Time `json:"flowPkgBeginAt" orm:"flow_pkg_begin_at" ` // 当前套餐生效时间
FlowPkgPresentAt *gtime.Time `json:"flowPkgPresentAt" orm:"flow_pkg_present_at" ` // 套餐赠送结束时间
FlowPkgRealPresentAt *gtime.Time `json:"flowPkgRealPresentAt" orm:"flow_pkg_real_present_at" ` // 实际赠送结束时间
FlowPkgEndAt *gtime.Time `json:"flowPkgEndAt" orm:"flow_pkg_end_at" ` // 当前套餐预计到期时间
DataServiceStatus int `json:"dataServiceStatus" orm:"data_service_status" ` // 数据服务状态:0启用,1停用
PackageTotalFlowMb float64 `json:"packageTotalFlowMb" orm:"package_total_flow_mb" ` // 套餐总流量MB
UsedFlowMb float64 `json:"usedFlowMb" orm:"used_flow_mb" ` // 已用流量MB
TrafficCutoffStatus int `json:"trafficCutoffStatus" orm:"traffic_cutoff_status" ` // 达量断网配置状态:0未配置,1已开启,2已关闭
TrafficCutoffThreshold float64 `json:"trafficCutoffThreshold" orm:"traffic_cutoff_threshold" ` // 达量断网阈值
SmsServiceStatus int `json:"smsServiceStatus" orm:"sms_service_status" ` // 短信服务状态:0启用,1停用
PackageTotalSms int `json:"packageTotalSms" orm:"package_total_sms" ` // 套餐短信总条数
UsedSms int `json:"usedSms" orm:"used_sms" ` // 已用短信条数
VoiceServiceStatus int `json:"voiceServiceStatus" orm:"voice_service_status" ` // 语音服务状态:0启用,1停用
PackageTotalVoice int `json:"packageTotalVoice" orm:"package_total_voice" ` // 套餐语音总分钟数
UsedVoice int `json:"usedVoice" orm:"used_voice" ` // 已用语音分钟数
RoamServiceStatus int `json:"roamServiceStatus" orm:"roam_service_status" ` // 国漫服务状态:0启用,1停用
PackageTotalRoamFlowMb float64 `json:"packageTotalRoamFlowMb" orm:"package_total_roam_flow_mb" ` // 套餐国际流量MB
UsedRoamFlowMb float64 `json:"usedRoamFlowMb" orm:"used_roam_flow_mb" ` // 已用国际流量MB
StatusSyncTime *gtime.Time `json:"statusSyncTime" orm:"status_sync_time" ` // 状态最后一次同步时间
FlowSyncTime *gtime.Time `json:"flowSyncTime" orm:"flow_sync_time" ` // 流量最后一次同步时间
SmsSyncTime *gtime.Time `json:"smsSyncTime" orm:"sms_sync_time" ` // 短信最后一次同步时间
VoiceSyncTime *gtime.Time `json:"voiceSyncTime" orm:"voice_sync_time" ` // 语音最后一次同步时间
RoamSyncTime *gtime.Time `json:"roamSyncTime" orm:"roam_sync_time" ` // 国漫最后一次同步时间
ExtraFeeEnabled int `json:"extraFeeEnabled" orm:"extra_fee_enabled" ` // 是否收取附加费:0是,1否
ExtraFeeMultiple float64 `json:"extraFeeMultiple" orm:"extra_fee_multiple" ` // 附加费用倍数
ExtraFee float64 `json:"extraFee" orm:"extra_fee" ` // 附加金额
ChanKey string `json:"chanKey" orm:"chan_key" ` // 通道编号
NetModel int `json:"netModel" orm:"net_model" ` // 网络类型 枚举
Remark string `json:"remark" orm:"remark" ` // 备注
TenantId string `json:"tenantId" orm:"tenant_id" ` // 租户ID
CreatedDept int64 `json:"createdDept" orm:"created_dept" ` // 创建部门
CreatedBy int64 `json:"createdBy" orm:"created_by" ` // 创建者
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" ` // 创建时间
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" ` // 更新者
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" ` // 更新时间
}
+71
View File
@@ -0,0 +1,71 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// TSimCardInfo is the golang structure for table t_sim_card_info.
type TSimCardInfo struct {
Id int64 `json:"id" orm:"id" description:"主键ID"`
Iccid string `json:"iccid" orm:"iccid" description:"ICCID"`
Msisdn string `json:"msisdn" orm:"msisdn" description:"MSISDN/卡号"`
Imsi string `json:"imsi" orm:"imsi" description:"IMSI"`
Imei string `json:"imei" orm:"imei" description:"IMEI"`
RegionCode string `json:"regionCode" orm:"region_code" description:"归属地"`
DeptId int64 `json:"deptId" orm:"dept_id" description:"渠道客户ID"`
CurrentPackageCode string `json:"currentPackageCode" orm:"current_package_code" description:"当前套餐编号"`
PackageStatus int `json:"packageStatus" orm:"package_status" description:"套餐状态:0 无套餐,1待生效,2生效中,3已过期"`
AccessType int `json:"accessType" orm:"access_type" description:"接入方式:ipv4、ipv6、ipv4_ipv6"`
BossCardStatus int `json:"bossCardStatus" orm:"boss_card_status" description:"运营商卡状态 枚举"`
CardType int `json:"cardType" orm:"card_type" description:"卡类型 枚举"`
BossOpenAt *gtime.Time `json:"bossOpenAt" orm:"boss_open_at" description:"运营商开户日期"`
BossActivateAt *gtime.Time `json:"bossActivateAt" orm:"boss_activate_at" description:"运营商激活日期"`
IsBossActivateEnabled int `json:"isBossActivateEnabled" orm:"is_boss_activate_enabled" description:"是否按运营商激活减去赠送时长方:1是,0否"`
InboundBatchNo string `json:"inboundBatchNo" orm:"inbound_batch_no" description:"入库批次"`
OutboundBatchNo string `json:"outboundBatchNo" orm:"outbound_batch_no" description:"出库批次"`
AllocationBatchNo string `json:"allocationBatchNo" orm:"allocation_batch_no" description:"划拨批次"`
IsFlowPool int `json:"isFlowPool" orm:"is_flow_pool" description:"是否为池卡:1是,0否"`
FlowPoolCode string `json:"flowPoolCode" orm:"flow_pool_code" description:"流量池编号"`
OutStockTime *gtime.Time `json:"outStockTime" orm:"out_stock_time" description:"出库时间"`
FlowPkgBeginAt *gtime.Time `json:"flowPkgBeginAt" orm:"flow_pkg_begin_at" description:"当前套餐生效时间"`
FlowPkgPresentAt *gtime.Time `json:"flowPkgPresentAt" orm:"flow_pkg_present_at" description:"套餐赠送结束时间"`
FlowPkgRealPresentAt *gtime.Time `json:"flowPkgRealPresentAt" orm:"flow_pkg_real_present_at" description:"实际赠送结束时间"`
FlowPkgEndAt *gtime.Time `json:"flowPkgEndAt" orm:"flow_pkg_end_at" description:"当前套餐预计到期时间"`
DataServiceStatus int `json:"dataServiceStatus" orm:"data_service_status" description:"数据服务状态:1启用、0禁用"`
PackageTotalFlowMb float64 `json:"packageTotalFlowMb" orm:"package_total_flow_mb" description:"套餐总流量MB"`
UsedFlowMb float64 `json:"usedFlowMb" orm:"used_flow_mb" description:"已用流量MB"`
TrafficCutoffStatus int `json:"trafficCutoffStatus" orm:"traffic_cutoff_status" description:"达量断网配置状态:0未配置,1已开启,2已关闭"`
TrafficCutoffThreshold float64 `json:"trafficCutoffThreshold" orm:"traffic_cutoff_threshold" description:"达量断网阈值"`
SmsServiceStatus int `json:"smsServiceStatus" orm:"sms_service_status" description:"短信服务状态:1启用、0禁用"`
PackageTotalSms int `json:"packageTotalSms" orm:"package_total_sms" description:"套餐短信总条数"`
UsedSms int `json:"usedSms" orm:"used_sms" description:"已用短信条数"`
VoiceServiceStatus int `json:"voiceServiceStatus" orm:"voice_service_status" description:"语音服务状态:1启用、0禁用"`
PackageTotalVoice int `json:"packageTotalVoice" orm:"package_total_voice" description:"套餐语音总分钟数"`
UsedVoice int `json:"usedVoice" orm:"used_voice" description:"已用语音分钟数"`
RoamServiceStatus int `json:"roamServiceStatus" orm:"roam_service_status" description:"国漫服务状态:1启用、0禁用"`
PackageTotalRoamFlowMb float64 `json:"packageTotalRoamFlowMb" orm:"package_total_roam_flow_mb" description:"套餐国际流量MB"`
UsedRoamFlowMb float64 `json:"usedRoamFlowMb" orm:"used_roam_flow_mb" description:"已用国际流量MB"`
StatusSyncTime *gtime.Time `json:"statusSyncTime" orm:"status_sync_time" description:"状态最后一次同步时间"`
FlowSyncTime *gtime.Time `json:"flowSyncTime" orm:"flow_sync_time" description:"流量最后一次同步时间"`
SmsSyncTime *gtime.Time `json:"smsSyncTime" orm:"sms_sync_time" description:"短信最后一次同步时间"`
VoiceSyncTime *gtime.Time `json:"voiceSyncTime" orm:"voice_sync_time" description:"语音最后一次同步时间"`
RoamSyncTime *gtime.Time `json:"roamSyncTime" orm:"roam_sync_time" description:"国漫最后一次同步时间"`
ImeiSyncTime *gtime.Time `json:"imeiSyncTime" orm:"imei_sync_time" description:"IMEI 最后一次轮询同步时间"`
ImeiUpdateTime *gtime.Time `json:"imeiUpdateTime" orm:"imei_update_time" description:"IMEI 值最后一次实际变更时间"`
ExtraFeeEnabled int `json:"extraFeeEnabled" orm:"extra_fee_enabled" description:"是否收取附加费:1是,0否"`
ExtraFeeMultiple float64 `json:"extraFeeMultiple" orm:"extra_fee_multiple" description:"附加费用倍数"`
ExtraFee float64 `json:"extraFee" orm:"extra_fee" description:"附加金额"`
ChanKey string `json:"chanKey" orm:"chan_key" description:"通道编号"`
NetModel int `json:"netModel" orm:"net_model" description:"网络类型:4G、5G、NB-IoT"`
Remark string `json:"remark" orm:"remark" description:"备注"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
}
+35
View File
@@ -0,0 +1,35 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gtime"
)
// TSimFlowPool is the golang structure for table t_sim_flow_pool.
type TSimFlowPool struct {
Id int64 `json:"id" orm:"id" description:"主键ID"`
FlowPoolCode string `json:"flowPoolCode" orm:"flow_pool_code" description:"流量池编号"`
DeptId int64 `json:"deptId" orm:"dept_id" description:"客户编号"`
PackageCodes *gjson.Json `json:"packageCodes" orm:"package_codes" description:"套餐编号列表(冗余)"`
PoolPackageCode string `json:"poolPackageCode" orm:"pool_package_code" description:"池套餐编码"`
CardCount int64 `json:"cardCount" orm:"card_count" description:"关联卡数量"`
CardFlowMb float64 `json:"cardFlowMb" orm:"card_flow_mb" description:"套餐卡流量MB"`
PoolPackageFlowMb float64 `json:"poolPackageFlowMb" orm:"pool_package_flow_mb" description:"套内总流量MB"`
AddOnFlowMb float64 `json:"addOnFlowMb" orm:"add_on_flow_mb" description:"加油包总流量MB"`
TotalFlowMb float64 `json:"totalFlowMb" orm:"total_flow_mb" description:"总流量MB(套内+加油包)"`
UsedFlowMb float64 `json:"usedFlowMb" orm:"used_flow_mb" description:"已使用流量MB"`
RemainFlowMb float64 `json:"remainFlowMb" orm:"remain_flow_mb" description:"剩余流量MB"`
LastStatTime *gtime.Time `json:"lastStatTime" orm:"last_stat_time" description:"最后流量统计时间"`
PoolStatus int `json:"poolStatus" orm:"pool_status" description:"状态:0 正常、1 停用、2 锁定"`
Remark string `json:"remark" orm:"remark" description:"备注"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
}
+23
View File
@@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// TUserMessage is the golang structure for table t_user_message.
type TUserMessage struct {
MessageId uint64 `json:"messageId" orm:"message_id" description:"主键ID"`
MessageLogId uint64 `json:"messageLogId" orm:"message_log_id" description:"消息日志ID"`
UserId uint64 `json:"userId" orm:"user_id" description:"用户ID"`
IsRead uint `json:"isRead" orm:"is_read" description:"是否已读"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
}
+36
View File
@@ -0,0 +1,36 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// TWarnConfig is the golang structure for table t_warn_config.
type TWarnConfig struct {
Id int64 `json:"id" orm:"id" description:"主键ID"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
BatchNo string `json:"batchNo" orm:"batch_no" description:"批次编号"`
ItemType int `json:"itemType" orm:"item_type" description:"对象类型:1卡,2流量池"`
ItemId int64 `json:"itemId" orm:"item_id" description:"对象ID:单卡为t_sim_card_info.id,流量池为t_sim_flow_pool.id"`
ItemCode string `json:"itemCode" orm:"item_code" description:"对象编码快照:ICCID/MSISDN/流量池编码"`
WarnUnit int `json:"warnUnit" orm:"warn_unit" description:"预警单位:1MB,2百分比,3天数,4月数"`
FirstWarn float64 `json:"firstWarn" orm:"first_warn" description:"第一档预警阈值,单位由warn_unit决定"`
SecondWarn float64 `json:"secondWarn" orm:"second_warn" description:"第二档预警阈值,单位由warn_unit决定"`
ThirdWarn float64 `json:"thirdWarn" orm:"third_warn" description:"第三档预警阈值,单位由warn_unit决定"`
WarnMethods string `json:"warnMethods" orm:"warn_methods" description:"预警方式:0短信,1邮箱,2电话,3平台消息;多选逗号分隔"`
WarnPhones string `json:"warnPhones" orm:"warn_phones" description:"预警手机号,多个逗号分隔"`
WarnEmails string `json:"warnEmails" orm:"warn_emails" description:"预警邮箱,多个逗号分隔"`
AutoAction int `json:"autoAction" orm:"auto_action" description:"自动动作:0无,2断网;第一期只保存配置不自动执行"`
IsEnabled int `json:"isEnabled" orm:"is_enabled" description:"是否启用:1启用,0停用"`
WxTemplateId string `json:"wxTemplateId" orm:"wx_template_id" description:"微信订阅消息模板ID"`
Remark string `json:"remark" orm:"remark" description:"备注"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
AppNotifyEnabled int `json:"appNotifyEnabled" orm:"app_notify_enabled" description:"是否开启小程序预警通知:0关闭,1开启"`
}
+37
View File
@@ -0,0 +1,37 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// TWarnLog is the golang structure for table t_warn_log.
type TWarnLog struct {
Id int64 `json:"id" orm:"id" description:"主键ID"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
ConfigId int64 `json:"configId" orm:"config_id" description:"预警配置ID"`
ItemType int `json:"itemType" orm:"item_type" description:"对象类型:1单卡,2流量池"`
ItemId int64 `json:"itemId" orm:"item_id" description:"对象ID:单卡为t_sim_card_info.id,流量池为t_sim_flow_pool.id"`
ItemCode string `json:"itemCode" orm:"item_code" description:"对象编码快照:ICCID/MSISDN/流量池编码"`
WarnStage int `json:"warnStage" orm:"warn_stage" description:"触发档位:1第一档,2第二档,3第三档"`
WarnLevel int `json:"warnLevel" orm:"warn_level" description:"预警级别:1提示,2注意,3警告,4危险,5紧急"`
WarnUnit int `json:"warnUnit" orm:"warn_unit" description:"预警单位/维度:1MB,2百分比,3天数,4月数"`
ThresholdValue float64 `json:"thresholdValue" orm:"threshold_value" description:"触发阈值,单位由warn_unit决定"`
ActualValue float64 `json:"actualValue" orm:"actual_value" description:"触发时实际值,单位由warn_unit决定"`
TotalFlowMb float64 `json:"totalFlowMb" orm:"total_flow_mb" description:"触发时总流量MB;流量类预警使用"`
RemainFlowMb float64 `json:"remainFlowMb" orm:"remain_flow_mb" description:"触发时剩余流量MB;流量类预警使用"`
WarnMethods string `json:"warnMethods" orm:"warn_methods" description:"实际预警方式快照"`
WarnPhones string `json:"warnPhones" orm:"warn_phones" description:"实际预警手机号快照"`
WarnEmails string `json:"warnEmails" orm:"warn_emails" description:"实际预警邮箱快照"`
MessageLogId int64 `json:"messageLogId" orm:"message_log_id" description:"平台消息ID;聚合通知时可能为空"`
WarnTime *gtime.Time `json:"warnTime" orm:"warn_time" description:"预警时间"`
Remark string `json:"remark" orm:"remark" description:"备注"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
}
+43
View File
@@ -0,0 +1,43 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// TWoMain is the golang structure for table t_wo_main.
type TWoMain struct {
Id int64 `json:"id" orm:"id" description:"主键ID"`
WoNo string `json:"woNo" orm:"wo_no" description:"工单编号"`
WoType int `json:"woType" orm:"wo_type" description:"工单类型 0卡,1模组,2设备,3订单,4余额,5提现"`
RelatedId int64 `json:"relatedId" orm:"related_id" description:"关联业务ID"`
Title string `json:"title" orm:"title" description:"工单标题"`
Content string `json:"content" orm:"content" description:"问题描述"`
Attachment string `json:"attachment" orm:"attachment" description:"附件"`
CreatorType int `json:"creatorType" orm:"creator_type" description:"创建人类型:1终端用户,2代理商"`
CreatorDeptId int64 `json:"creatorDeptId" orm:"creator_dept_id" description:"创建机构ID"`
CreatorUserId int64 `json:"creatorUserId" orm:"creator_user_id" description:"创建用户ID"`
CreatorName string `json:"creatorName" orm:"creator_name" description:"创建人姓名"`
CreatorPhone string `json:"creatorPhone" orm:"creator_phone" description:"创建人手机号"`
AssignDeptId int64 `json:"assignDeptId" orm:"assign_dept_id" description:"分派方机构ID"`
AssignUserId int64 `json:"assignUserId" orm:"assign_user_id" description:"分派人用户ID"`
CurrentStatus int `json:"currentStatus" orm:"current_status" description:"当前处理状态:1已分派,2处理中,3已解决,4已完结_关单,5已取消"`
HandlerDeptId int64 `json:"handlerDeptId" orm:"handler_dept_id" description:"处理方机构ID"`
HandlerUserId int64 `json:"handlerUserId" orm:"handler_user_id" description:"处理人用户ID"`
FirstResponseTime *gtime.Time `json:"firstResponseTime" orm:"first_response_time" description:"首次响应时间"`
ResolveTime *gtime.Time `json:"resolveTime" orm:"resolve_time" description:"确认时间"`
CloseTime *gtime.Time `json:"closeTime" orm:"close_time" description:"关闭时间"`
SatisfactionLevel int `json:"satisfactionLevel" orm:"satisfaction_level" description:"满意度:1-5分"`
EvalContent string `json:"evalContent" orm:"eval_content" description:"评价内容"`
EvalTime *gtime.Time `json:"evalTime" orm:"eval_time" description:"评价时间"`
Remark string `json:"remark" orm:"remark" description:"备注"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
}
+28
View File
@@ -0,0 +1,28 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// TWoRecord is the golang structure for table t_wo_record.
type TWoRecord struct {
Id int64 `json:"id" orm:"id" description:"主键ID"`
WoNo string `json:"woNo" orm:"wo_no" description:"工单编号"`
OperationType int `json:"operationType" orm:"operation_type" description:"操作类型:0创建,1分派,2处理,3完成,4关单,5取消"`
OperationDeptId int64 `json:"operationDeptId" orm:"operation_dept_id" description:"操作机构ID"`
OperationUserId int64 `json:"operationUserId" orm:"operation_user_id" description:"操作用户ID"`
TargetDeptId int64 `json:"targetDeptId" orm:"target_dept_id" description:"目标部门ID"`
TargetUserId int64 `json:"targetUserId" orm:"target_user_id" description:"目标用户ID"`
BeforeStatus int `json:"beforeStatus" orm:"before_status" description:"变更前状态"`
AfterStatus int `json:"afterStatus" orm:"after_status" description:"变更后状态"`
TenantId string `json:"tenantId" orm:"tenant_id" description:"租户ID"`
CreatedDept int64 `json:"createdDept" orm:"created_dept" description:"创建部门"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"`
}
+16
View File
@@ -0,0 +1,16 @@
package model
// ImeiQueueStartMessage asks the Worker to scan the card table and run a full
// IMEI synchronization. The Admin service does not perform upstream calls for
// this path. A nil Scope (or one whose channels normalize to empty) is a full
// sync.
//
// The json tags must stay byte-identical with the Admin-side definition in
// iotlcm-admin-svr (internal/model/imei_sync.go); the two services each keep
// their own copy by existing convention.
type ImeiQueueStartMessage struct {
RunID string `json:"runId"`
Operation string `json:"operation"`
TriggeredAt string `json:"triggeredAt"`
Scope *SyncScope `json:"scope,omitempty"`
}
+9
View File
@@ -0,0 +1,9 @@
package model
type PackageCustomerSyncMessage struct {
TenantId string `json:"tenantId"`
DeptId int64 `json:"deptId"`
UserId int64 `json:"userId"`
Trigger string `json:"trigger"`
SourceBatchNo string `json:"sourceBatchNo"`
}
+28
View File
@@ -0,0 +1,28 @@
package model
// SimStatusQueueStartMessage asks the Worker to scan the card table and run a
// full status synchronization. The Admin service does not perform upstream
// calls for this path. A nil Scope (or one whose channels normalize to empty)
// is a full sync.
type SimStatusQueueStartMessage struct {
RunID string `json:"runId"`
Operation string `json:"operation"`
TriggeredAt string `json:"triggeredAt"`
Scope *SyncScope `json:"scope,omitempty"`
}
// SimStatusQueueTaskMessage is the card-level form used by business actions.
// The complete card routing information is carried so the Worker can enqueue
// it without doing a synchronous Admin lookup.
type SimStatusQueueTaskMessage struct {
RequestID string `json:"requestId"`
RunID string `json:"runId"`
Operation string `json:"operation"`
CardID int64 `json:"cardId"`
ICCID string `json:"iccid"`
MSISDN string `json:"msisdn"`
IMSI string `json:"imsi"`
ChanKey string `json:"chanKey"`
TempKey string `json:"tempKey"`
Operator int `json:"operator"`
}
+149
View File
@@ -0,0 +1,149 @@
package model
import (
"fmt"
"sort"
"strings"
)
// SyncScope narrows one full-sync run to an explicit channel whitelist.
//
// A nil scope, or one whose channel list normalizes to empty, means "full
// sync" and must behave exactly like a run started before this field existed.
// TriggerSource is descriptive only: it is recorded on the run for operators
// and never changes scheduling or retry behaviour.
type SyncScope struct {
Channels []string `json:"channels,omitempty"`
TriggerSource string `json:"triggerSource,omitempty"`
}
const (
// MaxScopeChannels bounds one partial-sync request. It is a guard against
// accidental "select everything" payloads, not a capacity limit.
MaxScopeChannels = 200
// MaxChanKeyLength matches t_sim_channels.chan_key varchar(32).
MaxChanKeyLength = 32
)
// Trigger source values recorded on the run.
const (
TriggerSourceScheduled = "scheduled"
TriggerSourceManual = "manual"
TriggerSourceAPI = "api"
TriggerSourceReplay = "replay"
)
// NormalizeScope validates a requested scope and returns its canonical form.
//
// Canonical form is: nil for a full sync, otherwise a scope whose channel list
// is deduplicated and sorted. Sorting makes ScopeDigest stable across requests
// that select the same channels in a different order.
func NormalizeScope(scope *SyncScope) (*SyncScope, error) {
if scope == nil {
return nil, nil
}
triggerSource := strings.TrimSpace(scope.TriggerSource)
switch triggerSource {
case "", TriggerSourceScheduled, TriggerSourceManual, TriggerSourceAPI, TriggerSourceReplay:
default:
return nil, fmt.Errorf("invalid triggerSource %q", scope.TriggerSource)
}
if len(scope.Channels) == 0 {
return nil, nil
}
if len(scope.Channels) > MaxScopeChannels {
return nil, fmt.Errorf("scope has %d channels, maximum is %d", len(scope.Channels), MaxScopeChannels)
}
seen := make(map[string]struct{}, len(scope.Channels))
channels := make([]string, 0, len(scope.Channels))
for _, raw := range scope.Channels {
chanKey := strings.TrimSpace(raw)
if err := ValidateChanKey(chanKey); err != nil {
return nil, err
}
if _, exists := seen[chanKey]; exists {
continue
}
seen[chanKey] = struct{}{}
channels = append(channels, chanKey)
}
if len(channels) == 0 {
return nil, nil
}
sort.Strings(channels)
if triggerSource == "" {
triggerSource = TriggerSourceManual
}
return &SyncScope{Channels: channels, TriggerSource: triggerSource}, nil
}
// ValidateChanKey rejects values that cannot exist in t_sim_channels.chan_key.
// The whitelist character set keeps the value safe to log and to embed in a
// Redis key without escaping.
func ValidateChanKey(chanKey string) error {
if chanKey == "" {
return fmt.Errorf("chanKey is empty")
}
if len(chanKey) > MaxChanKeyLength {
return fmt.Errorf("chanKey %q exceeds %d characters", chanKey, MaxChanKeyLength)
}
for _, r := range chanKey {
switch {
case r >= 'a' && r <= 'z':
case r >= 'A' && r <= 'Z':
case r >= '0' && r <= '9':
case r == '-' || r == '_':
default:
return fmt.Errorf("chanKey %q contains invalid character %q", chanKey, r)
}
}
return nil
}
// ChannelSet returns the scope channels as a lookup set, or nil for a full
// sync. Callers treat nil as "no filtering".
func (s *SyncScope) ChannelSet() map[string]struct{} {
if s == nil || len(s.Channels) == 0 {
return nil
}
set := make(map[string]struct{}, len(s.Channels))
for _, chanKey := range s.Channels {
set[chanKey] = struct{}{}
}
return set
}
// Allows reports whether a card on chanKey belongs to this scope. A nil scope
// allows every channel.
func (s *SyncScope) Allows(chanKey string) bool {
if s == nil || len(s.Channels) == 0 {
return true
}
for _, allowed := range s.Channels {
if allowed == chanKey {
return true
}
}
return false
}
// ChannelCount is the number of selected channels; zero means full sync.
func (s *SyncScope) ChannelCount() int {
if s == nil {
return 0
}
return len(s.Channels)
}
// ChannelSample returns at most limit channels for logging and run metadata.
func (s *SyncScope) ChannelSample(limit int) []string {
if s == nil || limit <= 0 {
return nil
}
if len(s.Channels) <= limit {
return s.Channels
}
return s.Channels[:limit]
}
+141
View File
@@ -0,0 +1,141 @@
package model
import (
"strings"
"testing"
)
func TestNormalizeScopeNilAndEmptyMeanFullSync(t *testing.T) {
for name, scope := range map[string]*SyncScope{
"nil": nil,
"no channels": {},
"empty slice": {Channels: []string{}},
} {
got, err := NormalizeScope(scope)
if err != nil {
t.Fatalf("%s: unexpected error: %v", name, err)
}
if got != nil {
t.Fatalf("%s: expected nil scope for full sync, got %+v", name, got)
}
if got.ChannelCount() != 0 || !got.Allows("anything") {
t.Fatalf("%s: nil scope must allow every channel", name)
}
}
}
func TestNormalizeScopeDeduplicatesAndSorts(t *testing.T) {
got, err := NormalizeScope(&SyncScope{Channels: []string{"217", "173", "217", "189"}})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
want := []string{"173", "189", "217"}
if len(got.Channels) != len(want) {
t.Fatalf("channels = %v, want %v", got.Channels, want)
}
for i := range want {
if got.Channels[i] != want[i] {
t.Fatalf("channels = %v, want %v (sorted)", got.Channels, want)
}
}
// Sorting keeps ScopeDigest stable for requests listing the same channels
// in a different order.
reordered, err := NormalizeScope(&SyncScope{Channels: []string{"189", "217", "173"}})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if strings.Join(reordered.Channels, ",") != strings.Join(got.Channels, ",") {
t.Fatalf("order-dependent normalization: %v vs %v", reordered.Channels, got.Channels)
}
}
func TestNormalizeScopeTrimsWhitespace(t *testing.T) {
got, err := NormalizeScope(&SyncScope{Channels: []string{" 217 ", "173"}})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got.Allows("217") != true {
t.Fatalf("whitespace-padded chanKey was not trimmed: %+v", got)
}
}
func TestNormalizeScopeRejectsInvalidInput(t *testing.T) {
cases := map[string]*SyncScope{
"too many channels": {Channels: make([]string, MaxScopeChannels+1)},
"chanKey too long": {Channels: []string{strings.Repeat("a", MaxChanKeyLength+1)}},
"chanKey with slash": {Channels: []string{"a/b"}},
"chanKey with space": {Channels: []string{"a b"}},
"chanKey with unicode": {Channels: []string{"通道"}},
"chanKey with brace": {Channels: []string{"a{b}"}},
"empty chanKey": {Channels: []string{""}},
"blank chanKey": {Channels: []string{" "}},
"unknown triggerSource": {Channels: []string{"217"}, TriggerSource: "cron"},
}
for name, scope := range cases {
if _, err := NormalizeScope(scope); err == nil {
t.Fatalf("%s: expected an error", name)
}
}
}
func TestNormalizeScopeAcceptsBoundaries(t *testing.T) {
// Exactly the maximum count must pass.
channels := make([]string, MaxScopeChannels)
for i := range channels {
channels[i] = "chan-" + strings.Repeat("0", i%10) + string(rune('a'+i%26))
}
if _, err := NormalizeScope(&SyncScope{Channels: channels}); err != nil {
t.Fatalf("exactly %d channels must be accepted: %v", MaxScopeChannels, err)
}
// A chanKey of exactly the maximum length must pass.
if err := ValidateChanKey(strings.Repeat("a", MaxChanKeyLength)); err != nil {
t.Fatalf("chanKey of exactly %d characters must be accepted: %v", MaxChanKeyLength, err)
}
}
func TestNormalizeScopeDefaultsTriggerSource(t *testing.T) {
got, err := NormalizeScope(&SyncScope{Channels: []string{"217"}})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got.TriggerSource != TriggerSourceManual {
t.Fatalf("triggerSource = %q, want %q", got.TriggerSource, TriggerSourceManual)
}
}
func TestNormalizeScopeKeepsExplicitTriggerSource(t *testing.T) {
got, err := NormalizeScope(&SyncScope{Channels: []string{"217"}, TriggerSource: TriggerSourceAPI})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got.TriggerSource != TriggerSourceAPI {
t.Fatalf("triggerSource = %q, want %q", got.TriggerSource, TriggerSourceAPI)
}
}
func TestScopeChannelSetAndSample(t *testing.T) {
scope, err := NormalizeScope(&SyncScope{Channels: []string{"217", "173"}})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
set := scope.ChannelSet()
if _, ok := set["173"]; !ok {
t.Fatalf("channel set missing 173: %v", set)
}
if len(set) != 2 {
t.Fatalf("channel set = %v, want 2 entries", set)
}
if sample := scope.ChannelSample(1); len(sample) != 1 || sample[0] != "173" {
t.Fatalf("sample = %v, want [173]", sample)
}
if sample := scope.ChannelSample(10); len(sample) != 2 {
t.Fatalf("sample = %v, want both channels", sample)
}
var nilScope *SyncScope
if nilScope.ChannelSet() != nil {
t.Fatalf("nil scope must return a nil channel set")
}
if nilScope.ChannelSample(10) != nil {
t.Fatalf("nil scope must return a nil sample")
}
}
+12
View File
@@ -0,0 +1,12 @@
package model
import "strings"
func IsTelecomTemplate(tempKey string) bool {
switch strings.ToLower(strings.TrimSpace(tempKey)) {
case "sim_dx_v1", "sim_dx_v3":
return true
default:
return false
}
}
+19
View File
@@ -0,0 +1,19 @@
package model
import "time"
type TrafficUsageBase struct {
Iccid string
UsageMb float64
PackageCode string
}
type TrafficUsageDailyItem struct {
TrafficUsageBase
Date time.Time
}
type TrafficUsageMonthlyItem struct {
TrafficUsageBase
Month time.Time
}
+79
View File
@@ -0,0 +1,79 @@
package model
// TrafficUsageSimCard is the basic card data needed when writing usage to TDengine.
type TrafficUsageSimCard struct {
Iccid string `json:"iccid"`
PackageCode string `json:"packageCode"`
}
// TrafficUsageDailyRetryMessage is the retry message for daily traffic usage.
type TrafficUsageDailyRetryMessage struct {
UsageMb *float64 `json:"usageMb,omitempty"`
Attempt int `json:"attempt,omitempty"`
LastError string `json:"lastError,omitempty"`
SimKey *SimKey `json:"simKey"`
Card TrafficUsageSimCard `json:"card"`
// QueryDate format: yyyyMMdd.
QueryDate string `json:"queryDate"`
}
// TrafficUsageMonthlyRetryMessage is the retry message for monthly traffic usage.
type TrafficUsageMonthlyRetryMessage struct {
UsageMb *float64 `json:"usageMb,omitempty"`
Attempt int `json:"attempt,omitempty"`
LastError string `json:"lastError,omitempty"`
SimKey *SimKey `json:"simKey"`
Card TrafficUsageSimCard `json:"card"`
// QueryDate format: yyyyMM.
QueryDate string `json:"queryDate"`
}
// TrafficUsageMonthlyStartMessage starts one full monthly usage run.
// Admin publishes this command; Worker owns the card scan and Redis production.
// A nil Scope (or one whose channels normalize to empty) is a full sync.
type TrafficUsageMonthlyStartMessage struct {
RunID string `json:"runId"`
Operation string `json:"operation"`
QueryMonth string `json:"queryMonth"`
TriggeredAt string `json:"triggeredAt"`
Scope *SyncScope `json:"scope,omitempty"`
}
// TrafficUsageDailyStartMessage starts one full daily usage run.
// Admin publishes this command; Worker owns the card scan and Redis production.
// A nil Scope (or one whose channels normalize to empty) is a full sync.
//
// QueryDate is yyyyMMdd. The producer carries it through zset.Task.QueryMonth,
// which is a period identifier rather than a month name; see that field's doc.
type TrafficUsageDailyStartMessage struct {
RunID string `json:"runId"`
Operation string `json:"operation"`
QueryDate string `json:"queryDate"`
TriggeredAt string `json:"triggeredAt"`
Scope *SyncScope `json:"scope,omitempty"`
}
// TrafficUsageMonthlyHistoryStartMessage starts one full monthly usage history
// run. It writes the TDengine monthly table, which is a different target from
// TrafficUsageMonthlyStartMessage (the current-month snapshot written to MySQL).
//
// QueryMonth is yyyyMM and names the month being backfilled, which is the
// previous month rather than the current one.
type TrafficUsageMonthlyHistoryStartMessage struct {
RunID string `json:"runId"`
Operation string `json:"operation"`
QueryMonth string `json:"queryMonth"`
TriggeredAt string `json:"triggeredAt"`
Scope *SyncScope `json:"scope,omitempty"`
}
// OperationPreviousDayUsageFullSync identifies a daily usage run. It is the one
// string that Admin publishes, Worker produces, and contract.SyncKindForOperation
// maps to the traffic_usage_daily sync kind, so it lives here rather than in
// either side's logic package.
const OperationPreviousDayUsageFullSync = "previous_day_usage_full_sync"
// OperationPreviousMonthUsageFullSync identifies a monthly usage history run.
// It is deliberately distinct from current_month_usage_full_sync, which fills
// the MySQL current-month snapshot instead of the TDengine monthly table.
const OperationPreviousMonthUsageFullSync = "previous_month_usage_full_sync"
+110
View File
@@ -0,0 +1,110 @@
package model
import "time"
type UpstreamChanConfig struct {
Address string `json:"address"`
Timeout time.Duration `json:"timeout"`
}
type SimKey struct {
ChanKey string `json:"chanKey"`
ICCID string `json:"iccid"`
IMSI string `json:"imsi"`
MSISDN string `json:"msisdn"`
}
type SimBaseReq[T any] struct {
SimKeys []*SimKey `json:"simKeys"`
ReqData T `json:"reqData"`
}
// SimInputReqNullDate is used by current-month real-time usage calls. The
// upstream determines the current month at request time.
type SimInputReqNullDate struct{}
type SimDataUsageInput = SimBaseReq[SimInputReqNullDate]
type SimDataUsageItem struct {
DataUsage float64 `json:"dataUsage"`
}
type SimBaseRes[T any] struct {
Code int `json:"code"`
Message string `json:"message"`
ErrCode string `json:"errCode"`
SimKey *SimKey `json:"simKey"`
ResData T `json:"resData"`
}
type SimBasicInfoInput = SimBaseReq[SimInputReqNullDate]
type SimBasicInfoItem struct {
ICCID string `json:"iccid"`
IMSI string `json:"imsi"`
MSISDN string `json:"msisdn"`
ActiveDate string `json:"activeDate"`
OpenDate string `json:"openDate"`
Remark string `json:"remark"`
}
type SimDataUsageMonthlyInput = SimBaseReq[SimDataUsageMonthlyInputItem]
type SimDataUsageMonthlyInputItem struct {
QueryDate string `json:"queryDate"`
}
type SimDataUsageMonthlyOutputItem struct {
DeadLine string `json:"deadLine"`
DataAmount float64 `json:"dataAmount"`
}
type SimDataUsageDailyInput = SimBaseReq[SimDataUsageDailyInputItem]
type SimDataUsageDailyInputItem struct {
QueryDate string `json:"queryDate"`
}
type SimDataUsageDailyOutputItem struct {
QueryDate string `json:"queryDate"`
DataAmount float64 `json:"dataAmount"`
}
// SimCardStatusInput is the request envelope for carrier status queries.
type SimCardStatusInput = SimBaseReq[SimInputReqNullDate]
// SimImeiInput is the request envelope for terminal IMEI queries.
type SimImeiInput = SimBaseReq[SimInputReqNullDate]
// SimImeiItem is the terminal IMEI returned for one SIM card.
//
// A carrier may answer successfully yet return an empty value (for example a
// card whose device never reported an IMEI, or a template whose upstream
// endpoint does not expose IMEI at all). Callers must therefore distinguish
// "query succeeded with an empty value" from "query failed".
type SimImeiItem struct {
Imei string `json:"imei"`
}
// SimCardStatusItem is the carrier status returned for one SIM card.
type SimCardStatusItem struct {
CardStatus int `json:"cardStatus"`
LastChangeDate string `json:"lastChangeDate"`
}
type SimCardStatusChangeInput = SimBaseReq[SimCardStatusChangeInputItem]
type SimCardStatusChangeInputItem struct {
OperType string `json:"operType"`
}
type SimCardStatusChangeOutputItem struct {
OrderNum string `json:"orderNum"`
}
type SimCardApnChangeInput = SimBaseReq[SimCardApnChangeInputItem]
type SimCardApnChangeInputItem struct {
OperType string `json:"operType"`
ApnName string `json:"apnName"`
}
type SimCardApnChangeOutputItem struct {
OrderNum string `json:"orderNum"`
}
+13
View File
@@ -0,0 +1,13 @@
package model
// WorkOrderAutoCloseMessage is consumed after the auto-close waiting window.
type WorkOrderAutoCloseMessage struct {
WoNo string `json:"woNo"`
ResolveTimeTs int64 `json:"resolveTimeTs"`
}
// BalanceRechargeTimeoutMessage is consumed after the Alipay recharge window.
type BalanceRechargeTimeoutMessage struct {
OutTradeNo string `json:"outTradeNo"`
RetryCount int `json:"retryCount"`
}
+8
View File
@@ -0,0 +1,8 @@
package model
// WorkerDiagnosticMessage verifies the Admin-to-Worker RabbitMQ path.
type WorkerDiagnosticMessage struct {
TraceID string `json:"traceId"`
SentAt int64 `json:"sentAt"`
Message string `json:"message"`
}