fix: SMF-CDR/SGWC-CDR导出表格流量进行累加不分组

This commit is contained in:
TsMask
2024-12-26 18:45:40 +08:00
parent 2d3aa9b737
commit 8911468c7a
4 changed files with 372 additions and 364 deletions

View File

@@ -1,16 +1,12 @@
package controller
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"be.ems/src/framework/i18n"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/network_data/model"
@@ -116,173 +112,8 @@ func (s *SGWCController) CDRExport(c *gin.Context) {
// 导出文件名称
fileName := fmt.Sprintf("sgwc_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
// 第一行表头标题
headerCells := map[string]string{
"A1": "ID",
"B1": "NE Name",
"C1": "Resource Unique ID",
"D1": "Charging ID",
"E1": "IMSI",
"F1": "MSISDN",
"G1": "GPRS Uplink",
"H1": "GPRS Downlink",
"I1": "Duration",
"J1": "Invocation Time",
"K1": "PGW Address Used",
"L1": "SGW Address",
"M1": "RAT Type",
"N1": "PDPPDN Type",
"O1": "PDPPDN Address",
"P1": "Node Address",
"Q1": "Node Type",
"R1": "Record Access Point Name NI",
"S1": "Record Cause For Rec Closing",
"T1": "Record Sequence Number",
"U1": "Local Record Sequence Number",
}
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
for i, row := range rows {
idx := strconv.Itoa(i + 2)
// 解析 JSON 字符串为 map
var cdrJSON map[string]interface{}
err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON)
if err != nil {
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
continue
}
// 计费ID
chargingID := ""
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
chargingID = fmt.Sprint(parse.Number(v))
}
// IMSI
servedIMSI := ""
if v, ok := cdrJSON["servedIMSI"]; ok && v != nil {
servedIMSI = fmt.Sprint(v)
}
// MSISDN
servedMSISDN := ""
if v, ok := cdrJSON["servedMSISDN"]; ok && v != nil {
servedMSISDN = fmt.Sprint(v)
}
// pGWAddressUsed
pGWAddressUsed := ""
if v, ok := cdrJSON["pGWAddressUsed"]; ok && v != nil {
pGWAddressUsed = fmt.Sprint(v)
}
// sGWAddress
sGWAddress := ""
if v, ok := cdrJSON["sGWAddress"]; ok && v != nil {
sGWAddress = fmt.Sprint(v)
}
// rATType
rATType := ""
if v, ok := cdrJSON["rATType"]; ok && v != nil {
rATType = fmt.Sprint(v)
}
// pdpPDNType
pdpPDNType := ""
if v, ok := cdrJSON["pdpPDNType"]; ok && v != nil {
pdpPDNType = fmt.Sprint(v)
}
// servedPDPPDNAddress
servedPDPPDNAddress := ""
if v, ok := cdrJSON["servedPDPPDNAddress"]; ok && v != nil {
servedPDPPDNAddress = fmt.Sprint(v)
}
// servedPDPPDNAddress
servingNodeAddress := []string{}
if v, ok := cdrJSON["servingNodeAddress"]; ok && v != nil {
for _, v := range v.([]any) {
servingNodeAddress = append(servingNodeAddress, fmt.Sprint(v))
}
}
// servingNodeType
servingNodeType := []string{}
if v, ok := cdrJSON["servingNodeType"]; ok && v != nil {
for _, v := range v.([]any) {
if v, ok := v.(map[string]any)["servingNodeType"]; ok && v != nil {
servingNodeType = append(servingNodeType, fmt.Sprint(v))
}
}
}
// accessPointNameNI
accessPointNameNI := ""
if v, ok := cdrJSON["accessPointNameNI"]; ok && v != nil {
accessPointNameNI = fmt.Sprint(v)
}
// causeForRecClosing
causeForRecClosing := ""
if v, ok := cdrJSON["causeForRecClosing"]; ok && v != nil {
causeForRecClosing = fmt.Sprint(v)
}
// recordSequenceNumber
recordSequenceNumber := ""
if v, ok := cdrJSON["recordSequenceNumber"]; ok && v != nil {
recordSequenceNumber = fmt.Sprint(v)
}
// localRecordSequenceNumber
localRecordSequenceNumber := ""
if v, ok := cdrJSON["localRecordSequenceNumber"]; ok && v != nil {
localRecordSequenceNumber = fmt.Sprint(v)
}
// 数据量上行链路
dataVolumeGPRSUplink := []string{}
// 数据量下行链路
dataVolumeGPRSDownlink := []string{}
if v, ok := cdrJSON["listOfTrafficVolumes"]; ok && v != nil {
usageList := v.([]any)
if len(usageList) > 0 {
for _, used := range usageList {
usedUnit := used.(map[string]any)
if dup, dupOk := usedUnit["dataVolumeGPRSUplink"]; dupOk {
dataVolumeGPRSUplink = append(dataVolumeGPRSUplink, fmt.Sprint(parse.Number(dup)))
}
if ddown, ddownOk := usedUnit["dataVolumeGPRSDownlink"]; ddownOk {
dataVolumeGPRSDownlink = append(dataVolumeGPRSDownlink, fmt.Sprint(parse.Number(ddown)))
}
}
}
}
// 时长
duration := "-"
if v, ok := cdrJSON["duration"]; ok && v != nil {
duration = fmt.Sprint(parse.Number(v))
}
// 调用时间
invocationTimestamp := ""
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
invocationTimestamp = v.(string)
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.ID,
"B" + idx: row.NeName,
"C" + idx: row.RmUID,
"D" + idx: chargingID,
"E" + idx: servedIMSI,
"F" + idx: servedMSISDN,
"G" + idx: strings.Join(dataVolumeGPRSUplink, ","),
"H" + idx: strings.Join(dataVolumeGPRSDownlink, ","),
"I" + idx: duration,
"J" + idx: invocationTimestamp,
"K" + idx: pGWAddressUsed,
"L" + idx: sGWAddress,
"M" + idx: rATType,
"N" + idx: pdpPDNType,
"O" + idx: servedPDPPDNAddress,
"P" + idx: strings.Join(servingNodeAddress, ","),
"Q" + idx: strings.Join(servingNodeType, ","),
"R" + idx: accessPointNameNI,
"S" + idx: causeForRecClosing,
"T" + idx: recordSequenceNumber,
"U" + idx: localRecordSequenceNumber,
})
}
// 导出数据表格
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
saveFilePath, err := s.cdrEventService.ExportXlsx(rows, fileName)
if err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return

