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 已说明。
153 lines
4.4 KiB
Go
153 lines
4.4 KiB
Go
package addpackage
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchimport"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchinput/excel"
|
|
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchinput/text"
|
|
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
)
|
|
|
|
const (
|
|
headerPackageCode = "加油包套餐编码"
|
|
headerEffectiveMode = "生效方式"
|
|
headerRemark = "备注"
|
|
)
|
|
|
|
func parseExcelRows(ctx context.Context, filePath string, cfg Config, options SubmitOptions) ([]batchimport.Row, error) {
|
|
parsedRows, err := excel.ParseFile(ctx, filePath, excel.ParseOptions{
|
|
RequiredHeaders: []string{cfg.TargetHeader, headerPackageCode},
|
|
SingleSheet: true,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rows := make([]batchimport.Row, 0, len(parsedRows))
|
|
for _, parsed := range parsedRows {
|
|
row := &Row{
|
|
RowNo: parsed.RowNo,
|
|
TargetCode: fieldValue(parsed, targetAliases(cfg)...),
|
|
PackageCode: fieldValue(parsed, headerPackageCode, "加油包编码", "packageCode", "套餐编码"),
|
|
EffectiveMode: fieldValue(parsed, headerEffectiveMode, "effectiveMode", "生效模式"),
|
|
Remark: fieldValue(parsed, headerRemark, "remark"),
|
|
}
|
|
applyDefaultOptions(row, options)
|
|
rows = append(rows, row)
|
|
}
|
|
return rows, nil
|
|
}
|
|
|
|
func parseInputRows(ctx context.Context, input string, options SubmitOptions) ([]batchimport.Row, error) {
|
|
lines, err := text.ParseNonEmptyLines(ctx, input)
|
|
if err != nil {
|
|
if errors.Is(err, text.ErrEmptyInput) {
|
|
return nil, gerror.New("批量输入内容不能为空")
|
|
}
|
|
return nil, err
|
|
}
|
|
rows := make([]batchimport.Row, 0, len(lines))
|
|
for _, line := range lines {
|
|
row := &Row{RowNo: line.RowNo}
|
|
fields := parseInputFields(line.Text)
|
|
if len(fields) != 1 {
|
|
row.AddErrorReason("格式错误,应为目标编码")
|
|
} else {
|
|
row.TargetCode = fields[0]
|
|
}
|
|
applyDefaultOptions(row, options)
|
|
rows = append(rows, row)
|
|
}
|
|
return rows, nil
|
|
}
|
|
|
|
func fieldValue(row excel.ParsedRow, names ...string) string {
|
|
for _, name := range names {
|
|
if value := strings.TrimSpace(excel.Field(row, name)); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func targetAliases(cfg Config) []string {
|
|
if cfg.Operation == OperationPool {
|
|
return []string{cfg.TargetHeader, "流量池编码", "流量池编号", "poolNo", "flowPoolCode", "targetCode"}
|
|
}
|
|
return []string{cfg.TargetHeader, "卡号", "iccid", "targetCode"}
|
|
}
|
|
|
|
func parseInputFields(value string) []string {
|
|
value = strings.TrimSpace(value)
|
|
if value == "" {
|
|
return nil
|
|
}
|
|
if strings.Contains(value, "|") {
|
|
return splitAndTrim(value, "|")
|
|
}
|
|
if strings.Contains(value, "\t") {
|
|
return splitAndTrim(value, "\t")
|
|
}
|
|
return strings.Fields(value)
|
|
}
|
|
|
|
func splitAndTrim(value, sep string) []string {
|
|
parts := strings.Split(value, sep)
|
|
out := make([]string, 0, len(parts))
|
|
for _, part := range parts {
|
|
out = append(out, strings.TrimSpace(part))
|
|
}
|
|
return out
|
|
}
|
|
|
|
func applyDefaultOptions(row *Row, options SubmitOptions) {
|
|
if row == nil {
|
|
return
|
|
}
|
|
row.TargetCode = strings.TrimSpace(row.TargetCode)
|
|
row.PackageCode = strings.TrimSpace(row.PackageCode)
|
|
row.Remark = strings.TrimSpace(row.Remark)
|
|
row.EffectiveMode = strings.TrimSpace(row.EffectiveMode)
|
|
|
|
if options.PackageCode != "" {
|
|
if row.PackageCode != "" && row.PackageCode != options.PackageCode {
|
|
row.AddErrorReason("行内加油包编码与页面选择不一致")
|
|
}
|
|
row.PackageCode = options.PackageCode
|
|
}
|
|
if row.EffectiveMode == "" && options.EffectiveMode != "" {
|
|
row.EffectiveMode = options.EffectiveMode
|
|
}
|
|
if row.Remark == "" {
|
|
row.Remark = strings.TrimSpace(options.Remark)
|
|
}
|
|
}
|
|
|
|
func normalizeOptions(options SubmitOptions) (SubmitOptions, error) {
|
|
options.PackageCode = strings.TrimSpace(options.PackageCode)
|
|
options.Remark = strings.TrimSpace(options.Remark)
|
|
mode, err := NormalizeEffectiveMode(options.EffectiveMode)
|
|
if err != nil {
|
|
return SubmitOptions{}, err
|
|
}
|
|
options.EffectiveMode = mode
|
|
options.PaymentMode = strings.TrimSpace(options.PaymentMode)
|
|
if options.PaymentMode == "" {
|
|
options.PaymentMode = "balance"
|
|
}
|
|
switch options.PaymentMode {
|
|
case "balance":
|
|
options.OfflineContractCompleted = false
|
|
case "offline":
|
|
if !options.OfflineContractCompleted {
|
|
return SubmitOptions{}, gerror.New("请确认线下合同、销售和走账已完成")
|
|
}
|
|
default:
|
|
return SubmitOptions{}, gerror.New("加油包付款方式不正确")
|
|
}
|
|
return options, nil
|
|
}
|