59eb34976a
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 已说明。
165 lines
5.2 KiB
Go
165 lines
5.2 KiB
Go
package change
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchinput/excel"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model"
|
|
)
|
|
|
|
type ExcelSubmitOptions struct {
|
|
NewPackageCode string
|
|
DurationMonths int
|
|
GiftDurationMonths int
|
|
EffectiveMode string
|
|
OfflineContractCompleted bool
|
|
}
|
|
|
|
func ExcelTemplateHeaders() []string {
|
|
return []string{
|
|
"ICCID",
|
|
"MSISDN",
|
|
"IMSI",
|
|
"newPackageCode",
|
|
"durationMonths",
|
|
"giftDurationMonths",
|
|
"effectiveMode",
|
|
"offlineContractCompleted",
|
|
}
|
|
}
|
|
|
|
func (o *ExcelSubmitOptions) ToBatchSubmitParam() *model.TSimCardChangeBatchSubmitParam {
|
|
if o == nil {
|
|
return &model.TSimCardChangeBatchSubmitParam{}
|
|
}
|
|
return &model.TSimCardChangeBatchSubmitParam{
|
|
NewPackageCode: strings.TrimSpace(o.NewPackageCode),
|
|
DurationMonths: o.DurationMonths,
|
|
GiftDurationMonths: o.GiftDurationMonths,
|
|
EffectiveMode: strings.TrimSpace(o.EffectiveMode),
|
|
OfflineContractCompleted: o.OfflineContractCompleted,
|
|
}
|
|
}
|
|
|
|
func (o *ExcelSubmitOptions) ToBatchSubmitParamWithBatchNo(batchNo string) *model.TSimCardChangeBatchSubmitParam {
|
|
param := o.ToBatchSubmitParam()
|
|
param.BatchNo = strings.TrimSpace(batchNo)
|
|
return param
|
|
}
|
|
|
|
func ParseExcelFileRows(ctx context.Context, filePath string) ([]*Row, *ExcelSubmitOptions, error) {
|
|
parsedRows, err := excel.ParseFile(ctx, filePath, excel.ParseOptions{
|
|
RequiredHeaders: ExcelTemplateHeaders(),
|
|
SingleSheet: true,
|
|
})
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
rows := make([]*Row, 0, len(parsedRows))
|
|
var options *ExcelSubmitOptions
|
|
inconsistent := false
|
|
|
|
for _, parsed := range parsedRows {
|
|
row := &Row{
|
|
RowNo: parsed.RowNo,
|
|
Iccid: excel.Field(parsed, "ICCID"),
|
|
Msisdn: excel.Field(parsed, "MSISDN"),
|
|
Imsi: excel.Field(parsed, "IMSI"),
|
|
RawFields: map[string]string{
|
|
"ICCID": excel.Field(parsed, "ICCID"),
|
|
"MSISDN": excel.Field(parsed, "MSISDN"),
|
|
"IMSI": excel.Field(parsed, "IMSI"),
|
|
"newPackageCode": excel.Field(parsed, "newPackageCode"),
|
|
"durationMonths": excel.Field(parsed, "durationMonths"),
|
|
"giftDurationMonths": excel.Field(parsed, "giftDurationMonths"),
|
|
"effectiveMode": excel.Field(parsed, "effectiveMode"),
|
|
"offlineContractCompleted": excel.Field(parsed, "offlineContractCompleted"),
|
|
},
|
|
}
|
|
rowOptions, reasons := parseExcelSubmitOptions(parsed)
|
|
if len(reasons) > 0 {
|
|
row.AddReason(strings.Join(reasons, "; "))
|
|
rows = append(rows, row)
|
|
continue
|
|
}
|
|
|
|
row.NewPackageCode = rowOptions.NewPackageCode
|
|
row.DurationMonths = rowOptions.DurationMonths
|
|
row.GiftDurationMonths = rowOptions.GiftDurationMonths
|
|
row.EffectiveMode = rowOptions.EffectiveMode
|
|
row.OfflineContractCompleted = rowOptions.OfflineContractCompleted
|
|
|
|
if options == nil {
|
|
options = rowOptions
|
|
} else if !sameExcelSubmitOptions(options, rowOptions) {
|
|
row.AddReason("same excel batch change params must be consistent")
|
|
inconsistent = true
|
|
}
|
|
rows = append(rows, row)
|
|
}
|
|
|
|
if inconsistent {
|
|
markRowsWithoutReason(rows, "same excel batch change params must be consistent")
|
|
}
|
|
return rows, options, nil
|
|
}
|
|
|
|
func parseExcelSubmitOptions(row excel.ParsedRow) (*ExcelSubmitOptions, []string) {
|
|
var reasons []string
|
|
|
|
newPackageCode := strings.TrimSpace(excel.Field(row, "newPackageCode"))
|
|
if newPackageCode == "" {
|
|
reasons = append(reasons, "newPackageCode is required")
|
|
}
|
|
durationMonths, err := excel.ParsePositiveInt(excel.Field(row, "durationMonths"))
|
|
if err != nil {
|
|
reasons = append(reasons, "durationMonths must be a positive integer")
|
|
}
|
|
|
|
giftDurationValue := strings.TrimSpace(excel.Field(row, "giftDurationMonths"))
|
|
giftDurationMonths := 0
|
|
if giftDurationValue != "" {
|
|
giftDurationMonths, err = excel.ParseNonNegativeInt(giftDurationValue)
|
|
if err != nil {
|
|
reasons = append(reasons, "giftDurationMonths must be a non-negative integer")
|
|
}
|
|
}
|
|
|
|
effectiveMode := strings.TrimSpace(excel.Field(row, "effectiveMode"))
|
|
if effectiveMode == "" {
|
|
reasons = append(reasons, "effectiveMode is required")
|
|
}
|
|
|
|
offlineContractCompleted, err := excel.ParseBool(excel.Field(row, "offlineContractCompleted"))
|
|
if err != nil {
|
|
reasons = append(reasons, "offlineContractCompleted format is invalid")
|
|
} else if !offlineContractCompleted {
|
|
reasons = append(reasons, "offlineContractCompleted must be true")
|
|
}
|
|
|
|
if len(reasons) > 0 {
|
|
return nil, reasons
|
|
}
|
|
|
|
return &ExcelSubmitOptions{
|
|
NewPackageCode: newPackageCode,
|
|
DurationMonths: durationMonths,
|
|
GiftDurationMonths: giftDurationMonths,
|
|
EffectiveMode: effectiveMode,
|
|
OfflineContractCompleted: offlineContractCompleted,
|
|
}, nil
|
|
}
|
|
|
|
func sameExcelSubmitOptions(left, right *ExcelSubmitOptions) bool {
|
|
if left == nil || right == nil {
|
|
return false
|
|
}
|
|
return strings.TrimSpace(left.NewPackageCode) == strings.TrimSpace(right.NewPackageCode) &&
|
|
left.DurationMonths == right.DurationMonths &&
|
|
left.GiftDurationMonths == right.GiftDurationMonths &&
|
|
strings.TrimSpace(left.EffectiveMode) == strings.TrimSpace(right.EffectiveMode) &&
|
|
left.OfflineContractCompleted == right.OfflineContractCompleted
|
|
}
|