chore: 初始开源发布
iotlcm-app:小程序端 + 用户端服务。 - app/:uni-app 小程序前端(基于 unibest,MIT) - 微信 AppID → YOUR_WX_APPID,uni-app AppID → __UNI__YOURAPPID - 内网后端地址 → admin.iotlcm.example.com - 应用标题与 unibest 模板 README 重写(保留上游致谢与 MIT 声明) - server/:GoFrame 用户端服务(基于 XiuAdmin,Apache-2.0) - module xiuadmin → git.5iot.com/iotlcm-public/iotlcm-app(360 文件) - 支付回调地址 → app.iotlcm.example.com,商户名与应用名泛化 - 真实手机号 → 合法 11 位编造号(保留号段前 3 位 + 后 4 位) - 依赖号码尾部的断言同步更新 - 补 server/LICENSE(Apache-2.0) - 移除内部资产:CI 触发器 - 补根 README,LF 行尾 + .gitattributes 已知:TestSysDept_RefreshDeptAncestors 在源仓同一提交上同样失败,属既有缺陷。
This commit is contained in:
@@ -0,0 +1,543 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type appOneLinkMockConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
BaseURL string `json:"baseUrl"`
|
||||
AppID string `json:"appid"`
|
||||
Password string `json:"password"`
|
||||
Timeout string `json:"timeout"`
|
||||
}
|
||||
|
||||
type appOneLinkMockClient struct {
|
||||
cfg *appOneLinkMockConfig
|
||||
httpClient *http.Client
|
||||
token string
|
||||
}
|
||||
|
||||
type appOneLinkMockTokenResponse struct {
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
Result []struct {
|
||||
Token string `json:"token"`
|
||||
TTL string `json:"ttl"`
|
||||
} `json:"result"`
|
||||
}
|
||||
|
||||
type appOneLinkMockChangeStatusResponse struct {
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
Result []struct {
|
||||
Msisdn string `json:"msisdn"`
|
||||
OrderNum string `json:"orderNum"`
|
||||
} `json:"result"`
|
||||
}
|
||||
|
||||
type appOneLinkMockBasicInfoResponse struct {
|
||||
Status string `json:"status"`
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Result json.RawMessage `json:"result"`
|
||||
Data []struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
ResData json.RawMessage `json:"resData"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
type appOneLinkMockSimSessionResponse struct {
|
||||
Status string `json:"status"`
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Result json.RawMessage `json:"result"`
|
||||
Data []struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
ResData appOneLinkMockSimSessionItem `json:"resData"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
type appOneLinkMockSimSessionItem struct {
|
||||
ApnId string `json:"apnId"`
|
||||
Rat string `json:"rat"`
|
||||
Imei string `json:"imei"`
|
||||
Ipv4 string `json:"ipv4"`
|
||||
Ipv6 string `json:"ipv6"`
|
||||
Ipv6Prefix string `json:"ipv6Prefix"`
|
||||
Status string `json:"status"`
|
||||
CreateTime string `json:"createTime"`
|
||||
}
|
||||
|
||||
type appOneLinkMockStatusOutcome = appSimStatusChangeOutcome
|
||||
|
||||
func newAppOneLinkMockClient(ctx context.Context) (*appOneLinkMockClient, error) {
|
||||
cfg, err := appLoadOneLinkMockConfig(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
timeout := 10 * time.Second
|
||||
if cfg.Timeout != "" {
|
||||
if parsed, err := time.ParseDuration(cfg.Timeout); err == nil && parsed > 0 {
|
||||
timeout = parsed
|
||||
}
|
||||
}
|
||||
return &appOneLinkMockClient{
|
||||
cfg: cfg,
|
||||
httpClient: &http.Client{Timeout: timeout},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func appLoadOneLinkMockConfig(ctx context.Context) (*appOneLinkMockConfig, error) {
|
||||
cfg := &appOneLinkMockConfig{
|
||||
BaseURL: "https://iotlcm.example.com/onelink-mock/v5",
|
||||
Timeout: "10s",
|
||||
}
|
||||
if err := g.Cfg().MustGet(ctx, "upstream.onelinkMock").Scan(cfg); err != nil {
|
||||
return nil, gerror.Wrap(err, "读取OneLink挡板配置失败")
|
||||
}
|
||||
cfg.BaseURL = strings.TrimRight(strings.TrimSpace(cfg.BaseURL), "/")
|
||||
cfg.AppID = strings.TrimSpace(cfg.AppID)
|
||||
cfg.Password = strings.TrimSpace(cfg.Password)
|
||||
cfg.Timeout = strings.TrimSpace(cfg.Timeout)
|
||||
if !cfg.Enabled {
|
||||
return nil, gerror.New("OneLink挡板未启用")
|
||||
}
|
||||
if cfg.BaseURL == "" {
|
||||
return nil, gerror.New("OneLink挡板地址未配置")
|
||||
}
|
||||
if cfg.AppID == "" || cfg.Password == "" {
|
||||
return nil, gerror.New("OneLink挡板appid或password未配置")
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (c *appOneLinkMockClient) ChangeSimStatus(ctx context.Context, operation appCardLifecycleOperation, row *appCardLifecycleExecutionRow) (appOneLinkMockStatusOutcome, error) {
|
||||
if c == nil || c.cfg == nil {
|
||||
return appOneLinkMockStatusOutcome{}, gerror.New("OneLink挡板客户端未初始化")
|
||||
}
|
||||
if row == nil {
|
||||
return appOneLinkMockStatusOutcome{}, gerror.New("卡片操作行不能为空")
|
||||
}
|
||||
msisdn := strings.TrimSpace(row.Msisdn)
|
||||
if msisdn == "" && row.Card != nil {
|
||||
msisdn = strings.TrimSpace(row.Card.Msisdn)
|
||||
}
|
||||
if msisdn == "" {
|
||||
return appOneLinkMockStatusOutcome{}, gerror.New("卡片缺少MSISDN,不能请求OneLink挡板")
|
||||
}
|
||||
operType, err := appOneLinkMockOperType(operation)
|
||||
if err != nil {
|
||||
return appOneLinkMockStatusOutcome{}, err
|
||||
}
|
||||
token, err := c.ensureToken(ctx)
|
||||
if err != nil {
|
||||
return appOneLinkMockStatusOutcome{}, err
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
params.Set("appid", c.cfg.AppID)
|
||||
params.Set("transid", appOneLinkMockTransID(c.cfg.AppID))
|
||||
params.Set("token", token)
|
||||
params.Set("msisdn", msisdn)
|
||||
params.Set("operType", operType)
|
||||
|
||||
body, err := c.get(ctx, c.cfg.BaseURL+"/ec/change/sim-status?"+params.Encode())
|
||||
if err != nil {
|
||||
return appOneLinkMockStatusOutcome{}, err
|
||||
}
|
||||
var response appOneLinkMockChangeStatusResponse
|
||||
if err = json.Unmarshal(body, &response); err != nil {
|
||||
return appOneLinkMockStatusOutcome{}, gerror.Wrap(err, "解析OneLink挡板状态变更响应失败")
|
||||
}
|
||||
if strings.TrimSpace(response.Status) != "0" {
|
||||
message := strings.TrimSpace(response.Message)
|
||||
if message == "" {
|
||||
message = "OneLink挡板状态变更失败"
|
||||
}
|
||||
return appOneLinkMockStatusOutcome{Code: -1, Message: message}, nil
|
||||
}
|
||||
orderNum := ""
|
||||
if len(response.Result) > 0 {
|
||||
orderNum = strings.TrimSpace(response.Result[0].OrderNum)
|
||||
}
|
||||
return appOneLinkMockStatusOutcome{
|
||||
Success: true,
|
||||
Code: 0,
|
||||
Message: appOneLinkMockSuccessMessage(response.Message),
|
||||
OrderNum: orderNum,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *appOneLinkMockClient) QuerySimBasicInfo(ctx context.Context, input appSimBasicInfoInput) (*appSimBasicInfoOutput, error) {
|
||||
if c == nil || c.cfg == nil {
|
||||
return nil, gerror.New("OneLink鎸℃澘瀹㈡埛绔湭鍒濆鍖?")
|
||||
}
|
||||
token, err := c.ensureToken(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
params.Set("appid", c.cfg.AppID)
|
||||
params.Set("transid", appOneLinkMockTransID(c.cfg.AppID))
|
||||
params.Set("token", token)
|
||||
appOneLinkMockAddBasicInfoQueryParam(params, input)
|
||||
if params.Get("msisdn") == "" && params.Get("iccid") == "" && params.Get("imsi") == "" && params.Get("imei") == "" {
|
||||
return nil, gerror.New("鍗$墖缂哄皯鏌ヨ鏍囪瘑锛屼笉鑳借姹侽neLink鎸℃澘")
|
||||
}
|
||||
|
||||
body, err := c.get(ctx, c.cfg.BaseURL+"/ec/query/sim-basic-info?"+params.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response appOneLinkMockBasicInfoResponse
|
||||
if err = json.Unmarshal(body, &response); err != nil {
|
||||
return nil, gerror.Wrap(err, "瑙f瀽OneLink鎸℃澘鍩烘湰淇℃伅鍝嶅簲澶辫触")
|
||||
}
|
||||
if status := strings.TrimSpace(response.Status); status != "" && status != "0" {
|
||||
message := strings.TrimSpace(response.Message)
|
||||
if message == "" {
|
||||
message = "OneLink鎸℃澘鍩烘湰淇℃伅鏌ヨ澶辫触"
|
||||
}
|
||||
return nil, gerror.New(message)
|
||||
}
|
||||
if response.Code != 0 {
|
||||
message := strings.TrimSpace(response.Message)
|
||||
if message == "" {
|
||||
message = "OneLink鎸℃澘鍩烘湰淇℃伅鏌ヨ澶辫触"
|
||||
}
|
||||
return nil, gerror.New(message)
|
||||
}
|
||||
|
||||
if output := appOneLinkMockParseBasicInfoOutput(response.Result, input); output != nil {
|
||||
return output, nil
|
||||
}
|
||||
for _, item := range response.Data {
|
||||
if item.Code != 0 {
|
||||
continue
|
||||
}
|
||||
if output := appOneLinkMockParseBasicInfoOutput(item.ResData, input); output != nil {
|
||||
return output, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *appOneLinkMockClient) QuerySimSession(ctx context.Context, card *appCardQueryRow) (*appOneLinkMockSimSessionItem, error) {
|
||||
if c == nil || c.cfg == nil {
|
||||
return nil, gerror.New("OneLink挡板客户端未初始化")
|
||||
}
|
||||
if card == nil {
|
||||
return nil, gerror.New("卡片信息为空,不能查询会话")
|
||||
}
|
||||
params := url.Values{}
|
||||
params.Set("appid", c.cfg.AppID)
|
||||
params.Set("transid", appOneLinkMockTransID(c.cfg.AppID))
|
||||
if token, err := c.ensureToken(ctx); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
params.Set("token", token)
|
||||
}
|
||||
if value := strings.TrimSpace(card.Msisdn); value != "" {
|
||||
params.Set("msisdn", value)
|
||||
}
|
||||
if value := strings.TrimSpace(card.Iccid); value != "" {
|
||||
params.Set("iccid", value)
|
||||
}
|
||||
if value := strings.TrimSpace(card.Imsi); value != "" {
|
||||
params.Set("imsi", value)
|
||||
}
|
||||
if params.Get("msisdn") == "" && params.Get("iccid") == "" && params.Get("imsi") == "" {
|
||||
return nil, gerror.New("卡片缺少查询会话所需标识")
|
||||
}
|
||||
|
||||
body, err := c.get(ctx, c.cfg.BaseURL+"/ec/query/sim-session?"+params.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response appOneLinkMockSimSessionResponse
|
||||
if err = json.Unmarshal(body, &response); err != nil {
|
||||
return nil, gerror.Wrap(err, "解析OneLink挡板会话响应失败")
|
||||
}
|
||||
if strings.TrimSpace(response.Status) != "" && strings.TrimSpace(response.Status) != "0" {
|
||||
message := strings.TrimSpace(response.Message)
|
||||
if message == "" {
|
||||
message = "OneLink挡板会话查询失败"
|
||||
}
|
||||
return nil, gerror.New(message)
|
||||
}
|
||||
if response.Code != 0 {
|
||||
message := strings.TrimSpace(response.Message)
|
||||
if message == "" {
|
||||
message = "OneLink挡板会话查询失败"
|
||||
}
|
||||
return nil, gerror.New(message)
|
||||
}
|
||||
for _, item := range appOneLinkMockParseSessionResult(response.Result) {
|
||||
if !item.isZero() {
|
||||
return &item, nil
|
||||
}
|
||||
}
|
||||
for _, item := range response.Data {
|
||||
if item.Code == 0 && !item.ResData.isZero() {
|
||||
session := item.ResData
|
||||
return &session, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func appOneLinkMockAddBasicInfoQueryParam(params url.Values, input appSimBasicInfoInput) {
|
||||
if params == nil {
|
||||
return
|
||||
}
|
||||
if value := strings.TrimSpace(input.Msisdn); value != "" {
|
||||
params.Set("msisdn", value)
|
||||
}
|
||||
if value := strings.TrimSpace(input.Iccid); value != "" {
|
||||
params.Set("iccid", value)
|
||||
}
|
||||
if value := strings.TrimSpace(input.Imsi); value != "" {
|
||||
params.Set("imsi", value)
|
||||
}
|
||||
if value := strings.TrimSpace(input.Imei); value != "" {
|
||||
params.Set("imei", value)
|
||||
}
|
||||
if params.Get("msisdn") == "" && params.Get("iccid") == "" && params.Get("imsi") == "" && params.Get("imei") == "" {
|
||||
if value := strings.TrimSpace(input.CardValue); value != "" {
|
||||
params.Set("msisdn", value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func appOneLinkMockParseBasicInfoOutput(raw json.RawMessage, input appSimBasicInfoInput) *appSimBasicInfoOutput {
|
||||
payload := appOneLinkMockFirstPayload(raw)
|
||||
if len(payload) == 0 {
|
||||
return nil
|
||||
}
|
||||
output := &appSimBasicInfoOutput{
|
||||
Provider: appUpstreamProviderMock,
|
||||
Iccid: appFirstNotEmpty(appOneLinkMockMapString(payload, "iccid", "Iccid"), strings.TrimSpace(input.Iccid)),
|
||||
Msisdn: appFirstNotEmpty(appOneLinkMockMapString(payload, "msisdn", "Msisdn"), strings.TrimSpace(input.Msisdn), strings.TrimSpace(input.CardValue)),
|
||||
Imsi: appFirstNotEmpty(appOneLinkMockMapString(payload, "imsi", "Imsi"), strings.TrimSpace(input.Imsi)),
|
||||
Imei: appFirstNotEmpty(appOneLinkMockMapString(payload, "imei", "Imei"), strings.TrimSpace(input.Imei)),
|
||||
OpenDate: appOneLinkMockMapString(payload, "openDate", "open_date", "OpenDate"),
|
||||
ActiveDate: appOneLinkMockMapString(payload, "activeDate", "active_date", "ActiveDate"),
|
||||
Remark: appOneLinkMockMapString(payload, "remark", "Remark"),
|
||||
LastChangeDate: appOneLinkMockMapString(payload, "lastChangeDate", "last_change_date", "LastChangeDate"),
|
||||
}
|
||||
statusText := appOneLinkMockMapString(payload, "cardStatus", "card_status", "status", "Status")
|
||||
if statusText != "" {
|
||||
if status, err := strconv.Atoi(statusText); err == nil {
|
||||
output.CardStatus = status
|
||||
}
|
||||
if output.CardStatus == 0 {
|
||||
switch strings.ToLower(statusText) {
|
||||
case "active", "activated", "normal", "ok", "success":
|
||||
output.CardStatus = consts.V3ApiSimBossCardStatusActivated
|
||||
case "stop", "stopped", "disable", "disabled":
|
||||
output.CardStatus = consts.V3ApiSimBossCardStatusStopped
|
||||
}
|
||||
}
|
||||
}
|
||||
if output.Iccid == "" && output.Msisdn == "" && output.Imsi == "" && output.Imei == "" && output.OpenDate == "" && output.ActiveDate == "" && output.Remark == "" && output.LastChangeDate == "" && output.CardStatus == 0 {
|
||||
return nil
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func appOneLinkMockFirstPayload(raw json.RawMessage) map[string]any {
|
||||
if len(raw) == 0 || string(raw) == "null" {
|
||||
return nil
|
||||
}
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(raw, &payload); err == nil && len(payload) > 0 {
|
||||
if nested, ok := payload["resData"]; ok && nested != nil {
|
||||
if nestedRaw, err := json.Marshal(nested); err == nil {
|
||||
if nestedPayload := appOneLinkMockFirstPayload(nestedRaw); len(nestedPayload) > 0 {
|
||||
return nestedPayload
|
||||
}
|
||||
}
|
||||
}
|
||||
if nested, ok := payload["data"]; ok && nested != nil {
|
||||
if nestedRaw, err := json.Marshal(nested); err == nil {
|
||||
if nestedPayload := appOneLinkMockFirstPayload(nestedRaw); len(nestedPayload) > 0 {
|
||||
return nestedPayload
|
||||
}
|
||||
}
|
||||
}
|
||||
return payload
|
||||
}
|
||||
var payloadList []map[string]any
|
||||
if err := json.Unmarshal(raw, &payloadList); err == nil {
|
||||
for _, item := range payloadList {
|
||||
if len(item) > 0 {
|
||||
if nested, ok := item["resData"]; ok && nested != nil {
|
||||
if nestedRaw, err := json.Marshal(nested); err == nil {
|
||||
if nestedPayload := appOneLinkMockFirstPayload(nestedRaw); len(nestedPayload) > 0 {
|
||||
return nestedPayload
|
||||
}
|
||||
}
|
||||
}
|
||||
return item
|
||||
}
|
||||
}
|
||||
}
|
||||
var payloadWrapper struct {
|
||||
ResData json.RawMessage `json:"resData"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &payloadWrapper); err == nil && len(payloadWrapper.ResData) > 0 {
|
||||
return appOneLinkMockFirstPayload(payloadWrapper.ResData)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func appOneLinkMockMapString(data map[string]any, keys ...string) string {
|
||||
if len(data) == 0 {
|
||||
return ""
|
||||
}
|
||||
for _, key := range keys {
|
||||
if value, ok := data[key]; ok && value != nil {
|
||||
text := strings.TrimSpace(fmt.Sprint(value))
|
||||
if text != "" && text != "<nil>" {
|
||||
return text
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *appOneLinkMockClient) ensureToken(ctx context.Context) (string, error) {
|
||||
if strings.TrimSpace(c.token) != "" {
|
||||
return c.token, nil
|
||||
}
|
||||
params := url.Values{}
|
||||
params.Set("appid", c.cfg.AppID)
|
||||
params.Set("password", c.cfg.Password)
|
||||
params.Set("transid", appOneLinkMockTransID(c.cfg.AppID))
|
||||
|
||||
body, err := c.get(ctx, c.cfg.BaseURL+"/ec/get/token?"+params.Encode())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var response appOneLinkMockTokenResponse
|
||||
if err = json.Unmarshal(body, &response); err != nil {
|
||||
return "", gerror.Wrap(err, "解析OneLink挡板token响应失败")
|
||||
}
|
||||
if strings.TrimSpace(response.Status) != "0" || len(response.Result) == 0 || strings.TrimSpace(response.Result[0].Token) == "" {
|
||||
message := strings.TrimSpace(response.Message)
|
||||
if message == "" {
|
||||
message = "获取OneLink挡板token失败"
|
||||
}
|
||||
return "", gerror.New(message)
|
||||
}
|
||||
c.token = strings.TrimSpace(response.Result[0].Token)
|
||||
return c.token, nil
|
||||
}
|
||||
|
||||
func (c *appOneLinkMockClient) get(ctx context.Context, requestURL string) ([]byte, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "请求OneLink挡板失败")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "读取OneLink挡板响应失败")
|
||||
}
|
||||
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
|
||||
return nil, gerror.Newf("OneLink挡板HTTP状态异常:%d", resp.StatusCode)
|
||||
}
|
||||
return body, nil
|
||||
}
|
||||
|
||||
func appOneLinkMockParseSessionResult(raw json.RawMessage) []appOneLinkMockSimSessionItem {
|
||||
if len(raw) == 0 || string(raw) == "null" {
|
||||
return nil
|
||||
}
|
||||
var directList []appOneLinkMockSimSessionItem
|
||||
if err := json.Unmarshal(raw, &directList); err == nil && len(directList) > 0 {
|
||||
return directList
|
||||
}
|
||||
var direct appOneLinkMockSimSessionItem
|
||||
if err := json.Unmarshal(raw, &direct); err == nil && !direct.isZero() {
|
||||
return []appOneLinkMockSimSessionItem{direct}
|
||||
}
|
||||
var wrappedList []struct {
|
||||
Code int `json:"code"`
|
||||
ResData appOneLinkMockSimSessionItem `json:"resData"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &wrappedList); err == nil && len(wrappedList) > 0 {
|
||||
items := make([]appOneLinkMockSimSessionItem, 0, len(wrappedList))
|
||||
for _, wrapped := range wrappedList {
|
||||
if wrapped.Code == 0 && !wrapped.ResData.isZero() {
|
||||
items = append(items, wrapped.ResData)
|
||||
}
|
||||
}
|
||||
return items
|
||||
}
|
||||
var wrapped struct {
|
||||
Code int `json:"code"`
|
||||
ResData appOneLinkMockSimSessionItem `json:"resData"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &wrapped); err == nil && wrapped.Code == 0 && !wrapped.ResData.isZero() {
|
||||
return []appOneLinkMockSimSessionItem{wrapped.ResData}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (item appOneLinkMockSimSessionItem) isZero() bool {
|
||||
return strings.TrimSpace(item.ApnId) == "" &&
|
||||
strings.TrimSpace(item.Rat) == "" &&
|
||||
strings.TrimSpace(item.Imei) == "" &&
|
||||
strings.TrimSpace(item.Ipv4) == "" &&
|
||||
strings.TrimSpace(item.Ipv6) == "" &&
|
||||
strings.TrimSpace(item.Ipv6Prefix) == "" &&
|
||||
strings.TrimSpace(item.Status) == "" &&
|
||||
strings.TrimSpace(item.CreateTime) == ""
|
||||
}
|
||||
|
||||
func appOneLinkMockOperType(operation appCardLifecycleOperation) (string, error) {
|
||||
switch operation.Code {
|
||||
case "stop":
|
||||
return consts.SimCardStatusOperTypeStop, nil
|
||||
case "start":
|
||||
return consts.SimCardStatusOperTypeStart, nil
|
||||
default:
|
||||
return "", gerror.New("OneLink挡板暂不支持该卡片操作")
|
||||
}
|
||||
}
|
||||
|
||||
func appOneLinkMockTransID(appID string) string {
|
||||
random := time.Now().UnixNano() % 100000000
|
||||
return fmt.Sprintf("%s%s%08d", strings.TrimSpace(appID), gtime.Now().Format("YmdHis"), random)
|
||||
}
|
||||
|
||||
func appOneLinkMockSuccessMessage(message string) string {
|
||||
message = strings.TrimSpace(message)
|
||||
if message == "" {
|
||||
return "OneLink挡板处理成功"
|
||||
}
|
||||
return message
|
||||
}
|
||||
Reference in New Issue
Block a user