chore: 初始开源发布

iotlcm-admin-svr:管理后台服务。

- Go module:iotlcm → git.5iot.com/iotlcm-public/iotlcm-admin-svr(729 文件)
- 凭据与地址脱敏:JWT signingKey(含代码里的 MustGet 默认值)、
  MySQL DSN、Redis 口令、告警邮件发件人邮箱全部改为占位;
  私网 IP → 文档地址段;库名 xiujie_admin → iotlcm
- 真实手机号/邮箱 → 合法 11 位编造号 / example.com
- 移除内部资产:CI 触发器、过时 DDL(sql/db_iotlcm.sql)、
  私有依赖 go get 行、明文 registry 登录口令
- 启动 banner 统一 IOTLCM 方块字 + 社区惯例署名
- Dockerfile 改用公共基础镜像
- 拼错的 RADEME.md → README.md,README 重写
- 需要真实数据库的用例改为可用 IOTLCM_TEST_WITH_DB=1 显式启用
- 补 Apache-2.0 LICENSE,LF 行尾 + .gitattributes

数据库 schema 不随本仓发布(生产 DDL 已过时),README 已说明。
This commit is contained in:
MiFaZhan
2026-10-23 14:46:05 +08:00
commit 59eb34976a
1132 changed files with 138197 additions and 0 deletions
@@ -0,0 +1,129 @@
package model
import (
"context"
"strings"
"github.com/gogf/gf/v2/errors/gerror"
)
const (
TSimChannelsTestInputModeComplete = "complete"
TSimChannelsTestInputModeSingle = "single"
TSimChannelsTestInputModeDirectSingle = "direct_single"
)
type TSimChannelsTestParam struct {
ChannelId int64 `json:"channelId" v:"required#通道ID不能为空" dc:"通道ID"`
InputMode string `json:"inputMode" dc:"输入模式:complete/single"`
CardValueType string `json:"cardValueType" dc:"卡值类型:iccid/msisdn/imsi"`
CardValue string `json:"cardValue" dc:"卡值"`
Iccid string `json:"iccid" dc:"ICCID"`
Imsi string `json:"imsi" dc:"IMSI"`
Msisdn string `json:"msisdn" dc:"MSISDN"`
Items []string `json:"items" dc:"待测试接口;为空时测试全部"`
}
func (in *TSimChannelsTestParam) Filter(ctx context.Context) error {
in.InputMode = strings.ToLower(strings.TrimSpace(in.InputMode))
if in.InputMode == "" {
in.InputMode = TSimChannelsTestInputModeComplete
}
in.CardValueType = strings.ToLower(strings.TrimSpace(in.CardValueType))
in.CardValue = strings.TrimSpace(in.CardValue)
in.Iccid = strings.TrimSpace(in.Iccid)
in.Imsi = strings.TrimSpace(in.Imsi)
in.Msisdn = strings.TrimSpace(in.Msisdn)
items, err := NormalizeTSimChannelTestItems(in.Items)
if err != nil {
return err
}
in.Items = items
switch in.InputMode {
case TSimChannelsTestInputModeComplete:
if in.Iccid == "" || in.Imsi == "" || in.Msisdn == "" {
return gerror.New("完整三码模式下ICCID、IMSI、MSISDN均不能为空")
}
if in.CardValue != "" || in.CardValueType != "" {
return gerror.New("完整三码模式下不需要填写单码查询参数")
}
case TSimChannelsTestInputModeSingle:
if in.CardValue == "" || in.CardValueType == "" {
return gerror.New("单码补全模式下卡值类型和卡值不能为空")
}
if in.Iccid != "" || in.Imsi != "" || in.Msisdn != "" {
return gerror.New("单码补全模式下不需要填写完整三码")
}
switch in.CardValueType {
case "iccid", "imsi", "msisdn":
default:
return gerror.New("单码补全模式下卡值类型只能是iccid、imsi或msisdn")
}
case TSimChannelsTestInputModeDirectSingle:
if in.CardValue == "" || in.CardValueType == "" {
return gerror.New("direct single mode requires card value type and value")
}
if in.Iccid != "" || in.Imsi != "" || in.Msisdn != "" {
return gerror.New("direct single mode does not accept complete card identifiers")
}
switch in.CardValueType {
case "iccid", "imsi", "msisdn":
default:
return gerror.New("direct single mode card value type must be iccid, imsi, or msisdn")
}
default:
return gerror.New("不支持的输入模式")
}
return nil
}
type TSimChannelsTestOutput struct {
Items []*TSimChannelsTestItem `json:"items" dc:"测试结果"`
GatewayResponseRaw string `json:"gatewayResponseRaw,omitempty" dc:"网关原始响应"`
}
// TSimChannelsTestError adds diagnostic response data without replacing the original error.
type TSimChannelsTestError struct {
Err error
GatewayResponseRaw string
}
func (e *TSimChannelsTestError) Error() string { return e.Err.Error() }
func (e *TSimChannelsTestError) Unwrap() error { return e.Err }
type TSimChannelsTestItem struct {
Key string `json:"key" dc:"查询项标识"`
Name string `json:"name" dc:"查询项名称"`
Status string `json:"status" dc:"状态:success/failed/timeout"`
DurationMs int64 `json:"durationMs" dc:"耗时(毫秒)"`
Message string `json:"message,omitempty" dc:"结果消息"`
Data any `json:"data,omitempty" dc:"标准化响应数据"`
ErrorCode int `json:"errorCode,omitempty" dc:"gateway or carrier error code"`
ResponseJSON string `json:"responseJson,omitempty" dc:"本次通道测试响应 JSON"`
}
var tSimChannelTestItemKeys = map[string]struct{}{
"simBasicInfo": {}, "simSession": {}, "simStatus": {}, "simStopReason": {}, "simFrozenState": {},
"simCardBindStatus": {}, "simDeviceStatus": {}, "simRegionLimitStatus": {}, "simImei": {},
"simDataUsage": {}, "simDataUsageMonthly": {}, "simDataUsageDaily": {}, "simApnInfo": {},
}
func NormalizeTSimChannelTestItems(items []string) ([]string, error) {
if len(items) == 0 {
return nil, nil
}
seen := make(map[string]struct{}, len(items))
normalized := make([]string, 0, len(items))
for _, item := range items {
item = strings.TrimSpace(item)
if _, ok := tSimChannelTestItemKeys[item]; !ok {
return nil, gerror.Newf("不支持的测试项:%s", item)
}
if _, ok := seen[item]; ok {
continue
}
seen[item] = struct{}{}
normalized = append(normalized, item)
}
return normalized, nil
}