4e2cd43a55
iotlcm-onelink-mock:OneLink 挡板服务(本地测试替身)。 - Go module 迁移至 git.5iot.com/iotlcm-public/iotlcm-onelink-mock - 修复同毫秒内多次生成卡导致 ICCID/IMSI 唯一约束冲突 - 补 Apache-2.0 LICENSE,README 重写并新增 docs/deploy.md - 移除内部部署资产(CI 触发器 / 镜像推送脚本 / 指定环境部署文档) - 测试凭据改为 demo_appid / demo_password,真实手机号与内网 IP 脱敏 - 统一 LF 行尾并加 .gitattributes
613 lines
17 KiB
Go
613 lines
17 KiB
Go
package service
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
chanSuccessCode = 0
|
|
chanErrorCode = 9999
|
|
)
|
|
|
|
type chanSimKey struct {
|
|
ChanKey string `json:"chanKey"`
|
|
ICCID string `json:"iccid"`
|
|
IMSI string `json:"imsi"`
|
|
MSISDN string `json:"msisdn"`
|
|
}
|
|
|
|
type chanRequest struct {
|
|
SimKeys []chanSimKey `json:"simKeys"`
|
|
ReqData json.RawMessage `json:"reqData"`
|
|
}
|
|
|
|
type chanResponse[T any] struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
SimKey chanSimKey `json:"simKey"`
|
|
ResData T `json:"resData"`
|
|
}
|
|
|
|
type chanBasicInfo struct {
|
|
ActiveDate string `json:"activeDate"`
|
|
OpenDate string `json:"openDate"`
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
type chanSession struct {
|
|
ApnID string `json:"apnId"`
|
|
Rat string `json:"rat"`
|
|
IPv4 string `json:"ipv4"`
|
|
IPv6 string `json:"ipv6"`
|
|
IPv6Prefix string `json:"ipv6Prefix"`
|
|
Status string `json:"status"`
|
|
CreateTime string `json:"createTime"`
|
|
}
|
|
|
|
type chanCardStatus struct {
|
|
CardStatus int `json:"cardStatus"`
|
|
LastChangeDate string `json:"lastChangeDate"`
|
|
}
|
|
|
|
type chanIMEI struct {
|
|
IMEI string `json:"imei"`
|
|
}
|
|
|
|
type chanUsage struct {
|
|
DataUsage float64 `json:"dataUsage"`
|
|
}
|
|
|
|
type chanMonthlyUsage struct {
|
|
DeadLine string `json:"deadLine"`
|
|
DataAmount float64 `json:"dataAmount"`
|
|
}
|
|
|
|
type chanDailyUsage struct {
|
|
QueryDate string `json:"queryDate"`
|
|
DataAmount float64 `json:"dataAmount"`
|
|
}
|
|
|
|
type chanAPN struct {
|
|
APNName string `json:"apnName"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
type chanAPNList struct {
|
|
APNList []chanAPN `json:"apnList"`
|
|
}
|
|
|
|
type chanOrder struct {
|
|
OrderNum string `json:"orderNum"`
|
|
}
|
|
|
|
type chanBindStatus struct {
|
|
BindStatus string `json:"bindStatus"`
|
|
}
|
|
|
|
type chanDeviceStatus struct {
|
|
DeviceStatus string `json:"deviceStatus"`
|
|
}
|
|
|
|
type chanRegionLimitStatus struct {
|
|
RegionLimitStatus string `json:"regionLimitStatus"`
|
|
}
|
|
|
|
type chanReqData struct {
|
|
QueryDate string `json:"queryDate"`
|
|
OperType string `json:"operType"`
|
|
APNName string `json:"apnName"`
|
|
TestType *int `json:"testType"`
|
|
}
|
|
|
|
func (s *Service) chanAPI(w http.ResponseWriter, r *http.Request) {
|
|
path := strings.TrimPrefix(r.URL.Path, "/sim/")
|
|
switch path {
|
|
case "query/sim-basic-info":
|
|
s.chanQueryBasicInfo(w, r)
|
|
case "query/sim-session":
|
|
s.chanQuerySession(w, r)
|
|
case "query/sim-status", "query/sim-status-batch":
|
|
s.chanQueryStatus(w, r)
|
|
case "query/sim-card-bind-status":
|
|
s.chanQueryBindStatus(w, r)
|
|
case "query/sim-device-status":
|
|
s.chanQueryDeviceStatus(w, r)
|
|
case "query/sim-region-limit-status":
|
|
s.chanQueryRegionLimitStatus(w, r)
|
|
case "query/sim-imei":
|
|
s.chanQueryIMEI(w, r)
|
|
case "query/sim-datausage":
|
|
s.chanQueryDataUsage(w, r)
|
|
case "query/sim-datausage-monthly", "query/sim-datausage-monthly-batch":
|
|
s.chanQueryMonthly(w, r)
|
|
case "query/sim-datausage-daily", "query/sim-datausage-daily-batch":
|
|
s.chanQueryDaily(w, r)
|
|
case "query/sim-apn-info":
|
|
s.chanQueryAPN(w, r)
|
|
case "change/sim-status":
|
|
s.chanChangeStatus(w, r)
|
|
case "change/sim-apn":
|
|
s.chanChangeAPN(w, r)
|
|
default:
|
|
writeJSON(w, http.StatusNotFound, map[string]string{"message": "unknown sim endpoint"})
|
|
}
|
|
}
|
|
|
|
func parseChanRequest(r *http.Request) (chanRequest, error) {
|
|
var req chanRequest
|
|
if r.Method != http.MethodGet && r.Body != nil {
|
|
body, err := io.ReadAll(io.LimitReader(r.Body, 2<<20))
|
|
if err != nil {
|
|
return req, err
|
|
}
|
|
if len(strings.TrimSpace(string(body))) > 0 {
|
|
if err := json.Unmarshal(body, &req); err != nil {
|
|
return req, fmt.Errorf("invalid JSON body: %w", err)
|
|
}
|
|
}
|
|
}
|
|
if len(req.SimKeys) == 0 {
|
|
req.SimKeys = simKeysFromQuery(r.URL.Query())
|
|
}
|
|
if len(req.ReqData) == 0 {
|
|
data := chanReqData{
|
|
QueryDate: r.URL.Query().Get("queryDate"),
|
|
OperType: r.URL.Query().Get("operType"),
|
|
APNName: r.URL.Query().Get("apnName"),
|
|
}
|
|
if value := r.URL.Query().Get("testType"); value != "" {
|
|
if parsed, err := strconv.Atoi(value); err == nil {
|
|
data.TestType = &parsed
|
|
}
|
|
}
|
|
if data.QueryDate != "" || data.OperType != "" || data.APNName != "" || data.TestType != nil {
|
|
req.ReqData, _ = json.Marshal(data)
|
|
}
|
|
}
|
|
return req, nil
|
|
}
|
|
|
|
func simKeysFromQuery(q url.Values) []chanSimKey {
|
|
if raw := q.Get("simKeys"); raw != "" {
|
|
var keys []chanSimKey
|
|
if json.Unmarshal([]byte(raw), &keys) == nil {
|
|
return keys
|
|
}
|
|
}
|
|
var values []chanSimKey
|
|
for _, item := range []struct {
|
|
key string
|
|
name string
|
|
}{
|
|
{"iccids", "iccid"}, {"imsis", "imsi"}, {"msisdns", "msisdn"},
|
|
} {
|
|
for _, value := range splitIDs(q.Get(item.key)) {
|
|
key := chanSimKey{}
|
|
switch item.name {
|
|
case "iccid":
|
|
key.ICCID = value
|
|
case "imsi":
|
|
key.IMSI = value
|
|
case "msisdn":
|
|
key.MSISDN = value
|
|
}
|
|
values = append(values, key)
|
|
}
|
|
}
|
|
if len(values) == 0 {
|
|
key := chanSimKey{ICCID: q.Get("iccid"), IMSI: q.Get("imsi"), MSISDN: q.Get("msisdn")}
|
|
if key.ICCID != "" || key.IMSI != "" || key.MSISDN != "" {
|
|
values = append(values, key)
|
|
}
|
|
}
|
|
return values
|
|
}
|
|
|
|
func splitIDs(raw string) []string {
|
|
if raw == "" {
|
|
return nil
|
|
}
|
|
raw = strings.ReplaceAll(raw, ",", "_")
|
|
parts := strings.Split(raw, "_")
|
|
values := make([]string, 0, len(parts))
|
|
for _, part := range parts {
|
|
if value := strings.TrimSpace(part); value != "" {
|
|
values = append(values, value)
|
|
}
|
|
}
|
|
return values
|
|
}
|
|
|
|
func decodeChanReqData(req chanRequest) chanReqData {
|
|
var data chanReqData
|
|
_ = json.Unmarshal(req.ReqData, &data)
|
|
return data
|
|
}
|
|
|
|
func chanSuccess[T any](key chanSimKey, data T) chanResponse[T] {
|
|
return chanResponse[T]{Code: chanSuccessCode, Message: "success", SimKey: key, ResData: data}
|
|
}
|
|
|
|
func chanFailure[T any](key chanSimKey, message string) chanResponse[T] {
|
|
return chanResponse[T]{Code: chanErrorCode, Message: message, SimKey: key, ResData: *new(T)}
|
|
}
|
|
|
|
func writeChanResponses[T any](w http.ResponseWriter, responses []chanResponse[T]) {
|
|
writeJSON(w, http.StatusOK, responses)
|
|
}
|
|
|
|
func (s *Service) chanCards(r *http.Request) (chanRequest, Store, error) {
|
|
req, err := parseChanRequest(r)
|
|
if err != nil {
|
|
return req, Store{}, err
|
|
}
|
|
return req, s.store.Snapshot(), nil
|
|
}
|
|
|
|
func findChanCard(st Store, key chanSimKey) (SIMCard, bool) {
|
|
if key.ICCID != "" {
|
|
for _, card := range st.Cards {
|
|
if card.ICCID == key.ICCID {
|
|
return card, true
|
|
}
|
|
}
|
|
}
|
|
if key.IMSI != "" {
|
|
for _, card := range st.Cards {
|
|
if card.IMSI == key.IMSI {
|
|
return card, true
|
|
}
|
|
}
|
|
}
|
|
if key.MSISDN != "" {
|
|
for _, card := range st.Cards {
|
|
if card.MSISDN == key.MSISDN {
|
|
return card, true
|
|
}
|
|
}
|
|
}
|
|
return SIMCard{}, false
|
|
}
|
|
|
|
func chanRequestError[T any](w http.ResponseWriter, err error) {
|
|
writeJSON(w, http.StatusBadRequest, []chanResponse[T]{{Code: chanErrorCode, Message: err.Error()}})
|
|
}
|
|
|
|
func (s *Service) chanQueryBasicInfo(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanBasicInfo](w, err)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanBasicInfo], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanBasicInfo](key, "card not found"))
|
|
continue
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanBasicInfo{ActiveDate: card.ActiveDate, OpenDate: card.OpenDate, Remark: card.Remark}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQuerySession(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanSession](w, err)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanSession], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanSession](key, "card not found"))
|
|
continue
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanSession{ApnID: primaryAPN(card).Name, Rat: card.RAT, IPv4: card.IP, IPv6: card.IPv6, IPv6Prefix: card.IPv6Prefix, Status: chanSessionStatus(card.SessionStatus), CreateTime: card.LastChangeDate}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQueryStatus(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanCardStatus](w, err)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanCardStatus], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanCardStatus](key, "card not found"))
|
|
continue
|
|
}
|
|
status, _ := strconv.Atoi(card.CardStatus)
|
|
responses = append(responses, chanSuccess(key, chanCardStatus{CardStatus: status, LastChangeDate: card.LastChangeDate}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQueryBindStatus(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanBindStatus](w, err)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanBindStatus], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanBindStatus](key, "card not found"))
|
|
continue
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanBindStatus{BindStatus: card.CardBindStatus}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQueryDeviceStatus(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanDeviceStatus](w, err)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanDeviceStatus], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanDeviceStatus](key, "card not found"))
|
|
continue
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanDeviceStatus{DeviceStatus: chanSessionStatus(card.OnOffStatus)}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQueryRegionLimitStatus(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanRegionLimitStatus](w, err)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanRegionLimitStatus], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanRegionLimitStatus](key, "card not found"))
|
|
continue
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanRegionLimitStatus{RegionLimitStatus: card.RegionLimitStatus}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQueryIMEI(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanIMEI](w, err)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanIMEI], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanIMEI](key, "card not found"))
|
|
continue
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanIMEI{IMEI: card.IMEI}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQueryDataUsage(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanUsage](w, err)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanUsage], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanUsage](key, "card not found"))
|
|
continue
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanUsage{DataUsage: card.MonthUsageKB / 1024}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQueryMonthly(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanMonthlyUsage](w, err)
|
|
return
|
|
}
|
|
data := decodeChanReqData(req)
|
|
responses := make([]chanResponse[chanMonthlyUsage], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanMonthlyUsage](key, "card not found"))
|
|
continue
|
|
}
|
|
amount := card.MonthUsageKB
|
|
if data.QueryDate != "" && len(data.QueryDate) == 6 && data.QueryDate != time.Now().Format("200601") {
|
|
amount = card.MonthlyBaseKB
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanMonthlyUsage{DeadLine: time.Now().AddDate(0, 0, -1).Format("20060102"), DataAmount: amount / 1024}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQueryDaily(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanDailyUsage](w, err)
|
|
return
|
|
}
|
|
data := decodeChanReqData(req)
|
|
queryDate := data.QueryDate
|
|
if queryDate == "" {
|
|
queryDate = r.URL.Query().Get("queryDate")
|
|
}
|
|
if queryDate == "" {
|
|
queryDate = time.Now().Format("20060102")
|
|
}
|
|
responses := make([]chanResponse[chanDailyUsage], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanDailyUsage](key, "card not found"))
|
|
continue
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanDailyUsage{QueryDate: queryDate, DataAmount: card.DailyBaseKB / 1024}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanQueryAPN(w http.ResponseWriter, r *http.Request) {
|
|
req, st, err := s.chanCards(r)
|
|
if err != nil {
|
|
chanRequestError[chanAPNList](w, err)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanAPNList], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
card, ok := findChanCard(st, key)
|
|
if !ok {
|
|
responses = append(responses, chanFailure[chanAPNList](key, "card not found"))
|
|
continue
|
|
}
|
|
apns := make([]chanAPN, 0, len(card.APNs))
|
|
for _, apn := range card.APNs {
|
|
apns = append(apns, chanAPN{APNName: apn.Name, Status: apn.Status})
|
|
}
|
|
responses = append(responses, chanSuccess(key, chanAPNList{APNList: apns}))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanChangeStatus(w http.ResponseWriter, r *http.Request) {
|
|
req, err := parseChanRequest(r)
|
|
if err != nil {
|
|
chanRequestError[chanOrder](w, err)
|
|
return
|
|
}
|
|
data := decodeChanReqData(req)
|
|
if data.OperType != "0" && data.OperType != "1" {
|
|
responses := make([]chanResponse[chanOrder], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
responses = append(responses, chanFailure[chanOrder](key, "unsupported operType, expected 0(stop) or 1(resume)"))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanOrder], 0, len(req.SimKeys))
|
|
err = s.store.SaveMutation(func(st *Store) error {
|
|
for _, key := range req.SimKeys {
|
|
idx := findChanCardIndex(*st, key)
|
|
if idx < 0 {
|
|
responses = append(responses, chanFailure[chanOrder](key, "card not found"))
|
|
continue
|
|
}
|
|
card := &st.Cards[idx]
|
|
if data.OperType == "0" {
|
|
card.CardStatus = "4"
|
|
} else {
|
|
card.CardStatus = "2"
|
|
}
|
|
card.LastChangeDate = time.Now().Format("2006-01-02 15:04:05")
|
|
orderNum := "ORD" + time.Now().Format("20060102150405") + randomHex(3)
|
|
st.Orders = append(st.Orders, Order{OrderNum: orderNum, MSISDN: card.MSISDN, ICCID: card.ICCID, IMSI: card.IMSI, Type: "sim-status", OperType: data.OperType, Status: "completed", CreatedAt: card.LastChangeDate})
|
|
responses = append(responses, chanSuccess(key, chanOrder{OrderNum: orderNum}))
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
chanRequestError[chanOrder](w, err)
|
|
return
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func (s *Service) chanChangeAPN(w http.ResponseWriter, r *http.Request) {
|
|
req, err := parseChanRequest(r)
|
|
if err != nil {
|
|
chanRequestError[chanOrder](w, err)
|
|
return
|
|
}
|
|
data := decodeChanReqData(req)
|
|
if data.APNName == "" || (data.OperType != "0" && data.OperType != "1") {
|
|
responses := make([]chanResponse[chanOrder], 0, len(req.SimKeys))
|
|
for _, key := range req.SimKeys {
|
|
responses = append(responses, chanFailure[chanOrder](key, "apnName and operType are required"))
|
|
}
|
|
writeChanResponses(w, responses)
|
|
return
|
|
}
|
|
responses := make([]chanResponse[chanOrder], 0, len(req.SimKeys))
|
|
err = s.store.SaveMutation(func(st *Store) error {
|
|
for _, key := range req.SimKeys {
|
|
idx := findChanCardIndex(*st, key)
|
|
if idx < 0 {
|
|
responses = append(responses, chanFailure[chanOrder](key, "card not found"))
|
|
continue
|
|
}
|
|
card := &st.Cards[idx]
|
|
status := "0"
|
|
if data.OperType == "0" {
|
|
status = "1"
|
|
}
|
|
found := false
|
|
for i := range card.APNs {
|
|
if strings.EqualFold(card.APNs[i].Name, data.APNName) {
|
|
card.APNs[i].Status = status
|
|
found = true
|
|
}
|
|
}
|
|
if !found {
|
|
card.APNs = append(card.APNs, APN{Name: data.APNName, Status: status})
|
|
}
|
|
orderNum := "APN" + time.Now().Format("20060102150405") + randomHex(3)
|
|
now := time.Now().Format("2006-01-02 15:04:05")
|
|
st.Orders = append(st.Orders, Order{OrderNum: orderNum, MSISDN: card.MSISDN, ICCID: card.ICCID, IMSI: card.IMSI, Type: "sim-apn-function", OperType: data.OperType, APNName: data.APNName, Status: "completed", CreatedAt: now})
|
|
responses = append(responses, chanSuccess(key, chanOrder{OrderNum: orderNum}))
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
chanRequestError[chanOrder](w, err)
|
|
return
|
|
}
|
|
writeChanResponses(w, responses)
|
|
}
|
|
|
|
func findChanCardIndex(st Store, key chanSimKey) int {
|
|
for i, card := range st.Cards {
|
|
if (key.ICCID != "" && card.ICCID == key.ICCID) || (key.IMSI != "" && card.IMSI == key.IMSI) || (key.MSISDN != "" && card.MSISDN == key.MSISDN) {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func chanSessionStatus(status string) string {
|
|
switch strings.ToUpper(strings.TrimSpace(status)) {
|
|
case "01", "1", "0", "ONLINE":
|
|
return "0"
|
|
case "00", "-1", "OFFLINE":
|
|
return "-1"
|
|
default:
|
|
return "-2"
|
|
}
|
|
}
|