chore: 并入 iotlcm-admin-svr 历史到 admin-svr/(原提交 49818c6)
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
package packageduration
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
const (
|
||||
FlowCycleUnitMonth = "month"
|
||||
RenewUnitYear = "year"
|
||||
)
|
||||
|
||||
// Policy is the normalized duration contract used by package-related business.
|
||||
// The database keeps the existing fields; this type separates their meanings.
|
||||
type Policy struct {
|
||||
FlowCycleUnit string
|
||||
RenewUnit string
|
||||
RenewableYears []int
|
||||
ChangeMonths []int
|
||||
}
|
||||
|
||||
func FromPackage(pkg *entity.TSimFlowPackageInfo) (*Policy, error) {
|
||||
if pkg == nil {
|
||||
return nil, gerror.New("package information is empty")
|
||||
}
|
||||
years, err := RenewableYears(pkg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
months, err := ChangeMonths(pkg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Policy{
|
||||
FlowCycleUnit: FlowCycleUnitMonth,
|
||||
RenewUnit: RenewUnitYear,
|
||||
RenewableYears: years,
|
||||
ChangeMonths: months,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func MonthBillingMethodValue() string {
|
||||
return strconv.Itoa(consts.BillingMethodMonth)
|
||||
}
|
||||
|
||||
func RenewableYears(pkg *entity.TSimFlowPackageInfo) ([]int, error) {
|
||||
if pkg == nil {
|
||||
return nil, gerror.New("package information is empty")
|
||||
}
|
||||
return renewableYearsFromConfig(pkg.RenewableDurationConfig)
|
||||
}
|
||||
|
||||
func ChangeMonths(pkg *entity.TSimFlowPackageInfo) ([]int, error) {
|
||||
if pkg == nil {
|
||||
return nil, gerror.New("package information is empty")
|
||||
}
|
||||
values, legacyMonthConfig, err := rawDurationValues(pkg.RenewableDurationConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if legacyMonthConfig {
|
||||
return uniqueSorted(values), nil
|
||||
}
|
||||
|
||||
months := make([]int, 0, len(values))
|
||||
for _, year := range values {
|
||||
if year <= 0 {
|
||||
continue
|
||||
}
|
||||
months = append(months, year*12)
|
||||
}
|
||||
months = uniqueSorted(months)
|
||||
if len(months) == 0 {
|
||||
return nil, gerror.New("package has no valid change duration options")
|
||||
}
|
||||
return months, nil
|
||||
}
|
||||
|
||||
// NormalizeRenewableDurationConfig converts legacy month values such as
|
||||
// [12,24,36] into the new year values [1,2,3] before saving a package.
|
||||
func NormalizeRenewableDurationConfig(config *gjson.Json) (*gjson.Json, error) {
|
||||
values, legacyMonthConfig, err := rawDurationValues(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if legacyMonthConfig {
|
||||
years := make([]int, 0, len(values))
|
||||
for _, month := range values {
|
||||
if month > 0 && month%12 == 0 {
|
||||
years = append(years, month/12)
|
||||
}
|
||||
}
|
||||
years = uniqueSorted(years)
|
||||
if len(years) == 0 {
|
||||
return nil, gerror.New("package has no valid renewable duration options")
|
||||
}
|
||||
return gjson.New(years), nil
|
||||
}
|
||||
return gjson.New(uniqueSorted(values)), nil
|
||||
}
|
||||
|
||||
func NormalizeRenewableYears(values []int) []int {
|
||||
values = uniqueSorted(values)
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
legacyMonthConfig := true
|
||||
for _, value := range values {
|
||||
if value < 12 || value%12 != 0 {
|
||||
legacyMonthConfig = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !legacyMonthConfig {
|
||||
return values
|
||||
}
|
||||
years := make([]int, 0, len(values))
|
||||
for _, month := range values {
|
||||
if month > 0 && month%12 == 0 {
|
||||
years = append(years, month/12)
|
||||
}
|
||||
}
|
||||
return uniqueSorted(years)
|
||||
}
|
||||
|
||||
func RenewMonths(years int) int {
|
||||
if years <= 0 {
|
||||
return 0
|
||||
}
|
||||
return years * 12
|
||||
}
|
||||
|
||||
func renewableYearsFromConfig(config *gjson.Json) ([]int, error) {
|
||||
values, legacyMonthConfig, err := rawDurationValues(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
years := make([]int, 0, len(values))
|
||||
for _, value := range values {
|
||||
if value <= 0 {
|
||||
continue
|
||||
}
|
||||
if legacyMonthConfig {
|
||||
if value%12 != 0 {
|
||||
continue
|
||||
}
|
||||
value /= 12
|
||||
}
|
||||
years = append(years, value)
|
||||
}
|
||||
years = uniqueSorted(years)
|
||||
if len(years) == 0 {
|
||||
return nil, gerror.New("package has no valid renewable duration options")
|
||||
}
|
||||
return years, nil
|
||||
}
|
||||
|
||||
func rawDurationValues(config *gjson.Json) ([]int, bool, error) {
|
||||
if config == nil || config.IsNil() {
|
||||
return nil, false, gerror.New("package has no renewable duration config")
|
||||
}
|
||||
values := config.Interfaces()
|
||||
if len(values) == 0 {
|
||||
return nil, false, gerror.New("package has no renewable duration config")
|
||||
}
|
||||
|
||||
result := make([]int, 0, len(values))
|
||||
for _, value := range values {
|
||||
parsed := gconv.Int(value)
|
||||
if parsed > 0 {
|
||||
result = append(result, parsed)
|
||||
}
|
||||
}
|
||||
result = uniqueSorted(result)
|
||||
if len(result) == 0 {
|
||||
return nil, false, gerror.New("package has no valid renewable duration options")
|
||||
}
|
||||
|
||||
legacyMonthConfig := true
|
||||
for _, value := range result {
|
||||
if value < 12 || value%12 != 0 {
|
||||
legacyMonthConfig = false
|
||||
break
|
||||
}
|
||||
}
|
||||
return result, legacyMonthConfig, nil
|
||||
}
|
||||
|
||||
func uniqueSorted(values []int) []int {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
seen := make(map[int]struct{}, len(values))
|
||||
result := make([]int, 0, len(values))
|
||||
for _, value := range values {
|
||||
if value <= 0 {
|
||||
continue
|
||||
}
|
||||
if _, exists := seen[value]; exists {
|
||||
continue
|
||||
}
|
||||
seen[value] = struct{}{}
|
||||
result = append(result, value)
|
||||
}
|
||||
sort.Ints(result)
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user