View File

@@ -1,16 +1,12 @@
package controller
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"be.ems/src/framework/i18n"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/parse"
"be.ems/src/framework/vo/result"
"be.ems/src/modules/network_data/model"
@@ -118,196 +114,8 @@ func (s *SMFController) CDRExport(c *gin.Context) {
// 导出文件名称
fileName := fmt.Sprintf("smf_cdr_event_export_%d_%d.xlsx", len(rows), time.Now().UnixMilli())
// 第一行表头标题
headerCells := map[string]string{
"A1": "ID",
"B1": "Charging ID",
"C1": "NE Name",
"D1": "Resource Unique ID",
"E1": "Subscriber ID Data",
"F1": "Subscriber ID Type",
"G1": "Data Volume Uplink",
"H1": "Data Volume Downlink",
"I1": "Data Total Volume",
"J1": "Duration",
"K1": "Invocation Time",
"L1": "User Identifier",
"M1": "SSC Mode",
"N1": "DNN ID",
"O1": "PDU Type",
"P1": "RAT Type",
"Q1": "PDU IPv4 Address",
"R1": "Network Function IPv4",
"S1": "PDU IPv6 Address Swith Prefix",
"T1": "Record Network Function ID",
"U1": "Record Type",
"V1": "Record Opening Time",
}
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
for i, row := range rows {
idx := strconv.Itoa(i + 2)
// 解析 JSON 字符串为 map
var cdrJSON map[string]interface{}
err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON)
if err != nil {
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
continue
}
// 计费ID
chargingID := ""
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
chargingID = fmt.Sprint(parse.Number(v))
}
// 订阅 ID 类型
subscriptionIDType := "-"
// 订阅 ID 数据
subscriptionIDData := "-"
if v, ok := cdrJSON["subscriberIdentifier"]; ok && v != nil {
if sub, subOk := v.(map[string]any); subOk && sub != nil {
subscriptionIDType = sub["subscriptionIDType"].(string)
subscriptionIDData = sub["subscriptionIDData"].(string)
}
}
// 网络功能 IPv4 地址
networkFunctionIPv4Address := ""
if v, ok := cdrJSON["nFunctionConsumerInformation"]; ok && v != nil {
if conInfo, conInfoOk := v.(map[string]any); conInfoOk && conInfo != nil {
networkFunctionIPv4Address = conInfo["networkFunctionIPv4Address"].(string)
}
}
// 数据量上行链路
dataVolumeUplink := []string{}
// 数据量下行链路
dataVolumeDownlink := []string{}
// 数据总量
dataTotalVolume := []string{}
if v, ok := cdrJSON["listOfMultipleUnitUsage"]; ok && v != nil {
usageList := v.([]any)
if len(usageList) > 0 {
for _, used := range usageList {
usedUnit := used.(map[string]any)
usedUnitList := usedUnit["usedUnitContainer"].([]any)
if len(usedUnitList) > 0 {
for _, data := range usedUnitList {
udata := data.(map[string]any)
if dup, dupOk := udata["dataVolumeUplink"]; dupOk {
dataVolumeUplink = append(dataVolumeUplink, fmt.Sprint(parse.Number(dup)))
}
if ddown, ddownOk := udata["dataVolumeDownlink"]; ddownOk {
dataVolumeDownlink = append(dataVolumeDownlink, fmt.Sprint(parse.Number(ddown)))
}
if dt, dtOk := udata["dataTotalVolume"]; dtOk {
dataTotalVolume = append(dataTotalVolume, fmt.Sprint(parse.Number(dt)))
}
}
}
}
}
}
// 时长
duration := "-"
if v, ok := cdrJSON["duration"]; ok && v != nil {
duration = fmt.Sprint(parse.Number(v))
}
// 调用时间
invocationTimestamp := ""
if v, ok := cdrJSON["invocationTimestamp"]; ok && v != nil {
invocationTimestamp = v.(string)
}
// 记录打开时间
User_Identifier := ""
SSC_Mode := ""
RAT_Type := ""
DNN_ID := ""
PDU_Type := ""
PDU_IPv4 := ""
PDU_IPv6 := ""
if v, ok := cdrJSON["pDUSessionChargingInformation"]; ok && v != nil {
pduInfo := v.(map[string]any)
if v, ok := pduInfo["userIdentifier"]; ok && v != nil {
User_Identifier = v.(string)
}
if v, ok := pduInfo["sSCMode"]; ok && v != nil {
SSC_Mode = v.(string)
}
if v, ok := pduInfo["rATType"]; ok && v != nil {
RAT_Type = v.(string)
}
if v, ok := pduInfo["dNNID"]; ok && v != nil {
DNN_ID = v.(string)
}
if v, ok := pduInfo["pDUType"]; ok && v != nil {
PDU_Type = v.(string)
}
if v, ok := pduInfo["pDUAddress"]; ok && v != nil {
pDUAddress := v.(map[string]any)
if addr, ok := pDUAddress["pDUIPv4Address"]; ok && addr != nil {
PDU_IPv4 = addr.(string)
}
if addr, ok := pDUAddress["pDUIPv6AddresswithPrefix"]; ok && addr != nil {
PDU_IPv6 = addr.(string)
}
}
// pduSessionChargingInformation = fmt.Sprintf(`User Identifier: %s
// SSC Mode: %s RAT Type: %s DNN ID: %s
// PDU Type: %s
// PDU IPv4 Address: %s
// PDU IPv6 Addres Swith Prefix: %s`, User_Identifier, SSC_Mode, RAT_Type, DNN_ID, PDU_Type, PDU_IPv4, PDU_IPv6)
}
// 记录网络参数ID
recordNFID := ""
if v, ok := cdrJSON["recordingNetworkFunctionID"]; ok && v != nil {
recordNFID = v.(string)
}
//记录开始时间
recordOpeningTime := ""
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
recordOpeningTime = v.(string)
}
//记录类型
recordType := ""
if v, ok := cdrJSON["recordType"]; ok && v != nil {
recordType = v.(string)
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.ID,
"B" + idx: chargingID,
"C" + idx: row.NeName,
"D" + idx: row.RmUID,
"E" + idx: subscriptionIDData,
"F" + idx: subscriptionIDType,
"G" + idx: strings.Join(dataVolumeUplink, ","),
"H" + idx: strings.Join(dataVolumeDownlink, ","),
"I" + idx: strings.Join(dataTotalVolume, ","),
"J" + idx: duration,
"K" + idx: invocationTimestamp,
"L" + idx: User_Identifier,
"M" + idx: SSC_Mode,
"N" + idx: DNN_ID,
"O" + idx: PDU_Type,
"P" + idx: RAT_Type,
"Q" + idx: PDU_IPv4,
"R" + idx: networkFunctionIPv4Address,
"S" + idx: PDU_IPv6,
"T" + idx: recordNFID,
"U" + idx: recordType,
"V" + idx: recordOpeningTime,
})
}
// 导出数据表格
saveFilePath, err := file.WriteSheet(headerCells, dataCells, fileName, "")
saveFilePath, err := s.cdrEventService.ExportXlsx(rows, fileName)
if err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
@@ -393,7 +201,7 @@ func (s *SMFController) SubUserList(c *gin.Context) {
imsiStr = strings.TrimPrefix(imsiStr, "imsi-")
item["imsi"] = imsiStr
// 查UDM拓展信息
info := s.udmUserInfoService.SelectByIMSIAndNeID(imsiStr, "")
info := s.udmUserInfoService.SelectByIMSIAndNeID(imsiStr, "%")
item["remark"] = info.Remark
}
if v, ok := item["msisdn"]; ok && v != nil {

View File

@@ -1,8 +1,14 @@
package service
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/parse"
"be.ems/src/modules/network_data/model"
"be.ems/src/modules/network_data/repository"
)
@@ -37,3 +43,174 @@ func (r *CDREventSGWC) DeleteByIds(cdrIds []string) (int64, error) {
// 删除信息失败!
return 0, fmt.Errorf("delete fail")
}
// ExportXlsx 导出数据到 xlsx 文件
func (r CDREventSGWC) ExportXlsx(rows []model.CDREventSGWC, fileName string) (string, error) {
// 第一行表头标题
headerCells := map[string]string{
"A1": "ID",
"B1": "NE Name",
"C1": "Resource Unique ID",
"D1": "Charging ID",
"E1": "IMSI",
"F1": "MSISDN",
"G1": "GPRS Uplink",
"H1": "GPRS Downlink",
"I1": "Duration",
"J1": "Invocation Time",
"K1": "PGW Address Used",
"L1": "SGW Address",
"M1": "RAT Type",
"N1": "PDPPDN Type",
"O1": "PDPPDN Address",
"P1": "Node Address",
"Q1": "Node Type",
"R1": "Record Access Point Name NI",
"S1": "Record Cause For Rec Closing",
"T1": "Record Sequence Number",
"U1": "Local Record Sequence Number",
}
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
for i, row := range rows {
idx := strconv.Itoa(i + 2)
// 解析 JSON 字符串为 map
var cdrJSON map[string]interface{}
err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON)
if err != nil {
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
continue
}
// 计费ID
chargingID := ""
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
chargingID = fmt.Sprint(parse.Number(v))
}
// IMSI
servedIMSI := ""
if v, ok := cdrJSON["servedIMSI"]; ok && v != nil {
servedIMSI = fmt.Sprint(v)
}
// MSISDN
servedMSISDN := ""
if v, ok := cdrJSON["servedMSISDN"]; ok && v != nil {
servedMSISDN = fmt.Sprint(v)
}
// pGWAddressUsed
pGWAddressUsed := ""
if v, ok := cdrJSON["pGWAddressUsed"]; ok && v != nil {
pGWAddressUsed = fmt.Sprint(v)
}
// sGWAddress
sGWAddress := ""
if v, ok := cdrJSON["sGWAddress"]; ok && v != nil {
sGWAddress = fmt.Sprint(v)
}
// rATType
rATType := ""
if v, ok := cdrJSON["rATType"]; ok && v != nil {
rATType = fmt.Sprint(v)
}
// pdpPDNType
pdpPDNType := ""
if v, ok := cdrJSON["pdpPDNType"]; ok && v != nil {
pdpPDNType = fmt.Sprint(v)
}
// servedPDPPDNAddress
servedPDPPDNAddress := ""
if v, ok := cdrJSON["servedPDPPDNAddress"]; ok && v != nil {
servedPDPPDNAddress = fmt.Sprint(v)
}
// servedPDPPDNAddress
servingNodeAddress := []string{}
if v, ok := cdrJSON["servingNodeAddress"]; ok && v != nil {
for _, v := range v.([]any) {
servingNodeAddress = append(servingNodeAddress, fmt.Sprint(v))
}
}
// servingNodeType
servingNodeType := []string{}
if v, ok := cdrJSON["servingNodeType"]; ok && v != nil {
for _, v := range v.([]any) {
if v, ok := v.(map[string]any)["servingNodeType"]; ok && v != nil {
servingNodeType = append(servingNodeType, fmt.Sprint(v))
}
}
}
// accessPointNameNI
accessPointNameNI := ""
if v, ok := cdrJSON["accessPointNameNI"]; ok && v != nil {
accessPointNameNI = fmt.Sprint(v)
}
// causeForRecClosing
causeForRecClosing := ""
if v, ok := cdrJSON["causeForRecClosing"]; ok && v != nil {
causeForRecClosing = fmt.Sprint(v)
}
// recordSequenceNumber
recordSequenceNumber := ""
if v, ok := cdrJSON["recordSequenceNumber"]; ok && v != nil {
recordSequenceNumber = fmt.Sprint(v)
}
// localRecordSequenceNumber
localRecordSequenceNumber := ""
if v, ok := cdrJSON["localRecordSequenceNumber"]; ok && v != nil {
localRecordSequenceNumber = fmt.Sprint(v)
}
// 数据量上行链路
var dataVolumeGPRSUplink int64 = 0
// 数据量下行链路
var dataVolumeGPRSDownlink int64 = 0
if v, ok := cdrJSON["listOfTrafficVolumes"]; ok && v != nil {
usageList := v.([]any)
if len(usageList) > 0 {
for _, used := range usageList {
usedUnit := used.(map[string]any)
if dup, dupOk := usedUnit["dataVolumeGPRSUplink"]; dupOk {
dataVolumeGPRSUplink = parse.Number(dup)
}
if ddown, ddownOk := usedUnit["dataVolumeGPRSDownlink"]; ddownOk {
dataVolumeGPRSDownlink = parse.Number(ddown)
}
}
}
}
// 时长
duration := "-"
if v, ok := cdrJSON["duration"]; ok && v != nil {
duration = fmt.Sprint(parse.Number(v))
}
// 调用时间
invocationTimestamp := ""
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
invocationTimestamp = v.(string)
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.ID,
"B" + idx: row.NeName,
"C" + idx: row.RmUID,
"D" + idx: chargingID,
"E" + idx: servedIMSI,
"F" + idx: servedMSISDN,
"G" + idx: dataVolumeGPRSUplink,
"H" + idx: dataVolumeGPRSDownlink,
"I" + idx: duration,
"J" + idx: invocationTimestamp,
"K" + idx: pGWAddressUsed,
"L" + idx: sGWAddress,
"M" + idx: rATType,
"N" + idx: pdpPDNType,
"O" + idx: servedPDPPDNAddress,
"P" + idx: strings.Join(servingNodeAddress, ","),
"Q" + idx: strings.Join(servingNodeType, ","),
"R" + idx: accessPointNameNI,
"S" + idx: causeForRecClosing,
"T" + idx: recordSequenceNumber,
"U" + idx: localRecordSequenceNumber,
})
}
// 导出数据表格
return file.WriteSheet(headerCells, dataCells, fileName, "")
}

