chore: 并入 iotlcm-admin-svr 历史到 admin-svr/(原提交 49818c6)
This commit is contained in:
@@ -0,0 +1,344 @@
|
||||
package outbound
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchinput/excel"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type ExcelParseResult struct {
|
||||
Rows []*Row
|
||||
SubmitParam *model.TSimCardOutboundSubmitParam
|
||||
}
|
||||
|
||||
type consistencyValue struct {
|
||||
rowNo int
|
||||
normalized string
|
||||
}
|
||||
|
||||
func excelHeaders() []string {
|
||||
return []string{
|
||||
"ICCID",
|
||||
"MSISDN",
|
||||
"IMSI",
|
||||
"客户/机构",
|
||||
"套餐",
|
||||
"套餐开始时间",
|
||||
"购买时长(年)",
|
||||
"赠送时长(月)",
|
||||
"订单金额",
|
||||
"线下合同/销售/走账已完成",
|
||||
"备注",
|
||||
}
|
||||
}
|
||||
|
||||
func excelRequiredHeaders() []string {
|
||||
return []string{"ICCID"}
|
||||
}
|
||||
|
||||
func ParseExcelFile(ctx context.Context, filePath string) (*ExcelParseResult, error) {
|
||||
parsedRows, err := excel.ParseFile(ctx, filePath, excel.ParseOptions{
|
||||
RequiredHeaders: excelRequiredHeaders(),
|
||||
SingleSheet: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buildExcelParseResult(parsedRows), nil
|
||||
}
|
||||
|
||||
func ParseExcelReader(ctx context.Context, reader io.Reader) (*ExcelParseResult, error) {
|
||||
parsedRows, err := excel.ParseReader(ctx, reader, excel.ParseOptions{
|
||||
RequiredHeaders: excelRequiredHeaders(),
|
||||
SingleSheet: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buildExcelParseResult(parsedRows), nil
|
||||
}
|
||||
|
||||
func buildExcelParseResult(parsedRows []excel.ParsedRow) *ExcelParseResult {
|
||||
rows := make([]*Row, 0, len(parsedRows))
|
||||
consistentCustomerAgentId := consistencyValue{}
|
||||
consistentPackageCode := consistencyValue{}
|
||||
consistentPackageBeginTime := consistencyValue{}
|
||||
consistentDurationYears := consistencyValue{}
|
||||
consistentDurationMonthPart := consistencyValue{}
|
||||
consistentGiftDurationYears := consistencyValue{}
|
||||
consistentGiftDurationMonthPart := consistencyValue{}
|
||||
consistentAmount := consistencyValue{}
|
||||
consistentOfflineContractCompleted := consistencyValue{}
|
||||
consistentRemark := consistencyValue{}
|
||||
|
||||
for _, parsed := range parsedRows {
|
||||
row := &Row{
|
||||
RowNo: parsed.RowNo,
|
||||
Iccid: excel.Field(parsed, "ICCID"),
|
||||
Msisdn: excel.Field(parsed, "MSISDN"),
|
||||
Imsi: excel.Field(parsed, "IMSI"),
|
||||
// 出库不再配置测试期、沉默期;1 表示否。
|
||||
HasTestPeriod: 1,
|
||||
HasSilentPeriod: 1,
|
||||
}
|
||||
|
||||
parseRequiredPositiveInt(row, excelField(parsed, "customerAgentId"), "客户/机构", func(value int) {
|
||||
row.CustomerAgentId = int64(value)
|
||||
checkConsistency(row, "客户/机构", strconv.FormatInt(row.CustomerAgentId, 10), &consistentCustomerAgentId)
|
||||
})
|
||||
|
||||
row.PackageCode = strings.TrimSpace(excelField(parsed, "packageCode"))
|
||||
if row.PackageCode == "" {
|
||||
row.AddReason("套餐不能为空")
|
||||
} else {
|
||||
checkConsistency(row, "套餐", row.PackageCode, &consistentPackageCode)
|
||||
}
|
||||
|
||||
parseRequiredDateTime(row, excelField(parsed, "packageBeginTime"), "套餐开始时间", func(value *gtime.Time) {
|
||||
row.PackageBeginTime = value
|
||||
checkConsistency(row, "套餐开始时间", formatTime(value), &consistentPackageBeginTime)
|
||||
})
|
||||
|
||||
parseExcelDuration(row, parsed, &consistentDurationYears, &consistentDurationMonthPart)
|
||||
|
||||
parseExcelGiftDuration(row, parsed, &consistentGiftDurationYears, &consistentGiftDurationMonthPart)
|
||||
|
||||
parseRequiredAmount(row, excelField(parsed, "amount"), func(value string) {
|
||||
row.Amount = value
|
||||
checkConsistency(row, "订单金额", value, &consistentAmount)
|
||||
})
|
||||
|
||||
parseRequiredBool(row, excelField(parsed, "offlineContractCompleted"), "线下合同/销售/走账已完成", func(value bool) {
|
||||
row.OfflineContractCompleted = value
|
||||
checkConsistency(row, "线下合同/销售/走账已完成", strconv.FormatBool(value), &consistentOfflineContractCompleted)
|
||||
})
|
||||
|
||||
row.Remark = strings.TrimSpace(excelField(parsed, "remark"))
|
||||
checkConsistency(row, "备注", row.Remark, &consistentRemark)
|
||||
|
||||
rows = append(rows, row)
|
||||
}
|
||||
|
||||
result := &ExcelParseResult{Rows: rows}
|
||||
if hasInvalidRows(rows) {
|
||||
return result
|
||||
}
|
||||
result.SubmitParam = &model.TSimCardOutboundSubmitParam{
|
||||
CustomerAgentId: rows[0].CustomerAgentId,
|
||||
PackageCode: rows[0].PackageCode,
|
||||
PackageBeginTime: rows[0].PackageBeginTime,
|
||||
DurationYears: rows[0].DurationYears,
|
||||
DurationMonthPart: rows[0].DurationMonthPart,
|
||||
DurationMonths: rows[0].DurationMonths,
|
||||
GiftDurationYears: rows[0].GiftDurationYears,
|
||||
GiftDurationMonthPart: rows[0].GiftDurationMonthPart,
|
||||
GiftDurationMonths: rows[0].GiftDurationMonths,
|
||||
HasTestPeriod: 1,
|
||||
HasSilentPeriod: 1,
|
||||
Amount: rows[0].Amount,
|
||||
OfflineContractCompleted: rows[0].OfflineContractCompleted,
|
||||
Remark: rows[0].Remark,
|
||||
BuyerNote: rows[0].Remark,
|
||||
AdminNote: rows[0].Remark,
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func excelField(row excel.ParsedRow, name string) string {
|
||||
for _, alias := range excelFieldAliases(name) {
|
||||
if value := strings.TrimSpace(excel.Field(row, alias)); value != "" {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func excelFieldAliases(name string) []string {
|
||||
switch name {
|
||||
case "customerAgentId":
|
||||
return []string{"客户/机构", "客户/机构ID", "客户ID", "customerAgentId"}
|
||||
case "packageCode":
|
||||
return []string{"套餐", "套餐编码", "packageCode"}
|
||||
case "packageBeginTime":
|
||||
return []string{"套餐开始时间", "packageBeginTime"}
|
||||
case "durationYears":
|
||||
return []string{"购买时长(年)", "套餐购买时长(年)", "durationYears"}
|
||||
case "durationMonthPart":
|
||||
return []string{"购买时长(月)", "套餐购买时长(月)", "durationMonthPart"}
|
||||
case "durationMonths":
|
||||
return []string{"durationMonths"}
|
||||
case "giftDurationYears":
|
||||
return []string{"赠送时长(年)", "giftDurationYears"}
|
||||
case "giftDurationMonthPart":
|
||||
return []string{"赠送时长(月)", "giftDurationMonthPart"}
|
||||
case "giftDurationMonths":
|
||||
return []string{"giftDurationMonths"}
|
||||
case "amount":
|
||||
return []string{"订单金额", "amount"}
|
||||
case "offlineContractCompleted":
|
||||
return []string{"线下合同/销售/走账已完成", "是否走线下", "offlineContractCompleted"}
|
||||
case "remark":
|
||||
return []string{"备注", "remark", "buyerNote", "adminNote"}
|
||||
default:
|
||||
return []string{name}
|
||||
}
|
||||
}
|
||||
|
||||
func parseExcelDuration(row *Row, parsed excel.ParsedRow, consistentYears, consistentMonthPart *consistencyValue) {
|
||||
yearsRaw := excelField(parsed, "durationYears")
|
||||
monthPartRaw := excelField(parsed, "durationMonthPart")
|
||||
if strings.TrimSpace(yearsRaw) != "" || strings.TrimSpace(monthPartRaw) != "" {
|
||||
parseOptionalNonNegativeInt(row, yearsRaw, "购买时长(年)", 0, func(value int) {
|
||||
row.DurationYears = value
|
||||
checkConsistency(row, "购买时长(年)", strconv.Itoa(value), consistentYears)
|
||||
})
|
||||
parseOptionalMonthPart(row, monthPartRaw, "购买时长(月)", func(value int) {
|
||||
row.DurationMonthPart = value
|
||||
checkConsistency(row, "购买时长(月)", strconv.Itoa(value), consistentMonthPart)
|
||||
})
|
||||
row.DurationMonths = row.DurationYears*12 + row.DurationMonthPart
|
||||
if row.DurationMonths <= 0 {
|
||||
row.AddReason("购买时长必须大于0")
|
||||
}
|
||||
return
|
||||
}
|
||||
parseRequiredPositiveInt(row, excelField(parsed, "durationMonths"), "套餐购买时长(月)", func(value int) {
|
||||
row.DurationMonths = value
|
||||
row.DurationYears = value / 12
|
||||
row.DurationMonthPart = value % 12
|
||||
checkConsistency(row, "套餐购买时长(月)", strconv.Itoa(value), consistentMonthPart)
|
||||
})
|
||||
}
|
||||
|
||||
func parseExcelGiftDuration(row *Row, parsed excel.ParsedRow, consistentYears, consistentMonthPart *consistencyValue) {
|
||||
yearsRaw := excelField(parsed, "giftDurationYears")
|
||||
monthPartRaw := excelField(parsed, "giftDurationMonthPart")
|
||||
if strings.TrimSpace(yearsRaw) != "" || strings.TrimSpace(monthPartRaw) != "" {
|
||||
parseOptionalNonNegativeInt(row, yearsRaw, "赠送时长(年)", 0, func(value int) {
|
||||
row.GiftDurationYears = value
|
||||
checkConsistency(row, "赠送时长(年)", strconv.Itoa(value), consistentYears)
|
||||
})
|
||||
parseOptionalMonthPart(row, monthPartRaw, "赠送时长(月)", func(value int) {
|
||||
row.GiftDurationMonthPart = value
|
||||
checkConsistency(row, "赠送时长(月)", strconv.Itoa(value), consistentMonthPart)
|
||||
})
|
||||
row.GiftDurationMonths = row.GiftDurationYears*12 + row.GiftDurationMonthPart
|
||||
return
|
||||
}
|
||||
parseOptionalNonNegativeInt(row, excelField(parsed, "giftDurationMonths"), "赠送时长(月)", 0, func(value int) {
|
||||
row.GiftDurationMonths = value
|
||||
row.GiftDurationYears = value / 12
|
||||
row.GiftDurationMonthPart = value % 12
|
||||
checkConsistency(row, "赠送时长(月)", strconv.Itoa(value), consistentMonthPart)
|
||||
})
|
||||
}
|
||||
|
||||
func checkConsistency(row *Row, field, normalized string, base *consistencyValue) {
|
||||
if row == nil || !row.Valid() {
|
||||
return
|
||||
}
|
||||
if base.rowNo == 0 {
|
||||
base.rowNo = row.RowNo
|
||||
base.normalized = normalized
|
||||
return
|
||||
}
|
||||
if base.normalized != normalized {
|
||||
row.AddReason(fmt.Sprintf("%s与第%d行不一致", field, base.rowNo))
|
||||
}
|
||||
}
|
||||
|
||||
func parseRequiredPositiveInt(row *Row, raw, field string, apply func(value int)) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
row.AddReason(field + "不能为空")
|
||||
return
|
||||
}
|
||||
value, err := excel.ParsePositiveInt(raw)
|
||||
if err != nil {
|
||||
row.AddReason(field + "格式不正确")
|
||||
return
|
||||
}
|
||||
apply(value)
|
||||
}
|
||||
|
||||
func parseOptionalNonNegativeInt(row *Row, raw, field string, defaultValue int, apply func(value int)) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
apply(defaultValue)
|
||||
return
|
||||
}
|
||||
value, err := excel.ParseNonNegativeInt(raw)
|
||||
if err != nil {
|
||||
row.AddReason(field + "格式不正确")
|
||||
return
|
||||
}
|
||||
apply(value)
|
||||
}
|
||||
|
||||
func parseOptionalMonthPart(row *Row, raw, field string, apply func(value int)) {
|
||||
parseOptionalNonNegativeInt(row, raw, field, 0, func(value int) {
|
||||
if value > 11 {
|
||||
row.AddReason(field + "必须在0到11之间")
|
||||
return
|
||||
}
|
||||
apply(value)
|
||||
})
|
||||
}
|
||||
|
||||
func parseOptionalAmount(row *Row, raw string, apply func(value string)) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
apply("")
|
||||
return
|
||||
}
|
||||
value, err := excel.ParseAmount(raw)
|
||||
if err != nil {
|
||||
row.AddReason("订单金额格式不正确")
|
||||
return
|
||||
}
|
||||
apply(fmt.Sprintf("%.2f", value))
|
||||
}
|
||||
|
||||
func parseRequiredAmount(row *Row, raw string, apply func(value string)) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
row.AddReason("订单金额不能为空")
|
||||
return
|
||||
}
|
||||
parseOptionalAmount(row, raw, apply)
|
||||
}
|
||||
|
||||
func parseRequiredBool(row *Row, raw, field string, apply func(value bool)) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
row.AddReason(field + "不能为空")
|
||||
return
|
||||
}
|
||||
value, err := excel.ParseBool(raw)
|
||||
if err != nil {
|
||||
row.AddReason(field + "格式不正确")
|
||||
return
|
||||
}
|
||||
apply(value)
|
||||
}
|
||||
|
||||
func parseRequiredDateTime(row *Row, raw, field string, apply func(value *gtime.Time)) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
row.AddReason(field + "不能为空")
|
||||
return
|
||||
}
|
||||
value, err := excel.ParseDateTime(raw)
|
||||
if err != nil {
|
||||
row.AddReason(field + "格式不正确")
|
||||
return
|
||||
}
|
||||
apply(value)
|
||||
}
|
||||
Reference in New Issue
Block a user