add: SMF CDR
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"be.ems/lib/dborm"
|
"be.ems/lib/dborm"
|
||||||
"be.ems/lib/global"
|
"be.ems/lib/global"
|
||||||
@@ -14,13 +15,197 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
UriCDREvent = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrEvent"
|
UriIMSCDREvent = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/ims/objectType/cdrEvent"
|
||||||
UriCDRFile = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrFile"
|
UriIMSCDRFile = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/ims/objectType/cdrFile"
|
||||||
|
UriSMFCDREvent = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/smf/objectType/cdrEvent"
|
||||||
|
UriSMFCDRFile = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/smf/objectType/cdrFile"
|
||||||
|
|
||||||
CustomUriCDREvent = config.UriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrEvent"
|
CustomUriIMSCDREvent = config.UriPrefix + "/cdrManagement/v1/elementType/ims/objectType/cdrEvent"
|
||||||
CustomUriCDRFile = config.UriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrFile"
|
CustomUriIMSCDRFile = config.UriPrefix + "/cdrManagement/v1/elementType/ims/objectType/cdrFile"
|
||||||
|
CustomUriSMFCDREvent = config.UriPrefix + "/cdrManagement/v1/elementType/ims/objectType/cdrEvent"
|
||||||
|
CustomUriSMFCDRFile = config.UriPrefix + "/cdrManagement/v1/elementType/ims/objectType/cdrFile"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SMF CDR
|
||||||
|
type CdrSubscriptionID struct {
|
||||||
|
SubscriptionIDType string `json:"subscriptionIDType"`
|
||||||
|
SubscriptionIDData string `json:"subscriptionIDData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrNetWorkFuctionInfomation struct {
|
||||||
|
NetworkFunctionality string `json:"networkFunctionality"`
|
||||||
|
NetworkFunctionName string `json:"networkFunctionName,omitempty"`
|
||||||
|
NetworkFunctionIPv4Address string `json:"networkFunctionIPv4Address,omitempty"`
|
||||||
|
NetworkFunctionIPv6Address string `json:"networkFunctionIPv6Address,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SMFTrigger string
|
||||||
|
|
||||||
|
const (
|
||||||
|
TimeThresholdReached SMFTrigger = "timeThresholdReached"
|
||||||
|
VolumeThresholdReached SMFTrigger = "volumeThresholdReached"
|
||||||
|
UnitThresholdReached SMFTrigger = "unitThresholdReached"
|
||||||
|
TimeQuotaExhausted SMFTrigger = "timeQuotaExhausted"
|
||||||
|
VolumeQuotaExhausted SMFTrigger = "volumeQuotaExhausted"
|
||||||
|
UnitQuotaExhausted SMFTrigger = "unitQuotaExhausted"
|
||||||
|
ExpiryOfQuotaValidityTime SMFTrigger = "expiryOfQuotaValidityTime"
|
||||||
|
ExpiryOfQuotaHoldingTime SMFTrigger = "expiryOfQuotaHoldingTime"
|
||||||
|
EndOfPDUSession SMFTrigger = "endOfPDUSession"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CdrSMFTrigger struct {
|
||||||
|
SMFTrigger SMFTrigger `json:"sMFTrigger"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrQuotaManagementIndicator string
|
||||||
|
|
||||||
|
// List of QuotaManagementIndicator
|
||||||
|
const (
|
||||||
|
Cdr_QMI_ONLINE_CHARGING CdrQuotaManagementIndicator = "ONLINE_CHARGING"
|
||||||
|
Cdr_QMI_OFFLINE_CHARGING CdrQuotaManagementIndicator = "OFFLINE_CHARGING"
|
||||||
|
Cdr_QMI_QUOTA_MANAGEMENT_SUSPENDED CdrQuotaManagementIndicator = "QUOTA_MANAGEMENT_SUSPENDED"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CdrUsedUnitContainer struct {
|
||||||
|
ServiceIdentifier *int32 `json:"serviceIdentifier,omitempty"`
|
||||||
|
QuotaManagementIndicatorExt CdrQuotaManagementIndicator `json:"quotaManagementIndicatorExt,omitempty"`
|
||||||
|
Triggers []SMFTrigger `json:"triggers,omitempty"`
|
||||||
|
TriggerTimestamp *time.Time `json:"triggerTimestamp,omitempty"`
|
||||||
|
Time *uint32 `json:"time,omitempty"`
|
||||||
|
DataTotalVolume *uint64 `json:"dataTotalVolume,omitempty"`
|
||||||
|
DataVolumeUplink *uint64 `json:"dataVolumeUplink,omitempty"`
|
||||||
|
DataVolumeDownlink *uint64 `json:"dataVolumeDownlink,omitempty"`
|
||||||
|
ServiceSpecificUnits *uint64 `json:"serviceSpecificUnits,omitempty"`
|
||||||
|
EventTimeStamp *time.Time `json:"eventTimeStamp,omitempty"`
|
||||||
|
LocalSequenceNumber int32 `json:"localSequenceNumber"`
|
||||||
|
//PDUContainerInformation *PduContainerInformation `json:"pDUContainerInformation,omitempty"`
|
||||||
|
//NSPAContainerInformation *NspaContainerInformation `json:"nSPAContainerInformation,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrMultipleUnitUsage struct {
|
||||||
|
RatingGroup uint32 `json:"ratingGroup" yaml:"ratingGroup" bson:"ratingGroup" mapstructure:"RatingGroup"`
|
||||||
|
UsedUnitContainer []CdrUsedUnitContainer `json:"usedUnitContainer,omitempty" yaml:"usedUnitContainer" bson:"usedUnitContainer" mapstructure:"UsedUnitContainer"`
|
||||||
|
//UPFID string `json:"uPFID,omitempty" yaml:"uPFID" bson:"uPFID" mapstructure:"UPFID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrSubscriberEquipmentNumber struct {
|
||||||
|
SubscriberEquipmentNumberType string `json:"subscriberEquipmentNumberType"`
|
||||||
|
SubscriberEquipmentNumberData string `json:"subscriberEquipmentNumberData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrNetworkSliceInstanceID struct {
|
||||||
|
SST int32 `json:"sST"`
|
||||||
|
|
||||||
|
SD string `json:"sD,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrPduAddress struct {
|
||||||
|
PDUIPv4Address string `json:"pDUIPv4Address,omitempty"`
|
||||||
|
PDUIPv6AddresswithPrefix string `json:"pDUIPv6AddresswithPrefix,omitempty"`
|
||||||
|
IPV4dynamicAddressFlag bool `json:"iPV4dynamicAddressFlag,omitempty"`
|
||||||
|
IPV6dynamicPrefixFlag bool `json:"iPv6dynamicPrefixFlag,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrArp struct {
|
||||||
|
PriorityLevel int32 `json:"priorityLevel"`
|
||||||
|
PreemptionCapability string `json:"preemptionCapability"`
|
||||||
|
PreemptionVulnerability string `json:"preemptionVulnerability"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrAuthorizedQosInformation struct {
|
||||||
|
FiveQi int `json:"fiveQi"`
|
||||||
|
ARP *CdrArp `json:"aRP,omitempty"`
|
||||||
|
PriorityLevel *int32 `json:"priorityLevel,omitempty"`
|
||||||
|
AverWindow *int32 `json:"averWindow,omitempty"`
|
||||||
|
MaxDataBurstVol *int32 `json:"maxDataBurstVol,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrSubscribedDefaultQos struct {
|
||||||
|
FiveQi int32 `json:"fiveQi,omitempty"`
|
||||||
|
ARP CdrArp `json:"aRP,omitempty"`
|
||||||
|
PriorityLevel *int32 `json:"priorityLevel,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrSessionAmbr struct {
|
||||||
|
Uplink string `json:"uplink"`
|
||||||
|
|
||||||
|
Downlink string `json:"downlink"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CdrPDUSessionChargingInformation struct {
|
||||||
|
PDUSessionChargingID int32 `json:"pDUSessionChargingID"`
|
||||||
|
UserIdentifier string `json:"userIdentifier,omitempty"` // isdn
|
||||||
|
UserEquipmentInfo *CdrSubscriberEquipmentNumber `json:"userEquipmentInfo,omitempty"` // imei/imeisv
|
||||||
|
//UserLocationInfomation *UserLocation `json:"userLocationinfo,omitempty"`
|
||||||
|
UserRoamerInOut string `json:"userRoamerInOut,omitempty"`
|
||||||
|
PDUSessionId int32 `json:"pDUSessionId"`
|
||||||
|
NetworkSliceInstanceID *CdrNetworkSliceInstanceID `json:"networkSliceInstanceID,omitempty"`
|
||||||
|
//PDUType PduSessionType `json:"pDUType,omitempty"`
|
||||||
|
SSCMode string `json:"sSCMode,omitempty"`
|
||||||
|
DNNID string `json:"dNNID"`
|
||||||
|
SUPIPLMNIdentifier string `json:"sUPIPLMNIdentifier,omitempty"`
|
||||||
|
//ServingNetworkFunctionID *ServingNetworkFunctionId `json:"servingNetworkFunctionID,omitempty"`
|
||||||
|
//RATType RatType `json:"rATType,omitempty"`
|
||||||
|
DataNetworkNameIdentifier string `json:"dataNetworkNameIdentifier,omitempty"`
|
||||||
|
PDUAddress CdrPduAddress `json:"pDUAddress,omitempty"`
|
||||||
|
AuthorizedQoSInformation *CdrAuthorizedQosInformation `json:"authorizedQoSInformation,omitempty"`
|
||||||
|
UETimeZone string `json:"uETimeZone,omitempty"`
|
||||||
|
PDUSessionstartTime *time.Time `json:"pDUSessionstartTime,omitempty"`
|
||||||
|
PDUSessionstopTime *time.Time `json:"pDUSessionstopTime,omitempty"`
|
||||||
|
Diagnostics *int `json:"diagnostics,omitempty"`
|
||||||
|
ChargingCharacteristics string `json:"chargingCharacteristics,omitempty"`
|
||||||
|
ChChSelectionMode string `json:"chChSelectionMode,omitempty"`
|
||||||
|
ThreeGPPPSDataOffStatus string `json:"threeGPPPSDataOffStatus,omitempty"`
|
||||||
|
//RANSecondaryRATUsageReport *RanSecondaryRatUsageReport `json:"rANSecondaryRATUsageReport,omitempty"`
|
||||||
|
SubscribedQoSInformation *CdrSubscribedDefaultQos `json:"subscribedQoSInformation,omitempty"`
|
||||||
|
AuthorizedSessionAMBR *CdrSessionAmbr `json:"authorizedSessionAMBR,omitempty"`
|
||||||
|
SubscribedSessionAMBR *CdrSessionAmbr `json:"subscribedSessionAMBR,omitempty"`
|
||||||
|
ServingCNPLMNID string `json:"servingCNPLMNID,omitempty"`
|
||||||
|
DnnSelectionMode string `json:"dnnSelectionMode,omitempty"`
|
||||||
|
HomeProvidedChargingID int32 `json:"homeProvidedChargingID,omitempty"`
|
||||||
|
|
||||||
|
//MAPDUNon3GPPUserLocationInfo *UserLocation `json:"mAPDUNon3GPPUserLocationInfo,omitempty" yaml:"mAPDUNon3GPPUserLocationInfo" bson:"mAPDUNon3GPPUserLocationInfo" mapstructure:"MAPDUNon3GPPUserLocationInfo"`
|
||||||
|
//PresenceReportingAreaInformation map[string]PresenceInfo `json:"presenceReportingAreaInformation,omitempty" yaml:"presenceReportingAreaInformation" bson:"presenceReportingAreaInformation" mapstructure:"PresenceReportingAreaInformation"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CauseForRecordClosing string
|
||||||
|
|
||||||
|
const (
|
||||||
|
NormalRelease CauseForRecordClosing = "normalRelease"
|
||||||
|
PartialRecord CauseForRecordClosing = "partialRecord"
|
||||||
|
AbnormalRelease CauseForRecordClosing = "abnormalRelease"
|
||||||
|
CAMELInitCallRelease CauseForRecordClosing = "cAMELInitCallRelease"
|
||||||
|
VolumeLimit CauseForRecordClosing = "volumeLimit"
|
||||||
|
TimeLimit CauseForRecordClosing = "timeLimit"
|
||||||
|
ServingNodeChange CauseForRecordClosing = "servingNodeChange"
|
||||||
|
MaxChangeCond CauseForRecordClosing = "maxChangeCond"
|
||||||
|
ManagementIntervention CauseForRecordClosing = "managementIntervention"
|
||||||
|
IntraSGSNIntersystemChange CauseForRecordClosing = "intraSGSNIntersystemChange"
|
||||||
|
RATChange CauseForRecordClosing = "rATChange"
|
||||||
|
MSTimeZoneChange CauseForRecordClosing = "mSTimeZoneChange"
|
||||||
|
SGSNPLMNIDChange CauseForRecordClosing = "sGSNPLMNIDChange "
|
||||||
|
SGWChange CauseForRecordClosing = "sGWChange"
|
||||||
|
APNAMBRChange CauseForRecordClosing = "aPNAMBRChange"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ChargingRecord struct {
|
||||||
|
RecordType string `json:"recordType"`
|
||||||
|
ChargingID int `json:"chargingID"`
|
||||||
|
RecordingNetworkFunctionID string `json:"recordingNetworkFunctionID"` // UUID
|
||||||
|
SubscriberIdentifier CdrSubscriptionID `json:"subscriberIdentifier,omitempty"`
|
||||||
|
NFunctionConsumerInformation CdrNetWorkFuctionInfomation `json:"nFunctionConsumerInformation"`
|
||||||
|
Triggers []CdrSMFTrigger `json:"triggers,omitempty"`
|
||||||
|
ListOfMultipleUnitUsage []CdrMultipleUnitUsage `json:"listOfMultipleUnitUsage,omitempty"`
|
||||||
|
RecordOpeningTime string `json:"recordOpeningTime"`
|
||||||
|
Duration int `json:"duration"`
|
||||||
|
RecordSequenceNumber int `json:"recordSequenceNumber,omitempty"`
|
||||||
|
CauseForRecClosing CauseForRecordClosing `json:"causeForRecClosing"`
|
||||||
|
Diagnostics *int `json:"diagnostics,omitempty"`
|
||||||
|
LocalRecordSequenceNumber int `json:"localRecordSequenceNumber,omitempty"`
|
||||||
|
PDUSessionChargingInformation CdrPDUSessionChargingInformation `json:"pDUSessionChargingInformation,omitempty"`
|
||||||
|
InvocationTimestamp string `json:"invocationTimestamp,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type CDREvent struct {
|
type CDREvent struct {
|
||||||
NeType string `json:"neType" xorm:"ne_type"`
|
NeType string `json:"neType" xorm:"ne_type"`
|
||||||
NeName string `json:"neName" xorm:"ne_name"`
|
NeName string `json:"neName" xorm:"ne_name"`
|
||||||
@@ -29,8 +214,8 @@ type CDREvent struct {
|
|||||||
CDR map[string]any `json:"CDR" xorm:"cdr_json"`
|
CDR map[string]any `json:"CDR" xorm:"cdr_json"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func PostCDREventFromNF(w http.ResponseWriter, r *http.Request) {
|
func PostCDREventFromIMS(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Info("PostCDREventFromNF processing... ")
|
log.Info("PostCDREventFromIMS processing... ")
|
||||||
|
|
||||||
// body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
// body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||||
@@ -49,9 +234,9 @@ func PostCDREventFromNF(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
log.Trace("cdrEvent:", cdrEvent)
|
log.Trace("cdrEvent:", cdrEvent)
|
||||||
|
|
||||||
affected, err := dborm.XormInsertTableOne("cdr_event", cdrEvent)
|
affected, err := dborm.XormInsertTableOne("cdr_event_ims", cdrEvent)
|
||||||
if err != nil && affected <= 0 {
|
if err != nil && affected <= 0 {
|
||||||
log.Error("Failed to insert cdr_event:", err)
|
log.Error("Failed to insert cdr_event_ims:", err)
|
||||||
services.ResponseInternalServerError500ProcessError(w, err)
|
services.ResponseInternalServerError500ProcessError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -65,3 +250,40 @@ func PostCDREventFromNF(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
services.ResponseStatusOK204NoContent(w)
|
services.ResponseStatusOK204NoContent(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PostCDREventFromSMF(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Info("PostCDREventFromSMF processing... ")
|
||||||
|
|
||||||
|
// body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||||
|
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Faile to io.ReadAll: ", err)
|
||||||
|
services.ResponseNotFound404UriNotExist(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cdrEvent := new(CDREvent)
|
||||||
|
err = json.Unmarshal(body, &cdrEvent)
|
||||||
|
if cdrEvent.NeType == "" || err != nil {
|
||||||
|
log.Error("Failed to Unmarshal cdrEvent:", err)
|
||||||
|
services.ResponseInternalServerError500ProcessError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Trace("cdrEvent:", cdrEvent)
|
||||||
|
|
||||||
|
affected, err := dborm.XormInsertTableOne("cdr_event_smf", cdrEvent)
|
||||||
|
if err != nil && affected <= 0 {
|
||||||
|
log.Error("Failed to insert cdr_event_smf:", err)
|
||||||
|
services.ResponseInternalServerError500ProcessError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 推送到ws订阅组
|
||||||
|
// if v, ok := cdrEvent.CDR["recordType"]; ok {
|
||||||
|
// if v == "MOC" || v == "MTSM" {
|
||||||
|
// wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_IMS_CDR, cdrEvent)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
services.ResponseStatusOK204NoContent(w)
|
||||||
|
}
|
||||||
|
|||||||
@@ -696,3 +696,33 @@ func IsRpmOrDebPackage(filePath string) int {
|
|||||||
|
|
||||||
return fileType
|
return fileType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RecurseStructToMap(obj any) map[string]any {
|
||||||
|
out := make(map[string]any)
|
||||||
|
v := reflect.ValueOf(obj)
|
||||||
|
if v.Kind() == reflect.Ptr {
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归函数,用于处理嵌套结构体
|
||||||
|
var recurse func(reflect.Value) any
|
||||||
|
recurse = func(value reflect.Value) any {
|
||||||
|
if value.Kind() == reflect.Struct {
|
||||||
|
nestedOut := make(map[string]any)
|
||||||
|
for i := 0; i < value.NumField(); i++ {
|
||||||
|
nestedOut[value.Type().Field(i).Name] = recurse(value.Field(i))
|
||||||
|
}
|
||||||
|
return nestedOut
|
||||||
|
} else if value.Kind() == reflect.Ptr {
|
||||||
|
return recurse(value.Elem())
|
||||||
|
}
|
||||||
|
return value.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
t := v.Type()
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
f := v.Field(i)
|
||||||
|
out[t.Field(i).Name] = recurse(f)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|||||||
@@ -300,8 +300,13 @@ func init() {
|
|||||||
Register("GET", ue.UriNSSFSubscriptions, ue.GetSubscriptionsFromNSSF, nil)
|
Register("GET", ue.UriNSSFSubscriptions, ue.GetSubscriptionsFromNSSF, nil)
|
||||||
Register("GET", ue.CustomUriNSSFSubscriptions, ue.GetSubscriptionsFromNSSF, nil)
|
Register("GET", ue.CustomUriNSSFSubscriptions, ue.GetSubscriptionsFromNSSF, nil)
|
||||||
|
|
||||||
Register("POST", cdr.UriCDREvent, cdr.PostCDREventFromNF, nil)
|
// ims cdr event
|
||||||
Register("POST", cdr.CustomUriCDREvent, cdr.PostCDREventFromNF, nil)
|
Register("POST", cdr.UriIMSCDREvent, cdr.PostCDREventFromIMS, nil)
|
||||||
|
Register("POST", cdr.CustomUriIMSCDREvent, cdr.PostCDREventFromIMS, nil)
|
||||||
|
|
||||||
|
// smf cdr event
|
||||||
|
Register("POST", cdr.UriSMFCDREvent, cdr.PostCDREventFromSMF, nil)
|
||||||
|
Register("POST", cdr.CustomUriSMFCDREvent, cdr.PostCDREventFromSMF, nil)
|
||||||
|
|
||||||
// UE event
|
// UE event
|
||||||
//Register("POST", event.UriUEEvent, event.PostUEEventFromAMF, nil)
|
//Register("POST", event.UriUEEvent, event.PostUEEventFromAMF, nil)
|
||||||
|
|||||||
80
src/modules/network_data/controller/smf.go
Normal file
80
src/modules/network_data/controller/smf.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"be.ems/src/framework/i18n"
|
||||||
|
"be.ems/src/framework/utils/ctx"
|
||||||
|
"be.ems/src/framework/utils/parse"
|
||||||
|
"be.ems/src/framework/vo/result"
|
||||||
|
"be.ems/src/modules/network_data/model"
|
||||||
|
neDataService "be.ems/src/modules/network_data/service"
|
||||||
|
neService "be.ems/src/modules/network_element/service"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化控制层 IMSController 结构体
|
||||||
|
var NewSMFController = &SMFController{
|
||||||
|
neInfoService: neService.NewNeInfoImpl,
|
||||||
|
cdrEventService: neDataService.NewSMFCDREventImpl,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 网元IMS
|
||||||
|
//
|
||||||
|
// PATH /ims
|
||||||
|
type SMFController struct {
|
||||||
|
// 网元信息服务
|
||||||
|
neInfoService neService.INeInfo
|
||||||
|
// SMF CDR会话事件服务
|
||||||
|
cdrEventService neDataService.SMFCDREvent
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDR会话列表
|
||||||
|
//
|
||||||
|
// GET /cdr/list
|
||||||
|
func (s *SMFController) CDRList(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
var querys model.SMFCDREventQuery
|
||||||
|
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||||
|
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
querys.RmUID = neInfo.RmUID
|
||||||
|
|
||||||
|
// 查询数据
|
||||||
|
data := s.cdrEventService.SelectPage(querys)
|
||||||
|
c.JSON(200, result.Ok(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDR会话删除
|
||||||
|
//
|
||||||
|
// DELETE /cdr/:cdrIds
|
||||||
|
func (s *SMFController) CDRRemove(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
cdrIds := c.Param("cdrIds")
|
||||||
|
if cdrIds == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 处理字符转id数组后去重
|
||||||
|
ids := strings.Split(cdrIds, ",")
|
||||||
|
uniqueIDs := parse.RemoveDuplicates(ids)
|
||||||
|
if len(uniqueIDs) <= 0 {
|
||||||
|
c.JSON(200, result.Err(nil))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rows, err := s.cdrEventService.DeleteByIds(uniqueIDs)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||||
|
c.JSON(200, result.OkMsg(msg))
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package model
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// CDREvent CDR会话对象 cdr_event
|
// CDREvent CDR会话对象 cdr_event_ims/cdr_event_smf
|
||||||
type CDREvent struct {
|
type CDREvent struct {
|
||||||
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||||
@@ -15,7 +15,7 @@ type CDREvent struct {
|
|||||||
|
|
||||||
// CDREventQuery CDR会话对象查询参数结构体
|
// CDREventQuery CDR会话对象查询参数结构体
|
||||||
type CDREventQuery struct {
|
type CDREventQuery struct {
|
||||||
NeType string `json:"neType" form:"neType" binding:"required"` // 网元类型, 暂时支持IMS
|
NeType string `json:"neType" form:"neType" binding:"required"` // 网元类型
|
||||||
NeID string `json:"neId" form:"neId" binding:"required"`
|
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||||
RmUID string `json:"rmUID" form:"rmUID"`
|
RmUID string `json:"rmUID" form:"rmUID"`
|
||||||
RecordType string `json:"recordType" form:"recordType"` // 记录行为 MOC MTC MOSM MTSM
|
RecordType string `json:"recordType" form:"recordType"` // 记录行为 MOC MTC MOSM MTSM
|
||||||
|
|||||||
35
src/modules/network_data/model/cdr_event_smf.go
Normal file
35
src/modules/network_data/model/cdr_event_smf.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// CDREvent CDR会话对象 cdr_event_smf
|
||||||
|
type CDREventSMF struct {
|
||||||
|
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||||
|
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||||
|
NeName string `json:"neName" gorm:"column:ne_name"`
|
||||||
|
RmUID string `json:"rmUID" gorm:"column:rm_uid"`
|
||||||
|
Timestamp int64 `json:"timestamp" gorm:"column:timestamp"`
|
||||||
|
RecordType string `json:"recordType" gorm:"column:record_type"`
|
||||||
|
ChargingID string `json:"chargingID" gorm:"column:charging_id"`
|
||||||
|
SubscriberID string `json:"subscriberID" gorm:"column:subscriber_id"`
|
||||||
|
Duration string `json:"duration" gorm:"column:duration"`
|
||||||
|
DataVolumeUplink string `json:"dataVolumeUplink" gorm:"column:data_volume_uplink"`
|
||||||
|
DataVolumeDownlink string `json:"dataVolumeDownlink" gorm:"column:data_volume_downlink"`
|
||||||
|
DataTotalVolume string `json:"dataTotalVolume" gorm:"column:data_total_volume"`
|
||||||
|
PDUAddress string `json:"pduAddress" gorm:"column:pdu_address"`
|
||||||
|
CreatedAt time.Time `json:"createdAt" gorm:"column:created_at;default:CURRENT_TIMESTAMP"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SMFCDREventQuery struct {
|
||||||
|
NeType string `json:"neType" form:"neType" binding:"required"` // SMF
|
||||||
|
NeID string `json:"neId" form:"neId" binding:"required"`
|
||||||
|
RmUID string `json:"rmUID" form:"rmUID"`
|
||||||
|
RecordType string `json:"recordType" form:"recordType"`
|
||||||
|
SubscriberID string `json:"subscriberID" form:"subscriberID"`
|
||||||
|
StartTime string `json:"startTime" form:"startTime"`
|
||||||
|
EndTime string `json:"endTime" form:"endTime"`
|
||||||
|
SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=timestamp"` // 排序字段,填写结果字段
|
||||||
|
SortOrder string `json:"sortOrder" form:"sortOrder" binding:"omitempty,oneof=asc desc"` // 排序升降序,asc desc
|
||||||
|
PageNum int64 `json:"pageNum" form:"pageNum" binding:"required"`
|
||||||
|
PageSize int64 `json:"pageSize" form:"pageSize" binding:"required"`
|
||||||
|
}
|
||||||
@@ -57,6 +57,22 @@ func Setup(router *gin.Engine) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 网元SMF
|
||||||
|
smfGroup := neDataGroup.Group("/smf")
|
||||||
|
{
|
||||||
|
// CDR会话事件列表
|
||||||
|
smfGroup.GET("/cdr/list",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
controller.NewSMFController.CDRList,
|
||||||
|
)
|
||||||
|
// CDR会话删除
|
||||||
|
smfGroup.DELETE("/cdr/:cdrIds",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smfCDR", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||||
|
controller.NewSMFController.CDRRemove,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// 网元AMF
|
// 网元AMF
|
||||||
amfGroup := neDataGroup.Group("/amf")
|
amfGroup := neDataGroup.Group("/amf")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,3 +13,15 @@ type ICDREvent interface {
|
|||||||
// DeleteByIds 批量删除信息
|
// DeleteByIds 批量删除信息
|
||||||
DeleteByIds(cdrIds []string) int64
|
DeleteByIds(cdrIds []string) int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SMF CDR Event
|
||||||
|
type SMFCDREvent interface {
|
||||||
|
// SelectPage 根据条件分页查询
|
||||||
|
SelectPage(querys model.SMFCDREventQuery) map[string]any
|
||||||
|
|
||||||
|
// SelectByIds 通过ID查询
|
||||||
|
SelectByIds(cdrIds []string) []model.CDREventSMF
|
||||||
|
|
||||||
|
// DeleteByIds 批量删除信息
|
||||||
|
DeleteByIds(cdrIds []string) int64
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
// 实例化数据层 CDREventImpl 结构体
|
// 实例化数据层 CDREventImpl 结构体
|
||||||
var NewCDREventImpl = &CDREventImpl{
|
var NewCDREventImpl = &CDREventImpl{
|
||||||
selectSql: `select id, ne_type, ne_name, rm_uid, timestamp, cdr_json, created_at from cdr_event`,
|
selectSql: `select id, ne_type, ne_name, rm_uid, timestamp, cdr_json, created_at from cdr_event_ims`,
|
||||||
|
|
||||||
resultMap: map[string]string{
|
resultMap: map[string]string{
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
@@ -35,6 +35,36 @@ type CDREventImpl struct {
|
|||||||
resultMap map[string]string
|
resultMap map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Instance of SMF CDREventImpl
|
||||||
|
var NewSMFCDREventImpl = &SMFCDREventImpl{
|
||||||
|
selectSql: `select id, ne_type, ne_name, rm_uid, timestamp, JSON_EXTRACT(cdr_json, '$.recordType') AS record_type, JSON_EXTRACT(cdr_json, '$.chargingID') AS charging_id, JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') AS subscriber_id, JSON_EXTRACT(cdr_json, '$.duration') AS duration, JSON_EXTRACT(cdr_json, '$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink') AS data_volume_uplink, JSON_EXTRACT(cdr_json, '$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink') AS data_volume_downlink, JSON_EXTRACT(cdr_json, '$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume') AS data_total_volume, JSON_EXTRACT(cdr_json, '$.pDUSessionChargingInformation.pDUAddress') AS pdu_address, created_at from cdr_event_smf`,
|
||||||
|
|
||||||
|
resultMap: map[string]string{
|
||||||
|
"id": "ID",
|
||||||
|
"ne_type": "NeType",
|
||||||
|
"ne_name": "NeName",
|
||||||
|
"rm_uid": "RmUID",
|
||||||
|
"timestamp": "Timestamp",
|
||||||
|
"record_type": "RecordType",
|
||||||
|
"charging_id": "ChargingID",
|
||||||
|
"subscriber_id": "SubscriberID",
|
||||||
|
"duration": "Duration",
|
||||||
|
"data_volume_uplink": "DataVolumeUplink",
|
||||||
|
"data_volume_downlink": "DataVolumeDownlink",
|
||||||
|
"data_total_volume": "DataTotalVolume",
|
||||||
|
"pdu_address": "PDUAddress",
|
||||||
|
"created_at": "CreatedAt",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDREventImpl CDR会话事件 数据层处理
|
||||||
|
type SMFCDREventImpl struct {
|
||||||
|
// 查询视图对象SQL
|
||||||
|
selectSql string
|
||||||
|
// 结果字段与实体映射
|
||||||
|
resultMap map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
// convertResultRows 将结果记录转实体结果组
|
// convertResultRows 将结果记录转实体结果组
|
||||||
func (r *CDREventImpl) convertResultRows(rows []map[string]any) []model.CDREvent {
|
func (r *CDREventImpl) convertResultRows(rows []map[string]any) []model.CDREvent {
|
||||||
arr := make([]model.CDREvent, 0)
|
arr := make([]model.CDREvent, 0)
|
||||||
@@ -102,7 +132,7 @@ func (r *CDREventImpl) SelectPage(querys model.CDREventQuery) map[string]any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询数量 长度为0直接返回
|
// 查询数量 长度为0直接返回
|
||||||
totalSql := "select count(1) as 'total' from cdr_event"
|
totalSql := "select count(1) as 'total' from cdr_event_ims"
|
||||||
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("total err => %v", err)
|
logger.Errorf("total err => %v", err)
|
||||||
@@ -164,7 +194,146 @@ func (r *CDREventImpl) SelectByIds(cdrIds []string) []model.CDREvent {
|
|||||||
// DeleteByIds 批量删除信息
|
// DeleteByIds 批量删除信息
|
||||||
func (r *CDREventImpl) DeleteByIds(cdrIds []string) int64 {
|
func (r *CDREventImpl) DeleteByIds(cdrIds []string) int64 {
|
||||||
placeholder := repo.KeyPlaceholderByQuery(len(cdrIds))
|
placeholder := repo.KeyPlaceholderByQuery(len(cdrIds))
|
||||||
sql := "delete from cdr_event where id in (" + placeholder + ")"
|
sql := "delete from cdr_event_ims where id in (" + placeholder + ")"
|
||||||
|
parameters := repo.ConvertIdsSlice(cdrIds)
|
||||||
|
results, err := datasource.ExecDB("", sql, parameters)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("delete err => %v", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertResultRows 将结果记录转实体结果组
|
||||||
|
func (r *SMFCDREventImpl) convertResultRows(rows []map[string]any) []model.CDREventSMF {
|
||||||
|
arr := make([]model.CDREventSMF, 0)
|
||||||
|
for _, row := range rows {
|
||||||
|
item := model.CDREventSMF{}
|
||||||
|
for key, value := range row {
|
||||||
|
if keyMapper, ok := r.resultMap[key]; ok {
|
||||||
|
repo.SetFieldValue(&item, keyMapper, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arr = append(arr, item)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectPage 根据条件分页查询
|
||||||
|
func (r *SMFCDREventImpl) SelectPage(querys model.SMFCDREventQuery) map[string]any {
|
||||||
|
// 查询条件拼接
|
||||||
|
var conditions []string
|
||||||
|
var params []any
|
||||||
|
if querys.NeType != "" {
|
||||||
|
conditions = append(conditions, "ne_type = ?")
|
||||||
|
params = append(params, querys.NeType)
|
||||||
|
}
|
||||||
|
if querys.RmUID != "" {
|
||||||
|
conditions = append(conditions, "rm_uid = ?")
|
||||||
|
params = append(params, querys.RmUID)
|
||||||
|
}
|
||||||
|
if querys.StartTime != "" {
|
||||||
|
conditions = append(conditions, "timestamp >= ?")
|
||||||
|
beginDate := date.ParseStrToDate(querys.StartTime, date.YYYY_MM_DD_HH_MM_SS)
|
||||||
|
params = append(params, beginDate.Unix())
|
||||||
|
}
|
||||||
|
if querys.EndTime != "" {
|
||||||
|
conditions = append(conditions, "timestamp <= ?")
|
||||||
|
endDate := date.ParseStrToDate(querys.EndTime, date.YYYY_MM_DD_HH_MM_SS)
|
||||||
|
params = append(params, endDate.Unix())
|
||||||
|
}
|
||||||
|
if querys.RecordType != "" {
|
||||||
|
conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.recordType') = ?")
|
||||||
|
params = append(params, querys.RecordType)
|
||||||
|
}
|
||||||
|
if querys.SubscriberID != "" {
|
||||||
|
conditions = append(conditions, "JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') = ?")
|
||||||
|
params = append(params, querys.SubscriberID)
|
||||||
|
}
|
||||||
|
// if querys.RecordType != "" {
|
||||||
|
// recordTypes := strings.Split(querys.RecordType, ",")
|
||||||
|
// placeholder := repo.KeyPlaceholderByQuery(len(recordTypes))
|
||||||
|
// conditions = append(conditions, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') in (%s)", placeholder))
|
||||||
|
// for _, recordType := range recordTypes {
|
||||||
|
// params = append(params, recordType)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 构建查询条件语句
|
||||||
|
whereSql := ""
|
||||||
|
if len(conditions) > 0 {
|
||||||
|
whereSql += " where " + strings.Join(conditions, " and ")
|
||||||
|
}
|
||||||
|
|
||||||
|
result := map[string]any{
|
||||||
|
"total": 0,
|
||||||
|
"rows": []model.CDREventSMF{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询数量 长度为0直接返回
|
||||||
|
totalSql := "select count(1) as 'total' from cdr_event_smf"
|
||||||
|
totalRows, err := datasource.RawDB("", totalSql+whereSql, params)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("total err => %v", err)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
total := parse.Number(totalRows[0]["total"])
|
||||||
|
if total == 0 {
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
result["total"] = total
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
pageNum, pageSize := repo.PageNumSize(querys.PageNum, querys.PageSize)
|
||||||
|
pageSql := " limit ?,? "
|
||||||
|
params = append(params, pageNum*pageSize)
|
||||||
|
params = append(params, pageSize)
|
||||||
|
|
||||||
|
// 排序
|
||||||
|
orderSql := ""
|
||||||
|
if querys.SortField != "" {
|
||||||
|
sortSql := querys.SortField
|
||||||
|
if querys.SortOrder != "" {
|
||||||
|
if querys.SortOrder == "desc" {
|
||||||
|
sortSql += " desc "
|
||||||
|
} else {
|
||||||
|
sortSql += " asc "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
orderSql = fmt.Sprintf(" order by id desc, %s ", sortSql)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询数据
|
||||||
|
querySql := r.selectSql + whereSql + orderSql + pageSql
|
||||||
|
results, err := datasource.RawDB("", querySql, params)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("query err => %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换实体
|
||||||
|
result["rows"] = r.convertResultRows(results)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectByIds 通过ID查询
|
||||||
|
func (r *SMFCDREventImpl) SelectByIds(cdrIds []string) []model.CDREventSMF {
|
||||||
|
placeholder := repo.KeyPlaceholderByQuery(len(cdrIds))
|
||||||
|
querySql := r.selectSql + " where id in (" + placeholder + ")"
|
||||||
|
parameters := repo.ConvertIdsSlice(cdrIds)
|
||||||
|
results, err := datasource.RawDB("", querySql, parameters)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("query err => %v", err)
|
||||||
|
return []model.CDREventSMF{}
|
||||||
|
}
|
||||||
|
// 转换实体
|
||||||
|
return r.convertResultRows(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteByIds 批量删除信息
|
||||||
|
func (r *SMFCDREventImpl) DeleteByIds(cdrIds []string) int64 {
|
||||||
|
placeholder := repo.KeyPlaceholderByQuery(len(cdrIds))
|
||||||
|
sql := "delete from cdr_event_smf where id in (" + placeholder + ")"
|
||||||
parameters := repo.ConvertIdsSlice(cdrIds)
|
parameters := repo.ConvertIdsSlice(cdrIds)
|
||||||
results, err := datasource.ExecDB("", sql, parameters)
|
results, err := datasource.ExecDB("", sql, parameters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -10,3 +10,12 @@ type ICDREvent interface {
|
|||||||
// DeleteByIds 批量删除信息
|
// DeleteByIds 批量删除信息
|
||||||
DeleteByIds(cdrIds []string) (int64, error)
|
DeleteByIds(cdrIds []string) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CDR会话事件 服务层接口
|
||||||
|
type SMFCDREvent interface {
|
||||||
|
// SelectPage 根据条件分页查询
|
||||||
|
SelectPage(querys model.SMFCDREventQuery) map[string]any
|
||||||
|
|
||||||
|
// DeleteByIds 批量删除信息
|
||||||
|
DeleteByIds(cdrIds []string) (int64, error)
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,12 +12,21 @@ var NewCDREventImpl = &CDREventImpl{
|
|||||||
cdrEventRepository: repository.NewCDREventImpl,
|
cdrEventRepository: repository.NewCDREventImpl,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var NewSMFCDREventImpl = &SMFCDREventImpl{
|
||||||
|
cdrEventRepository: repository.NewSMFCDREventImpl,
|
||||||
|
}
|
||||||
|
|
||||||
// CDREventImpl CDR会话事件 服务层处理
|
// CDREventImpl CDR会话事件 服务层处理
|
||||||
type CDREventImpl struct {
|
type CDREventImpl struct {
|
||||||
// CDR会话事件数据信息
|
// CDR会话事件数据信息
|
||||||
cdrEventRepository repository.ICDREvent
|
cdrEventRepository repository.ICDREvent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SMFCDREventImpl struct {
|
||||||
|
// CDR会话事件数据信息
|
||||||
|
cdrEventRepository repository.SMFCDREvent
|
||||||
|
}
|
||||||
|
|
||||||
// SelectPage 根据条件分页查询
|
// SelectPage 根据条件分页查询
|
||||||
func (r *CDREventImpl) SelectPage(querys model.CDREventQuery) map[string]any {
|
func (r *CDREventImpl) SelectPage(querys model.CDREventQuery) map[string]any {
|
||||||
return r.cdrEventRepository.SelectPage(querys)
|
return r.cdrEventRepository.SelectPage(querys)
|
||||||
@@ -38,3 +47,23 @@ func (r *CDREventImpl) DeleteByIds(cdrIds []string) (int64, error) {
|
|||||||
// 删除信息失败!
|
// 删除信息失败!
|
||||||
return 0, fmt.Errorf("delete fail")
|
return 0, fmt.Errorf("delete fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *SMFCDREventImpl) SelectPage(querys model.SMFCDREventQuery) map[string]any {
|
||||||
|
return r.cdrEventRepository.SelectPage(querys)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteByIds 批量删除信息
|
||||||
|
func (r *SMFCDREventImpl) DeleteByIds(cdrIds []string) (int64, error) {
|
||||||
|
// 检查是否存在
|
||||||
|
ids := r.cdrEventRepository.SelectByIds(cdrIds)
|
||||||
|
if len(ids) <= 0 {
|
||||||
|
return 0, fmt.Errorf("not data")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ids) == len(cdrIds) {
|
||||||
|
rows := r.cdrEventRepository.DeleteByIds(cdrIds)
|
||||||
|
return rows, nil
|
||||||
|
}
|
||||||
|
// 删除信息失败!
|
||||||
|
return 0, fmt.Errorf("delete fail")
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,3 +27,21 @@ func GetCDRConnect(requestID string, data any) ([]byte, error) {
|
|||||||
}))
|
}))
|
||||||
return resultByte, err
|
return resultByte, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCDRConnect 获取CDR会话事件-SMF
|
||||||
|
func GetSMFCDRConnect(requestID string, data any) ([]byte, error) {
|
||||||
|
msgByte, _ := json.Marshal(data)
|
||||||
|
var query neDataModel.SMFCDREventQuery
|
||||||
|
err := json.Unmarshal(msgByte, &query)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warnf("ws processor GetCDRConnect err: %s", err.Error())
|
||||||
|
return nil, fmt.Errorf("query data structure error")
|
||||||
|
}
|
||||||
|
|
||||||
|
dataMap := neDataService.NewSMFCDREventImpl.SelectPage(query)
|
||||||
|
resultByte, err := json.Marshal(result.Ok(map[string]any{
|
||||||
|
"requestId": requestID,
|
||||||
|
"data": dataMap,
|
||||||
|
}))
|
||||||
|
return resultByte, err
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user