This commit is contained in:
@@ -146,6 +146,9 @@ components:
|
||||
card_status_name:
|
||||
description: 卡状态名称(中文)
|
||||
type: string
|
||||
gateway_extend:
|
||||
description: Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因
|
||||
type: string
|
||||
stop_reason:
|
||||
description: 停机原因
|
||||
type: string
|
||||
@@ -908,6 +911,9 @@ components:
|
||||
enable_virtual_data:
|
||||
description: 当前主套餐是否启用虚流量(按套餐使用记录快照返回)
|
||||
type: boolean
|
||||
gateway_extend:
|
||||
description: Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因
|
||||
type: string
|
||||
generation:
|
||||
description: 世代
|
||||
type: string
|
||||
@@ -1314,6 +1320,9 @@ components:
|
||||
type: string
|
||||
device_realtime:
|
||||
$ref: '#/components/schemas/DtoDeviceGatewayInfo'
|
||||
gateway_extend:
|
||||
description: Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因
|
||||
type: string
|
||||
last_gateway_reading_mb:
|
||||
description: 运营商当前周期累计流量读数(MB,asset_type=card时有效,运营商口径展示建议读取该字段)
|
||||
type: number
|
||||
@@ -1446,6 +1455,9 @@ components:
|
||||
enable_virtual_data:
|
||||
description: 当前主套餐是否启用虚流量(按套餐使用记录快照返回)
|
||||
type: boolean
|
||||
gateway_extend:
|
||||
description: Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因
|
||||
type: string
|
||||
iccid:
|
||||
description: 卡ICCID(asset_type=card时有效)
|
||||
type: string
|
||||
@@ -2124,6 +2136,9 @@ components:
|
||||
carrier_type:
|
||||
description: 运营商类型
|
||||
type: string
|
||||
gateway_extend:
|
||||
description: Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因
|
||||
type: string
|
||||
iccid:
|
||||
description: ICCID
|
||||
type: string
|
||||
@@ -3807,6 +3822,9 @@ components:
|
||||
carrier_name:
|
||||
description: 运营商名称
|
||||
type: string
|
||||
gateway_extend:
|
||||
description: Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因
|
||||
type: string
|
||||
iccid:
|
||||
description: ICCID
|
||||
type: string
|
||||
@@ -3858,6 +3876,9 @@ components:
|
||||
carrier_type:
|
||||
description: 运营商类型(CMCC/CUCC/CTCC/CBN)
|
||||
type: string
|
||||
gateway_extend:
|
||||
description: Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因
|
||||
type: string
|
||||
iccid:
|
||||
description: 物联网卡ICCID
|
||||
type: string
|
||||
@@ -4542,6 +4563,9 @@ components:
|
||||
minimum: 0
|
||||
nullable: true
|
||||
type: integer
|
||||
gateway_extend:
|
||||
description: Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因
|
||||
type: string
|
||||
iccid:
|
||||
description: ICCID
|
||||
type: string
|
||||
@@ -6911,7 +6935,7 @@ components:
|
||||
description: 下单时资产的标识符快照(ICCID 或 VirtualNo)
|
||||
type: string
|
||||
asset_reset:
|
||||
description: 资产是否已重置
|
||||
description: 退款后资产处理是否完成
|
||||
type: boolean
|
||||
asset_type:
|
||||
description: 资产类型 (card:单卡, device:设备)
|
||||
@@ -7750,6 +7774,9 @@ components:
|
||||
enable_polling:
|
||||
description: 是否参与轮询
|
||||
type: boolean
|
||||
gateway_extend:
|
||||
description: Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因
|
||||
type: string
|
||||
iccid:
|
||||
description: ICCID
|
||||
type: string
|
||||
|
||||
@@ -192,6 +192,7 @@ func (h *ClientAssetHandler) GetAssetInfo(c *fiber.Ctx) error {
|
||||
CarrierType: resolved.Asset.CarrierType,
|
||||
NetworkStatus: resolved.Asset.NetworkStatus,
|
||||
NetworkStatusName: constants.GetNetworkStatusName(resolved.Asset.NetworkStatus),
|
||||
GatewayExtend: resolved.Asset.GatewayExtend,
|
||||
ActivationStatus: resolved.Asset.ActivationStatus,
|
||||
ActivationStatusName: constants.GetActivationStatusName(resolved.Asset.ActivationStatus),
|
||||
CardCategory: resolved.Asset.CardCategory,
|
||||
|
||||
@@ -166,6 +166,7 @@ func (h *ClientDeviceHandler) GetDeviceCards(c *fiber.Ctx) error {
|
||||
CarrierType: card.CarrierType,
|
||||
CarrierName: card.CarrierName,
|
||||
NetworkStatus: networkStatusText(card.NetworkStatus),
|
||||
GatewayExtend: card.GatewayExtend,
|
||||
RealNameStatus: card.RealNameStatus,
|
||||
SlotPosition: slot,
|
||||
IsActive: isCurrentMap[card.ID],
|
||||
|
||||
@@ -39,6 +39,7 @@ type AgentOpenAPICardStatusResponse struct {
|
||||
CardNo string `json:"card_no" description:"卡标识"`
|
||||
CardStatus string `json:"card_status" description:"卡状态 (normal:正常, stopped:停机)"`
|
||||
CardStatusName string `json:"card_status_name" description:"卡状态名称(中文)"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
StopReason string `json:"stop_reason" description:"停机原因"`
|
||||
StopReasonName string `json:"stop_reason_name" description:"停机原因名称(中文)"`
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ type AssetResolveResponse struct {
|
||||
ActivationStatus int `json:"activation_status,omitempty" description:"激活状态"`
|
||||
EnablePolling bool `json:"enable_polling" description:"是否参与轮询"`
|
||||
NetworkStatus int `json:"network_status" description:"网络状态:0停机 1开机(asset_type=card时有效)"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
}
|
||||
|
||||
// BoundCardInfo 设备绑定的卡信息
|
||||
@@ -81,6 +82,7 @@ type BoundCardInfo struct {
|
||||
CarrierType string `json:"carrier_type,omitempty" description:"运营商类型"`
|
||||
CarrierName string `json:"carrier_name,omitempty" description:"运营商名称"`
|
||||
RealnamePolicy string `json:"realname_policy" description:"实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名)"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
}
|
||||
|
||||
// AssetRealtimeStatusResponse 资产实时状态(只读DB/Redis)
|
||||
@@ -88,6 +90,7 @@ type AssetRealtimeStatusResponse struct {
|
||||
AssetType string `json:"asset_type" description:"资产类型:card 或 device"`
|
||||
AssetID uint `json:"asset_id" description:"资产ID"`
|
||||
NetworkStatus int `json:"network_status" description:"网络状态(asset_type=card时有效):0停机 1开机"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
RealNameStatus int `json:"real_name_status" description:"实名状态(asset_type=card时有效):0未实名 1已实名"`
|
||||
RealnamePolicy string `json:"realname_policy,omitempty" description:"实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名)"`
|
||||
CurrentMonthUsageMB float64 `json:"current_month_usage_mb,omitempty" description:"系统自然月累计流量(MB,asset_type=card时有效,不等于运营商周期口径)"`
|
||||
|
||||
@@ -63,6 +63,7 @@ type AssetInfoResponse struct {
|
||||
CarrierType string `json:"carrier_type,omitempty" description:"运营商类型(CMCC/CUCC/CTCC/CBN)"`
|
||||
NetworkStatus int `json:"network_status,omitempty" description:"网络状态(0:停机, 1:开机)"`
|
||||
NetworkStatusName string `json:"network_status_name,omitempty" description:"网络状态名称(中文)"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
ActivationStatus int `json:"activation_status,omitempty" description:"激活状态(0:未激活, 1:已激活)"`
|
||||
ActivationStatusName string `json:"activation_status_name,omitempty" description:"激活状态名称(中文)"`
|
||||
CardCategory string `json:"card_category,omitempty" description:"卡业务类型(normal:普通卡, industry:行业卡)"`
|
||||
|
||||
@@ -42,6 +42,7 @@ type DeviceCardItem struct {
|
||||
CarrierType string `json:"carrier_type" description:"运营商类型(CMCC/CUCC/CTCC/CBN)"`
|
||||
CarrierName string `json:"carrier_name" description:"运营商名称"`
|
||||
NetworkStatus string `json:"network_status" description:"网络状态"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
RealNameStatus int `json:"real_name_status" description:"实名状态 (0:未实名, 1:已实名)"`
|
||||
SlotPosition int `json:"slot_position" description:"插槽位置"`
|
||||
IsActive bool `json:"is_active" description:"是否当前激活卡"`
|
||||
|
||||
@@ -87,6 +87,7 @@ type DeviceCardBindingResponse struct {
|
||||
IsCurrent bool `json:"is_current" description:"是否为当前使用的卡"`
|
||||
RealnamePolicy string `json:"realname_policy" description:"实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名)"`
|
||||
NetworkStatus int `json:"network_status" description:"网络状态:0停机 1开机(asset_type=card时有效)"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
}
|
||||
|
||||
type ListDeviceCardsResponse struct {
|
||||
|
||||
@@ -87,6 +87,7 @@ type EnterpriseCardItem struct {
|
||||
StatusName string `json:"status_name" description:"状态名称"`
|
||||
NetworkStatus int `json:"network_status" description:"网络状态"`
|
||||
NetworkStatusName string `json:"network_status_name" description:"网络状态名称"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
}
|
||||
|
||||
type EnterpriseCardPageResult struct {
|
||||
|
||||
@@ -85,6 +85,7 @@ type DeviceCardInfo struct {
|
||||
CarrierName string `json:"carrier_name" description:"运营商名称"`
|
||||
NetworkStatus int `json:"network_status" description:"网络状态:0=停机 1=开机"`
|
||||
NetworkStatusName string `json:"network_status_name" description:"网络状态名称"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
}
|
||||
|
||||
type DeviceDetailReq struct {
|
||||
|
||||
@@ -45,6 +45,7 @@ type StandaloneIotCardResponse struct {
|
||||
RealNameStatusName string `json:"real_name_status_name" description:"实名状态名称(中文)"`
|
||||
NetworkStatus int `json:"network_status" description:"网络状态 (0:停机, 1:开机)"`
|
||||
NetworkStatusName string `json:"network_status_name" description:"网络状态名称(中文)"`
|
||||
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend,用于展示运营商侧实际停机原因"`
|
||||
DataUsageMB int64 `json:"data_usage_mb" description:"累计流量使用(MB)"`
|
||||
CurrentMonthUsageMB float64 `json:"current_month_usage_mb" description:"系统自然月累计流量(MB,不等于运营商周期口径)"`
|
||||
LastGatewayReadingMB float64 `json:"last_gateway_reading_mb" description:"运营商当前周期累计流量读数(MB,展示运营商口径时使用)"`
|
||||
|
||||
@@ -54,6 +54,7 @@ type IotCard struct {
|
||||
VirtualNo string `gorm:"column:virtual_no;type:varchar(50);uniqueIndex:idx_iot_card_virtual_no,where:deleted_at IS NULL AND virtual_no IS NOT NULL AND virtual_no <> '';comment:虚拟号(可选,非空时全局唯一)" json:"virtual_no,omitempty"`
|
||||
DeviceVirtualNo string `gorm:"column:device_virtual_no;type:varchar(100);not null;default:'';comment:绑定设备的虚拟号快照(未绑定时为空字符串)" json:"device_virtual_no"`
|
||||
LastGatewayReadingMB float64 `gorm:"column:last_gateway_reading_mb;type:float;not null;default:0;comment:运营商当前周期累计流量读数(MB,来自网关)" json:"last_gateway_reading_mb"`
|
||||
GatewayExtend string `gorm:"column:gateway_extend;type:text;not null;default:'';comment:Gateway 卡状态扩展字段,原样保存上游 extend,用于展示运营商侧实际停机原因" json:"gateway_extend"`
|
||||
RealnamePolicy string `gorm:"column:realname_policy;type:varchar(20);default:'after_order';not null;comment:实名认证策略(none=无需实名,before_order=先实名后充值/购买,after_order=先充值/购买后实名)" json:"realname_policy"`
|
||||
|
||||
// ICCID 双列存储,用于支持 19/20 位 ICCID 精确路由查询
|
||||
|
||||
@@ -121,6 +121,7 @@ func (s *Service) GetCardStatus(ctx context.Context, req *dto.AgentOpenAPICardQu
|
||||
CardNo: req.CardNo,
|
||||
CardStatus: cardStatus,
|
||||
CardStatusName: constants.AgentOpenAPICardStatusName(cardStatus),
|
||||
GatewayExtend: card.GatewayExtend,
|
||||
StopReason: stopReason,
|
||||
StopReasonName: constants.AgentOpenAPIStopReasonName(stopReason),
|
||||
}, nil
|
||||
|
||||
@@ -200,6 +200,7 @@ func (s *Service) buildDeviceResolveResponse(ctx context.Context, device *model.
|
||||
CarrierType: c.CarrierType,
|
||||
CarrierName: c.CarrierName,
|
||||
RealnamePolicy: c.RealnamePolicy,
|
||||
GatewayExtend: c.GatewayExtend,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -255,6 +256,7 @@ func (s *Service) buildCardResolveResponse(ctx context.Context, card *model.IotC
|
||||
RealNameAt: card.FirstRealnameAt,
|
||||
RealnamePolicy: card.RealnamePolicy,
|
||||
NetworkStatus: card.NetworkStatus,
|
||||
GatewayExtend: card.GatewayExtend,
|
||||
ICCID: card.ICCID,
|
||||
CarrierID: card.CarrierID,
|
||||
CarrierType: card.CarrierType,
|
||||
@@ -353,6 +355,7 @@ func (s *Service) GetRealtimeStatus(ctx context.Context, assetType string, id ui
|
||||
return nil, errors.Wrap(errors.CodeNotFound, err, "卡不存在")
|
||||
}
|
||||
resp.NetworkStatus = card.NetworkStatus
|
||||
resp.GatewayExtend = card.GatewayExtend
|
||||
resp.RealNameStatus = card.RealNameStatus
|
||||
resp.CurrentMonthUsageMB = card.CurrentMonthUsageMB
|
||||
resp.LastGatewayReadingMB = card.LastGatewayReadingMB
|
||||
@@ -389,6 +392,7 @@ func (s *Service) GetRealtimeStatus(ctx context.Context, assetType string, id ui
|
||||
CarrierType: c.CarrierType,
|
||||
CarrierName: c.CarrierName,
|
||||
RealnamePolicy: c.RealnamePolicy,
|
||||
GatewayExtend: c.GatewayExtend,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ func (s *Service) ListBindings(ctx context.Context, deviceID uint) (*dto.ListDev
|
||||
IsCurrent: binding.IsCurrent,
|
||||
RealnamePolicy: card.RealnamePolicy,
|
||||
NetworkStatus: card.NetworkStatus,
|
||||
GatewayExtend: card.GatewayExtend,
|
||||
}
|
||||
responses = append(responses, resp)
|
||||
}
|
||||
|
||||
@@ -308,6 +308,7 @@ func (s *Service) ListCards(ctx context.Context, enterpriseID uint, req *dto.Ent
|
||||
StatusName: constants.GetIotCardStatusName(card.Status),
|
||||
NetworkStatus: card.NetworkStatus,
|
||||
NetworkStatusName: constants.GetNetworkStatusName(card.NetworkStatus),
|
||||
GatewayExtend: card.GatewayExtend,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -369,6 +369,7 @@ func (s *Service) toStandaloneResponse(card *model.IotCard, shopMap map[uint]str
|
||||
RealNameStatusName: constants.GetRealNameStatusName(card.RealNameStatus),
|
||||
NetworkStatus: card.NetworkStatus,
|
||||
NetworkStatusName: constants.GetNetworkStatusName(card.NetworkStatus),
|
||||
GatewayExtend: card.GatewayExtend,
|
||||
DataUsageMB: card.DataUsageMB,
|
||||
CurrentMonthUsageMB: card.CurrentMonthUsageMB,
|
||||
LastGatewayReadingMB: card.LastGatewayReadingMB,
|
||||
@@ -1420,6 +1421,7 @@ func (s *Service) RefreshCardDataFromGateway(ctx context.Context, iccid string)
|
||||
if err != nil {
|
||||
s.logger.Warn("刷新卡数据:查询网络状态失败", zap.String("iccid", iccid), zap.Error(err))
|
||||
} else {
|
||||
updates["gateway_extend"] = statusResp.Extend
|
||||
networkStatus, ok := gateway.ParseCardNetworkStatus(statusResp.CardStatus, statusResp.Extend)
|
||||
if !ok {
|
||||
s.logger.Warn("刷新卡数据:未知 Gateway 卡状态",
|
||||
|
||||
@@ -440,7 +440,7 @@ var standaloneListColumns = []string{
|
||||
"imsi", "msisdn", "batch_no", "supplier", "status", "shop_id", "activated_at",
|
||||
"activation_status", "real_name_status", "network_status", "data_usage_mb",
|
||||
"current_month_usage_mb", "last_gateway_reading_mb", "current_month_start_date", "last_month_total_mb",
|
||||
"last_data_check_at", "last_real_name_check_at", "enable_polling", "series_id", "device_virtual_no", "realname_policy",
|
||||
"gateway_extend", "last_data_check_at", "last_real_name_check_at", "enable_polling", "series_id", "device_virtual_no", "realname_policy",
|
||||
"created_at", "updated_at",
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,9 @@ func parseCardFromCache(cardID uint, result map[string]string) *model.IotCard {
|
||||
card.NetworkStatus = status
|
||||
}
|
||||
}
|
||||
if v, ok := result["gateway_extend"]; ok {
|
||||
card.GatewayExtend = v
|
||||
}
|
||||
if v, ok := result["carrier_id"]; ok {
|
||||
if id, err := strconv.ParseUint(v, 10, 64); err == nil {
|
||||
card.CarrierID = uint(id)
|
||||
@@ -126,6 +129,7 @@ func writeCardToCache(b *PollingBase, key string, card *model.IotCard) {
|
||||
"card_category": card.CardCategory,
|
||||
"real_name_status": card.RealNameStatus,
|
||||
"network_status": card.NetworkStatus,
|
||||
"gateway_extend": card.GatewayExtend,
|
||||
"carrier_id": card.CarrierID,
|
||||
"current_month_usage_mb": card.CurrentMonthUsageMB,
|
||||
"last_gateway_reading_mb": card.LastGatewayReadingMB,
|
||||
|
||||
@@ -65,6 +65,8 @@ func (h *PollingCardStatusHandler) Handle(ctx context.Context, t *asynq.Task) er
|
||||
|
||||
newNetworkStatus := card.NetworkStatus
|
||||
gatewayCardStatus := ""
|
||||
gatewayExtend := card.GatewayExtend
|
||||
statusQueried := false
|
||||
if h.gateway != nil {
|
||||
result, gwErr := h.gateway.QueryCardStatus(ctx, &gateway.CardStatusReq{CardNo: card.ICCID})
|
||||
if gwErr != nil {
|
||||
@@ -74,6 +76,8 @@ func (h *PollingCardStatusHandler) Handle(ctx context.Context, t *asynq.Task) er
|
||||
return h.base.requeueCard(ctx, cardID, constants.TaskTypePollingCardStatus)
|
||||
}
|
||||
gatewayCardStatus = result.CardStatus
|
||||
gatewayExtend = result.Extend
|
||||
statusQueried = true
|
||||
parsedStatus, ok := gateway.ParseCardNetworkStatus(result.CardStatus, result.Extend)
|
||||
if !ok {
|
||||
h.base.logger.Warn("卡状态轮询:未知 Gateway 卡状态",
|
||||
@@ -100,6 +104,9 @@ func (h *PollingCardStatusHandler) Handle(ctx context.Context, t *asynq.Task) er
|
||||
|
||||
// 无论状态是否变化,都更新最后一次检查时间
|
||||
fields := map[string]any{"last_card_status_check_at": now}
|
||||
if statusQueried {
|
||||
fields["gateway_extend"] = gatewayExtend
|
||||
}
|
||||
if statusChanged {
|
||||
fields["network_status"] = newNetworkStatus
|
||||
// 网关侧停机事件:补写 stop_reason,便于状态追踪和区分手动停机
|
||||
@@ -116,8 +123,18 @@ func (h *PollingCardStatusHandler) Handle(ctx context.Context, t *asynq.Task) er
|
||||
return h.base.requeueCard(ctx, cardID, constants.TaskTypePollingCardStatus)
|
||||
}
|
||||
|
||||
if statusQueried || statusChanged {
|
||||
cacheUpdates := map[string]any{}
|
||||
if statusQueried {
|
||||
cacheUpdates["gateway_extend"] = gatewayExtend
|
||||
}
|
||||
if statusChanged {
|
||||
cacheUpdates["network_status"] = newNetworkStatus
|
||||
}
|
||||
h.base.updateCardCache(ctx, cardID, cacheUpdates)
|
||||
}
|
||||
|
||||
if statusChanged {
|
||||
h.base.updateCardCache(ctx, cardID, map[string]any{"network_status": newNetworkStatus})
|
||||
h.base.logger.Info("卡状态已变化",
|
||||
zap.Uint("card_id", cardID),
|
||||
zap.Int("old_status", card.NetworkStatus),
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- 回滚 IoT 卡 Gateway 卡状态扩展字段
|
||||
|
||||
ALTER TABLE tb_iot_card
|
||||
DROP COLUMN IF EXISTS gateway_extend;
|
||||
6
migrations/000143_add_gateway_extend_to_iot_card.up.sql
Normal file
6
migrations/000143_add_gateway_extend_to_iot_card.up.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
-- 为 IoT 卡保存 Gateway 卡状态扩展字段,用于展示运营商侧实际停机原因
|
||||
|
||||
ALTER TABLE tb_iot_card
|
||||
ADD COLUMN IF NOT EXISTS gateway_extend TEXT NOT NULL DEFAULT '';
|
||||
|
||||
COMMENT ON COLUMN tb_iot_card.gateway_extend IS 'Gateway 卡状态扩展字段,原样保存上游 extend,用于展示运营商侧实际停机原因';
|
||||
Reference in New Issue
Block a user