642 lines
20 KiB
Go
642 lines
20 KiB
Go
package upstreamimpl
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"math"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"git.5iot.com/iotlcm-public/iotlcm-upstream-chan/internal/consts"
|
|
"git.5iot.com/iotlcm-public/iotlcm-upstream-chan/internal/logic/upstreamimpl/dx"
|
|
"git.5iot.com/iotlcm-public/iotlcm-upstream-chan/internal/model"
|
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
)
|
|
|
|
const (
|
|
dxBatchStatusLimit = 10000
|
|
dxBatchUsageLimit = 100
|
|
)
|
|
|
|
type telecomBatchKey struct {
|
|
index int
|
|
simKey *model.SimKey
|
|
accessNumber string
|
|
}
|
|
|
|
type dxBatchRequest struct {
|
|
AccessNumbers []string `json:"accessNumbers"`
|
|
CustNumber string `json:"custNumber"`
|
|
GroupID string `json:"groupId,omitempty"`
|
|
SimStatus string `json:"simStatus,omitempty"`
|
|
FlowDate string `json:"flowDate,omitempty"`
|
|
}
|
|
|
|
type dxBatchStatusResponse struct {
|
|
Code any `json:"code"`
|
|
Message string `json:"message"`
|
|
Msg string `json:"msg"`
|
|
Data struct {
|
|
QrySimStatusList []dxBatchStatusItem `json:"qrySimStatusList"`
|
|
StatusList []dxBatchStatusItem `json:"statusList"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
type dxBatchStatusItem struct {
|
|
AccessNumber string `json:"accessNumber"`
|
|
AccNum string `json:"accNum"`
|
|
Result any `json:"result"`
|
|
Iccid string `json:"iccid"`
|
|
Imsi string `json:"imsi"`
|
|
SimStatus any `json:"simStatus"`
|
|
}
|
|
|
|
type dxBatchFlowResponse struct {
|
|
Code any `json:"code"`
|
|
Message string `json:"message"`
|
|
Msg string `json:"msg"`
|
|
Data []dxBatchFlowItem `json:"data"`
|
|
}
|
|
|
|
type dxBatchFlowItem struct {
|
|
AccessNumber string `json:"accessNumber"`
|
|
AccNum string `json:"accNum"`
|
|
Result any `json:"result"`
|
|
Unit string `json:"unit"`
|
|
FlowAmount any `json:"flowAmount"`
|
|
FlowDate string `json:"flowDate"`
|
|
FlowDay string `json:"flowDay"`
|
|
}
|
|
|
|
func parseDXCustNumber(ctx context.Context, channelConfig *model.SimChannelConfigItemCache) string {
|
|
if channelConfig == nil || channelConfig.Channel == nil {
|
|
return ""
|
|
}
|
|
var cfg struct {
|
|
CustNumber string `json:"custNumber"`
|
|
}
|
|
if err := json.Unmarshal([]byte(channelConfig.Channel.ChanConfig), &cfg); err != nil {
|
|
g.Log().Warningf(ctx, "parse telecom channel config failed, chanKey=%s err=%+v", channelConfig.Channel.ChanKey, err)
|
|
return ""
|
|
}
|
|
return strings.TrimSpace(cfg.CustNumber)
|
|
}
|
|
|
|
func parseDXBaseURL(ctx context.Context, channelConfig *model.SimChannelConfigItemCache) string {
|
|
if channelConfig == nil || channelConfig.Channel == nil {
|
|
return ""
|
|
}
|
|
if channelConfig.Template != nil {
|
|
var template struct {
|
|
API struct {
|
|
BaseURL string `json:"baseUrl"`
|
|
} `json:"api"`
|
|
}
|
|
if err := json.Unmarshal([]byte(channelConfig.Template.TempConfig), &template); err == nil && strings.TrimSpace(template.API.BaseURL) != "" {
|
|
return strings.TrimRight(strings.TrimSpace(template.API.BaseURL), "/")
|
|
}
|
|
}
|
|
var cfg struct {
|
|
BaseURL string `json:"baseURL"`
|
|
URL string `json:"url"`
|
|
}
|
|
if err := json.Unmarshal([]byte(channelConfig.Channel.ChanConfig), &cfg); err != nil {
|
|
g.Log().Warningf(ctx, "parse telecom channel config failed, chanKey=%s err=%+v", channelConfig.Channel.ChanKey, err)
|
|
return ""
|
|
}
|
|
baseURL := strings.TrimSpace(firstNonEmpty(cfg.BaseURL, cfg.URL))
|
|
if baseURL == "" {
|
|
baseURL = strings.TrimSpace(g.Cfg().MustGet(ctx, "dependencies.sim_dx_v1.url", dx.DefaultBaseURL).String())
|
|
}
|
|
return strings.TrimRight(baseURL, "/")
|
|
}
|
|
|
|
func (s *sSimDX) QuerySimCardStatusBatch(ctx context.Context, input *model.SimCardStatusInput) (model.SimCardStatusOutput, error) {
|
|
return s.queryCardStatusBatch(ctx, input)
|
|
}
|
|
|
|
func (s *sSimDX) QuerySimDataUsageMonthlyBatch(ctx context.Context, input *model.SimDataUsageMonthlyInput) (model.SimDataUsageMonthlyOutput, error) {
|
|
return s.queryDataUsageMonthlyBatch(ctx, input)
|
|
}
|
|
|
|
func (s *sSimDX) QuerySimDataUsageDailyBatch(ctx context.Context, input *model.SimDataUsageDailyInput) (model.SimDataUsageDailyOutput, error) {
|
|
return s.queryDataUsageDailyBatch(ctx, input)
|
|
}
|
|
|
|
func (s *sSimDX) queryCardStatusBatch(ctx context.Context, input *model.SimCardStatusInput) (model.SimCardStatusOutput, error) {
|
|
if err := s.ensureDXBatchConfig(); err != nil {
|
|
return nil, err
|
|
}
|
|
if input == nil || len(input.SimKeys) == 0 {
|
|
return make(model.SimCardStatusOutput, 0), nil
|
|
}
|
|
|
|
results := make(model.SimCardStatusOutput, len(input.SimKeys))
|
|
pending := make([]telecomBatchKey, 0, len(input.SimKeys))
|
|
for i, simKey := range input.SimKeys {
|
|
if simKey == nil || strings.TrimSpace(simKey.MSISDN) == "" {
|
|
results[i] = &model.SimBaseRes[model.SimCardStatusItem]{
|
|
SimKey: simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: "MSISDN not found",
|
|
}
|
|
continue
|
|
}
|
|
pending = append(pending, telecomBatchKey{
|
|
index: i,
|
|
simKey: simKey,
|
|
accessNumber: strings.TrimSpace(simKey.MSISDN),
|
|
})
|
|
}
|
|
|
|
for _, chunk := range chunkTelecomBatchKeys(pending, dxBatchStatusLimit) {
|
|
accessNumbers := make([]string, 0, len(chunk))
|
|
for _, item := range chunk {
|
|
accessNumbers = append(accessNumbers, item.accessNumber)
|
|
}
|
|
|
|
resp, err := s.doDXBatchStatusPost(ctx, "/api/v1/prod/batchQrySimStatus", dxBatchRequest{
|
|
AccessNumbers: accessNumbers,
|
|
CustNumber: s.custNumber,
|
|
GroupID: "",
|
|
SimStatus: "",
|
|
})
|
|
if err != nil {
|
|
for _, item := range chunk {
|
|
results[item.index] = &model.SimBaseRes[model.SimCardStatusItem]{
|
|
SimKey: item.simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: err.Error(),
|
|
}
|
|
}
|
|
continue
|
|
}
|
|
|
|
batchItems := resp.Data.QrySimStatusList
|
|
if len(batchItems) == 0 {
|
|
batchItems = resp.Data.StatusList
|
|
}
|
|
itemMap := make(map[string]dxBatchStatusItem, len(batchItems))
|
|
for _, item := range batchItems {
|
|
accessNumber := telecomBatchAccessNumber(item.AccessNumber, item.AccNum)
|
|
if accessNumber == "" {
|
|
continue
|
|
}
|
|
itemMap[accessNumber] = item
|
|
}
|
|
|
|
for _, item := range chunk {
|
|
batchItem, ok := itemMap[item.accessNumber]
|
|
if !ok {
|
|
results[item.index] = &model.SimBaseRes[model.SimCardStatusItem]{
|
|
SimKey: item.simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: "batch response missing accessNumber",
|
|
}
|
|
continue
|
|
}
|
|
|
|
itemResult := gconv.String(batchItem.Result)
|
|
itemStatus := gconv.String(batchItem.SimStatus)
|
|
if itemResult != "1" {
|
|
results[item.index] = &model.SimBaseRes[model.SimCardStatusItem]{
|
|
SimKey: item.simKey,
|
|
Code: telecomBatchResultCode(itemResult),
|
|
Message: firstNonEmpty(resp.Message, resp.Msg, "telecom batch status query failed"),
|
|
ResData: model.SimCardStatusItem{
|
|
CardStatus: 0,
|
|
LastChangeDate: "",
|
|
},
|
|
}
|
|
continue
|
|
}
|
|
if itemStatus == "" {
|
|
results[item.index] = &model.SimBaseRes[model.SimCardStatusItem]{
|
|
SimKey: item.simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: "simStatus missing in batch response",
|
|
}
|
|
continue
|
|
}
|
|
|
|
results[item.index] = &model.SimBaseRes[model.SimCardStatusItem]{
|
|
SimKey: item.simKey,
|
|
Code: 0,
|
|
Message: "",
|
|
ResData: model.SimCardStatusItem{
|
|
CardStatus: convertDXBatchCardStatus(ctx, itemStatus),
|
|
LastChangeDate: "",
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
return compactStatusBatchResults(results), nil
|
|
}
|
|
|
|
func (s *sSimDX) queryDataUsageMonthlyBatch(ctx context.Context, input *model.SimDataUsageMonthlyInput) (model.SimDataUsageMonthlyOutput, error) {
|
|
if err := s.ensureDXBatchConfig(); err != nil {
|
|
return nil, err
|
|
}
|
|
if input == nil || len(input.SimKeys) == 0 {
|
|
return make(model.SimDataUsageMonthlyOutput, 0), nil
|
|
}
|
|
queryMonth := strings.TrimSpace(input.ReqData.QueryDate)
|
|
if queryMonth == "" {
|
|
return nil, fmt.Errorf("queryDate is required")
|
|
}
|
|
if _, err := time.Parse("200601", queryMonth); err != nil {
|
|
return nil, fmt.Errorf("invalid queryDate: %s", queryMonth)
|
|
}
|
|
if !dxBatchMonthAvailable(queryMonth, time.Now()) {
|
|
return nil, fmt.Errorf("电信月批量接口仅支持当月;历史月份请使用 /sim/query/sim-datausage-monthly")
|
|
}
|
|
|
|
results := make(model.SimDataUsageMonthlyOutput, len(input.SimKeys))
|
|
pending := make([]telecomBatchKey, 0, len(input.SimKeys))
|
|
for i, simKey := range input.SimKeys {
|
|
if simKey == nil || strings.TrimSpace(simKey.MSISDN) == "" {
|
|
results[i] = &model.SimBaseRes[model.SimDataUsageMonthlyOutputItem]{
|
|
SimKey: simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: "MSISDN not found",
|
|
ResData: model.SimDataUsageMonthlyOutputItem{},
|
|
}
|
|
continue
|
|
}
|
|
pending = append(pending, telecomBatchKey{
|
|
index: i,
|
|
simKey: simKey,
|
|
accessNumber: strings.TrimSpace(simKey.MSISDN),
|
|
})
|
|
}
|
|
|
|
for _, chunk := range chunkTelecomBatchKeys(pending, dxBatchUsageLimit) {
|
|
accessNumbers := make([]string, 0, len(chunk))
|
|
for _, item := range chunk {
|
|
accessNumbers = append(accessNumbers, item.accessNumber)
|
|
}
|
|
|
|
resp, err := s.doDXBatchFlowPost(ctx, "/api/v1/batchQry/batchQryFlowByMonth", dxBatchRequest{
|
|
AccessNumbers: accessNumbers,
|
|
CustNumber: s.custNumber,
|
|
})
|
|
if err != nil {
|
|
for _, item := range chunk {
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageMonthlyOutputItem]{
|
|
SimKey: item.simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: err.Error(),
|
|
ResData: model.SimDataUsageMonthlyOutputItem{DeadLine: queryMonth},
|
|
}
|
|
}
|
|
continue
|
|
}
|
|
|
|
itemMap := make(map[string]dxBatchFlowItem, len(resp.Data))
|
|
for _, item := range resp.Data {
|
|
accessNumber := telecomBatchAccessNumber(item.AccessNumber, item.AccNum)
|
|
if accessNumber == "" {
|
|
continue
|
|
}
|
|
itemMap[accessNumber] = item
|
|
}
|
|
|
|
for _, item := range chunk {
|
|
batchItem, ok := itemMap[item.accessNumber]
|
|
if !ok {
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageMonthlyOutputItem]{
|
|
SimKey: item.simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: "batch response missing accessNumber",
|
|
ResData: model.SimDataUsageMonthlyOutputItem{},
|
|
}
|
|
continue
|
|
}
|
|
|
|
itemResult := gconv.String(batchItem.Result)
|
|
dataAmount, amountErr := parseDXBatchAmount(batchItem)
|
|
if itemResult == "1" && amountErr != nil {
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageMonthlyOutputItem]{SimKey: item.simKey, Code: consts.ApiStatusError, Message: amountErr.Error()}
|
|
continue
|
|
}
|
|
if itemResult != "1" {
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageMonthlyOutputItem]{
|
|
SimKey: item.simKey,
|
|
Code: telecomBatchResultCode(itemResult),
|
|
Message: firstNonEmpty(resp.Message, resp.Msg, "telecom batch monthly usage query failed"),
|
|
ResData: model.SimDataUsageMonthlyOutputItem{
|
|
DeadLine: queryMonth,
|
|
DataAmount: dataAmount,
|
|
},
|
|
}
|
|
continue
|
|
}
|
|
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageMonthlyOutputItem]{
|
|
SimKey: item.simKey,
|
|
Code: 0,
|
|
Message: "",
|
|
ResData: model.SimDataUsageMonthlyOutputItem{
|
|
DeadLine: queryMonth,
|
|
DataAmount: dataAmount,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
return compactMonthlyBatchResults(results), nil
|
|
}
|
|
|
|
func (s *sSimDX) queryDataUsageDailyBatch(ctx context.Context, input *model.SimDataUsageDailyInput) (model.SimDataUsageDailyOutput, error) {
|
|
if err := s.ensureDXBatchConfig(); err != nil {
|
|
return nil, err
|
|
}
|
|
if input == nil || len(input.SimKeys) == 0 {
|
|
return make(model.SimDataUsageDailyOutput, 0), nil
|
|
}
|
|
queryDate := strings.TrimSpace(input.ReqData.QueryDate)
|
|
if queryDate == "" {
|
|
return nil, fmt.Errorf("queryDate is required")
|
|
}
|
|
if _, err := time.Parse("20060102", queryDate); err != nil {
|
|
return nil, fmt.Errorf("invalid queryDate: %s", queryDate)
|
|
}
|
|
if !dxBatchDayAvailable(queryDate, time.Now()) {
|
|
return nil, fmt.Errorf("电信日批量接口仅支持最近7个已结束日期")
|
|
}
|
|
|
|
results := make(model.SimDataUsageDailyOutput, len(input.SimKeys))
|
|
pending := make([]telecomBatchKey, 0, len(input.SimKeys))
|
|
for i, simKey := range input.SimKeys {
|
|
if simKey == nil || strings.TrimSpace(simKey.MSISDN) == "" {
|
|
results[i] = &model.SimBaseRes[model.SimDataUsageDailyOutputItem]{
|
|
SimKey: simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: "MSISDN not found",
|
|
ResData: model.SimDataUsageDailyOutputItem{QueryDate: queryDate},
|
|
}
|
|
continue
|
|
}
|
|
pending = append(pending, telecomBatchKey{
|
|
index: i,
|
|
simKey: simKey,
|
|
accessNumber: strings.TrimSpace(simKey.MSISDN),
|
|
})
|
|
}
|
|
|
|
for _, chunk := range chunkTelecomBatchKeys(pending, dxBatchUsageLimit) {
|
|
accessNumbers := make([]string, 0, len(chunk))
|
|
for _, item := range chunk {
|
|
accessNumbers = append(accessNumbers, item.accessNumber)
|
|
}
|
|
|
|
resp, err := s.doDXBatchFlowPost(ctx, "/api/v1/batchQry/batchQryFlowByDate", dxBatchRequest{
|
|
AccessNumbers: accessNumbers,
|
|
CustNumber: s.custNumber,
|
|
FlowDate: queryDate,
|
|
})
|
|
if err != nil {
|
|
for _, item := range chunk {
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageDailyOutputItem]{
|
|
SimKey: item.simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: err.Error(),
|
|
ResData: model.SimDataUsageDailyOutputItem{QueryDate: queryDate},
|
|
}
|
|
}
|
|
continue
|
|
}
|
|
|
|
itemMap := make(map[string]dxBatchFlowItem, len(resp.Data))
|
|
for _, item := range resp.Data {
|
|
accessNumber := telecomBatchAccessNumber(item.AccessNumber, item.AccNum)
|
|
if accessNumber == "" {
|
|
continue
|
|
}
|
|
itemMap[accessNumber] = item
|
|
}
|
|
|
|
for _, item := range chunk {
|
|
batchItem, ok := itemMap[item.accessNumber]
|
|
if !ok {
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageDailyOutputItem]{
|
|
SimKey: item.simKey,
|
|
Code: consts.ApiStatusError,
|
|
Message: "batch response missing accessNumber",
|
|
ResData: model.SimDataUsageDailyOutputItem{QueryDate: queryDate},
|
|
}
|
|
continue
|
|
}
|
|
|
|
itemResult := gconv.String(batchItem.Result)
|
|
dataAmount, amountErr := parseDXBatchAmount(batchItem)
|
|
if itemResult == "1" && amountErr != nil {
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageDailyOutputItem]{SimKey: item.simKey, Code: consts.ApiStatusError, Message: amountErr.Error()}
|
|
continue
|
|
}
|
|
batchQueryDate := firstNonEmpty(strings.TrimSpace(batchItem.FlowDate), strings.TrimSpace(batchItem.FlowDay))
|
|
if batchQueryDate == "" {
|
|
batchQueryDate = queryDate
|
|
}
|
|
if batchQueryDate != queryDate {
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageDailyOutputItem]{SimKey: item.simKey, Code: consts.ApiStatusError, Message: "batch response date mismatched"}
|
|
continue
|
|
}
|
|
if itemResult != "1" {
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageDailyOutputItem]{
|
|
SimKey: item.simKey,
|
|
Code: telecomBatchResultCode(itemResult),
|
|
Message: firstNonEmpty(resp.Message, resp.Msg, "telecom batch daily usage query failed"),
|
|
ResData: model.SimDataUsageDailyOutputItem{
|
|
QueryDate: batchQueryDate,
|
|
DataAmount: dataAmount,
|
|
},
|
|
}
|
|
continue
|
|
}
|
|
|
|
results[item.index] = &model.SimBaseRes[model.SimDataUsageDailyOutputItem]{
|
|
SimKey: item.simKey,
|
|
Code: 0,
|
|
Message: "",
|
|
ResData: model.SimDataUsageDailyOutputItem{
|
|
QueryDate: batchQueryDate,
|
|
DataAmount: dataAmount,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
return compactDailyBatchResults(results), nil
|
|
}
|
|
|
|
func (s *sSimDX) ensureDXBatchConfig() error {
|
|
if strings.TrimSpace(s.custNumber) == "" {
|
|
return fmt.Errorf("telecom custNumber not configured")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
var dxBatchLocation = time.FixedZone("UTC+8", 8*60*60)
|
|
|
|
func parseDXBatchAmount(item dxBatchFlowItem) (float64, error) {
|
|
amount, err := strconv.ParseFloat(strings.TrimSpace(gconv.String(item.FlowAmount)), 64)
|
|
if err != nil || math.IsNaN(amount) || math.IsInf(amount, 0) || amount < 0 {
|
|
return 0, fmt.Errorf("invalid telecom batch flowAmount")
|
|
}
|
|
if unit := strings.ToUpper(strings.TrimSpace(item.Unit)); unit != "" && unit != "MB" {
|
|
return 0, fmt.Errorf("unexpected telecom batch usage unit: %s", unit)
|
|
}
|
|
return amount, nil
|
|
}
|
|
|
|
func dailyBatchOutputSuccessful(input *model.SimDataUsageDailyInput, output model.SimDataUsageDailyOutput) bool {
|
|
if input == nil || len(output) != len(input.SimKeys) {
|
|
return false
|
|
}
|
|
queryDate := strings.TrimSpace(input.ReqData.QueryDate)
|
|
for _, item := range output {
|
|
if item == nil || item.Code != 0 || item.ResData.QueryDate != queryDate {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func dxBatchDayAvailable(queryDate string, now time.Time) bool {
|
|
date, err := time.ParseInLocation("20060102", strings.TrimSpace(queryDate), dxBatchLocation)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
now = now.In(dxBatchLocation)
|
|
today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, dxBatchLocation)
|
|
// CTIOT_5GCMP_UQ013 only accepts one completed day within the latest 7 days.
|
|
return !date.Before(today.AddDate(0, 0, -7)) && date.Before(today)
|
|
}
|
|
|
|
func dxBatchMonthAvailable(queryMonth string, now time.Time) bool {
|
|
month, err := time.ParseInLocation("200601", strings.TrimSpace(queryMonth), dxBatchLocation)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
now = now.In(dxBatchLocation)
|
|
// CTIOT_5GCMP_UQ014 is explicitly a current-month batch endpoint.
|
|
return month.Year() == now.Year() && month.Month() == now.Month()
|
|
}
|
|
|
|
func (s *sSimDX) doDXBatchPost(ctx context.Context, endpoint string, req dxBatchRequest) ([]byte, error) {
|
|
body, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return s.client.DoPostJSONRequest(ctx, endpoint, body)
|
|
}
|
|
|
|
func (s *sSimDX) doDXBatchStatusPost(ctx context.Context, endpoint string, req dxBatchRequest) (*dxBatchStatusResponse, error) {
|
|
respBody, err := s.doDXBatchPost(ctx, endpoint, req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var resp dxBatchStatusResponse
|
|
if err := json.Unmarshal(respBody, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
if gconv.String(resp.Code) != "0" {
|
|
return nil, fmt.Errorf("telecom batch status request failed: code=%s message=%s", gconv.String(resp.Code), firstNonEmpty(resp.Message, resp.Msg))
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
func (s *sSimDX) doDXBatchFlowPost(ctx context.Context, endpoint string, req dxBatchRequest) (*dxBatchFlowResponse, error) {
|
|
respBody, err := s.doDXBatchPost(ctx, endpoint, req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var resp dxBatchFlowResponse
|
|
if err := json.Unmarshal(respBody, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
if gconv.String(resp.Code) != "0" {
|
|
return nil, fmt.Errorf("telecom batch flow request failed: code=%s message=%s", gconv.String(resp.Code), firstNonEmpty(resp.Message, resp.Msg))
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
func chunkTelecomBatchKeys(items []telecomBatchKey, size int) [][]telecomBatchKey {
|
|
if size <= 0 {
|
|
size = 1
|
|
}
|
|
if len(items) == 0 {
|
|
return nil
|
|
}
|
|
chunks := make([][]telecomBatchKey, 0, (len(items)+size-1)/size)
|
|
for start := 0; start < len(items); start += size {
|
|
end := start + size
|
|
if end > len(items) {
|
|
end = len(items)
|
|
}
|
|
chunks = append(chunks, items[start:end])
|
|
}
|
|
return chunks
|
|
}
|
|
|
|
func telecomBatchAccessNumber(values ...string) string {
|
|
for _, value := range values {
|
|
if value = strings.TrimSpace(value); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func telecomBatchResultCode(result string) int {
|
|
result = strings.TrimSpace(result)
|
|
if result == "" {
|
|
return consts.ApiStatusError
|
|
}
|
|
return gconv.Int(result)
|
|
}
|
|
|
|
func firstNonEmpty(values ...string) string {
|
|
for _, value := range values {
|
|
if strings.TrimSpace(value) != "" {
|
|
return value
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func compactStatusBatchResults(items model.SimCardStatusOutput) model.SimCardStatusOutput {
|
|
output := make(model.SimCardStatusOutput, 0, len(items))
|
|
for _, item := range items {
|
|
if item != nil {
|
|
output = append(output, item)
|
|
}
|
|
}
|
|
return output
|
|
}
|
|
|
|
func compactMonthlyBatchResults(items model.SimDataUsageMonthlyOutput) model.SimDataUsageMonthlyOutput {
|
|
output := make(model.SimDataUsageMonthlyOutput, 0, len(items))
|
|
for _, item := range items {
|
|
if item != nil {
|
|
output = append(output, item)
|
|
}
|
|
}
|
|
return output
|
|
}
|
|
|
|
func compactDailyBatchResults(items model.SimDataUsageDailyOutput) model.SimDataUsageDailyOutput {
|
|
output := make(model.SimDataUsageDailyOutput, 0, len(items))
|
|
for _, item := range items {
|
|
if item != nil {
|
|
output = append(output, item)
|
|
}
|
|
}
|
|
return output
|
|
}
|