View File

@@ -1,8 +1,13 @@
package service
import (
"encoding/json"
"fmt"
"strconv"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/file"
"be.ems/src/framework/utils/parse"
"be.ems/src/modules/network_data/model"
"be.ems/src/modules/network_data/repository"
)
@@ -37,3 +42,190 @@ func (r *CDREventSMF) DeleteByIds(cdrIds []string) (int64, error) {
// 删除信息失败!
return 0, fmt.Errorf("delete fail")
}
// ExportXlsx 导出数据到 xlsx 文件
func (r CDREventSMF) ExportXlsx(rows []model.CDREventSMF, fileName string) (string, error) {
// 第一行表头标题
headerCells := map[string]string{
"A1": "ID",
"B1": "Charging ID",
"C1": "NE Name",
"D1": "Resource Unique ID",
"E1": "Subscriber ID Data",
"F1": "Subscriber ID Type",
"G1": "Data Volume Uplink",
"H1": "Data Volume Downlink",
"I1": "Data Total Volume",
"J1": "Duration",
"K1": "Invocation Time",
"L1": "User Identifier",
"M1": "SSC Mode",
"N1": "DNN ID",
"O1": "PDU Type",
"P1": "RAT Type",
"Q1": "PDU IPv4 Address",
"R1": "Network Function IPv4",
"S1": "PDU IPv6 Address Swith Prefix",
"T1": "Record Network Function ID",
"U1": "Record Type",
"V1": "Record Opening Time",
}
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
for i, row := range rows {
idx := strconv.Itoa(i + 2)
// 解析 JSON 字符串为 map
var cdrJSON map[string]interface{}
err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON)
if err != nil {
logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
continue
}
// 计费ID
chargingID := ""
if v, ok := cdrJSON["chargingID"]; ok && v != nil {
chargingID = fmt.Sprint(parse.Number(v))
}
// 订阅 ID 类型
subscriptionIDType := "-"
// 订阅 ID 数据
subscriptionIDData := "-"
if v, ok := cdrJSON["subscriberIdentifier"]; ok && v != nil {
if sub, subOk := v.(map[string]any); subOk && sub != nil {
subscriptionIDType = sub["subscriptionIDType"].(string)
subscriptionIDData = sub["subscriptionIDData"].(string)
}
}
// 网络功能 IPv4 地址
networkFunctionIPv4Address := ""
if v, ok := cdrJSON["nFunctionConsumerInformation"]; ok && v != nil {
if conInfo, conInfoOk := v.(map[string]any); conInfoOk && conInfo != nil {
networkFunctionIPv4Address = conInfo["networkFunctionIPv4Address"].(string)
}
}
// 数据量上行链路
var dataVolumeUplink int64 = 0
// 数据量下行链路
var dataVolumeDownlink int64 = 0
// 数据总量
var dataTotalVolume int64 = 0
if v, ok := cdrJSON["listOfMultipleUnitUsage"]; ok && v != nil {
usageList := v.([]any)
if len(usageList) > 0 {
for _, used := range usageList {
usedUnit := used.(map[string]any)
usedUnitList := usedUnit["usedUnitContainer"].([]any)
if len(usedUnitList) > 0 {
for _, data := range usedUnitList {
udata := data.(map[string]any)
if dup, dupOk := udata["dataVolumeUplink"]; dupOk {
dataVolumeUplink += parse.Number(dup)
}
if ddown, ddownOk := udata["dataVolumeDownlink"]; ddownOk {
dataVolumeDownlink += parse.Number(ddown)
}
if dt, dtOk := udata["dataTotalVolume"]; dtOk {
dataTotalVolume += parse.Number(dt)
}
}
}
}
}
}
// 时长
duration := "-"
if v, ok := cdrJSON["duration"]; ok && v != nil {
duration = fmt.Sprint(parse.Number(v))
}
// 调用时间
invocationTimestamp := ""
if v, ok := cdrJSON["invocationTimestamp"]; ok && v != nil {
invocationTimestamp = v.(string)
}
// 记录打开时间
User_Identifier := ""
SSC_Mode := ""
RAT_Type := ""
DNN_ID := ""
PDU_Type := ""
PDU_IPv4 := ""
PDU_IPv6 := ""
if v, ok := cdrJSON["pDUSessionChargingInformation"]; ok && v != nil {
pduInfo := v.(map[string]any)
if v, ok := pduInfo["userIdentifier"]; ok && v != nil {
User_Identifier = v.(string)
}
if v, ok := pduInfo["sSCMode"]; ok && v != nil {
SSC_Mode = v.(string)
}
if v, ok := pduInfo["rATType"]; ok && v != nil {
RAT_Type = v.(string)
}
if v, ok := pduInfo["dNNID"]; ok && v != nil {
DNN_ID = v.(string)
}
if v, ok := pduInfo["pDUType"]; ok && v != nil {
PDU_Type = v.(string)
}
if v, ok := pduInfo["pDUAddress"]; ok && v != nil {
pDUAddress := v.(map[string]any)
if addr, ok := pDUAddress["pDUIPv4Address"]; ok && addr != nil {
PDU_IPv4 = addr.(string)
}
if addr, ok := pDUAddress["pDUIPv6AddresswithPrefix"]; ok && addr != nil {
PDU_IPv6 = addr.(string)
}
}
}
// 记录网络参数ID
recordNFID := ""
if v, ok := cdrJSON["recordingNetworkFunctionID"]; ok && v != nil {
recordNFID = v.(string)
}
//记录开始时间
recordOpeningTime := ""
if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
recordOpeningTime = v.(string)
}
//记录类型
recordType := ""
if v, ok := cdrJSON["recordType"]; ok && v != nil {
recordType = v.(string)
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.ID,
"B" + idx: chargingID,
"C" + idx: row.NeName,
"D" + idx: row.RmUID,
"E" + idx: subscriptionIDData,
"F" + idx: subscriptionIDType,
"G" + idx: dataVolumeUplink,
"H" + idx: dataVolumeDownlink,
"I" + idx: dataTotalVolume,
"J" + idx: duration,
"K" + idx: invocationTimestamp,
"L" + idx: User_Identifier,
"M" + idx: SSC_Mode,
"N" + idx: DNN_ID,
"O" + idx: PDU_Type,
"P" + idx: RAT_Type,
"Q" + idx: PDU_IPv4,
"R" + idx: networkFunctionIPv4Address,
"S" + idx: PDU_IPv6,
"T" + idx: recordNFID,
"U" + idx: recordType,
"V" + idx: recordOpeningTime,
})
}
// 导出数据表格
return file.WriteSheet(headerCells, dataCells, fileName, "")
}