Merge remote-tracking branch 'origin/main' into multi-tenant

This commit is contained in:
TsMask
2025-01-03 21:48:54 +08:00
37 changed files with 1268 additions and 347 deletions

View File

@@ -1,114 +1,144 @@
# 版本发布日志
## 2.2501.1-20250103
- 新增 菜单-基站状态页面路由,定义接口功能
- 更新 AMF/MME参数配置映射文件
- 修复 网元安装MME补充hss域名到hosts
## 2.2412.4-20241228
- 新增 菜单页面-SMF 用户使用数据流量报表
- 新增 CDR 删除权限标识 cdr:ne:remove
- 新增 初始自定义指标 title
- 新增 AMF 基站状态查询接口,更新 AMF 配置项 gnbList
- 修复 SMF-CDR/SGWC-CDR 导出表格流量进行累加不分组显示
- 修复 UDM 签约用户备注信息对应 IMSI 唯一
- 修复 omc 升级日志输出文件权限写入问题
- 修复 网元配置数据查询无 data 时默认返回空数组占位
- 优化 配置文件读取错误显示中文问题
- 优化 OMC 网元状态默认参数空时用“-”表示
- 优化 AMF-UE 上报数据格式统一结构UE 事件 AMF/MME 区分网元查询
## 2.2412.3-20241220
- 新增 直连网元请求带UA标识OMC/version
- 新增 网元直连接口补充AMF/SMF/MME/IMS
- 新增 CDR-SGWC表定义SGWC参数配置可选属性
- 新增 CDR接收SGWC并推送, 数据功能接口, 菜单命名SGWC-漫游数据
- 新增 直连网元请求带 UA 标识 OMC/version
- 新增 网元直连接口补充 AMF/SMF/MME/IMS
- 新增 CDR-SGWC 表定义SGWC 参数配置可选属性
- 新增 CDR 接收 SGWC 并推送, 数据功能接口, 菜单命名 SGWC-漫游数据
- 优化 网元配置可选参数接口
## 2.2412.2-20241213
- 新增 网元信息通过neType查询函数
- 新增 网元类型HLR跟踪查询类型HLR添加HLR KPI指标项数据
- 修复 网元安装redis依赖包bind0.0.0.0
- 修复 UDM签约cag参数允许为空
- 新增 网元信息通过 neType 查询函数
- 新增 网元类型 HLR 跟踪查询类型 HLR添加 HLR KPI 指标项数据
- 修复 网元安装 redis 依赖包 bind0.0.0.0
- 修复 UDM 签约 cag 参数允许为空
- 修复 custom indicator exist issue
## 2.2412.1-20241209
- 修复 GetHashBatch检查索引是否越界
- 修复 网元备份SMSC配置文件
- 修复 UDM签约批量添加msisdnstart_msisdn识别导致数据一致
- 修复 GetHashBatch 检查索引是否越界
- 修复 网元备份 SMSC 配置文件
- 修复 UDM 签约批量添加 msisdnstart_msisdn 识别导致数据一致
## 2.2411.4-20241130
- 新增 系统用户免登录认证默认为admin操作所有接口
- 新增 Para5G参数UPF新增填写N3 N6网卡名
- 新增 系统用户免登录认证,默认为 admin 操作所有接口
- 新增 Para5G 参数 UPF 新增填写 N3 N6 网卡名
## 2.2411.3-20241123
- 修复 SMSC安装host重复
- 修复 SMSC 安装 host 重复
- 修复 字典多语言翻译 Multi-language - Chinese
## 2.2411.2-20241115
- 新增 支持aarch64平台软件包iperf v2
- 新增 定时UDM数据加载每12小时一次
- 修复 网元软件包升级时rpm同版本号强制安装
- 更新 初始系统用户默认信息手机号长度32位系统菜单显示指标报表
- 新增 支持 aarch64 平台软件包 iperf v2
- 新增 定时 UDM 数据加载每 12 小时一次
- 修复 网元软件包升级时 rpm 同版本号强制安装
- 更新 初始系统用户默认信息,手机号长度 32 位,系统菜单显示指标报表
## 2.2411.1-20241108
- 新增 iperf支持v2的版本操作
- 新增 网元主机添加redis连接终端控制
- 更新 UDM用户数据表索引更新
- 更新 网元快速安装配置UPF网卡名和驱动类型参数
- 新增 iperf 支持 v2 的版本操作
- 新增 网元主机添加 redis 连接终端控制
- 更新 UDM 用户数据表索引更新
- 更新 网元快速安装配置 UPF 网卡名和驱动类型参数
## 2.2410.4-20241102
- 新增 直连网元信息取得hostname/os属性值
- 新增 UDM鉴权签约imsi多查询
- 新增 直连网元信息取得 hostname/os 属性值
- 新增 UDM 鉴权签约 imsi 多查询
- 更新 更新系统菜单新增关键指标概览
- 更新 定时任务周期同步更新UDM用户数据
- 更新 AMF/SMF参数配置项数据
- 修复 SMSC安装时关联修改IMSUDM配置
- 更新 定时任务周期同步更新 UDM 用户数据
- 更新 AMF/SMF 参数配置项数据
- 修复 SMSC 安装时关联修改 IMSUDM 配置
## 2.2410.3-20241018
多租户修改如下:
- 新增 网元主机支持 redis 配置项
- 新增 菜单功能 iperf3/ping 网络测试工具
- 更新 抓包文件支持查看内容
- 更新 初始网元相关表字段数据变更
- 更新 UDM 用户数据按查询条件导出
- ims在线用户显示异常
- admin和tenant角色只能单选
合并主线版本修改如下:
- 新增 系统菜单新增工具栏目,网元 SSH,网络测试,网络探针
- 更新 UDM 签约数据表,同步数据支持 MICO 和 RAT 操作修改
- 优化 MML 命令连接改为网元信息配置 telnet
- 更新 SMSC、AMF 参数配置数据
- 更新 定时清除到导出文件缓存
## 2.2409.4-20240927
- 新增 跟踪任务pcap文件获取接口
- 优化 socket消息接收跟踪任务推送ws
- 新增 跟踪任务 pcap 文件获取接口
- 优化 socket 消息接收,跟踪任务推送 ws
- 修复 历史告警同步判断存在错误
- 优化 redis数据scan数调整1000
- 修复 SMF在线订阅用户列表接口地址错误
- 修复 多语言SMSC原因0表示未知
- 优化 redis 数据 scan 数调整 1000
- 修复 SMF 在线订阅用户列表接口地址错误
- 修复 多语言 SMSC 原因 0 表示未知
- 新增 网元版本列表主动检查服务状态的版本
- 更新 UDM用户数据表字段
- 更新 UDM 用户数据表字段
## 2.2409.3-20240920
- 修复 字典多语言序号重复问题
- 更新 UDM用户数据表SMSC参数配置属性字典数据和跟踪相关表
- 新增 跟踪任务HLR免登录接口
- 新增 跟踪任务相关接口初始化跟踪任务新增非201/400时接收信息
- 修复 抓包文件下载zip时目录同名导致删除压缩无内容
- 更新 UDM 用户数据表SMSC 参数配置属性,字典数据和跟踪相关表
- 新增 跟踪任务 HLR 免登录接口
- 新增 跟踪任务相关接口初始化,跟踪任务新增非 201/400 时接收信息
- 修复 抓包文件下载 zip 时目录同名导致删除压缩无内容
--## 2.2409.1-20240909
- 新增 告警前转的两个接口email前转和短信前转的系统参数采用了和网元统一的参数配置方式
- 优化 修改了dpkgrpm包安装后的运行脚本支持通过环境变量传入参数并判断传入参数调用setomc.sh安装/升级数据库命令格式M_PARAM=upgrade C_PARAM=ba dpkg -I xxxx.deb如果不传入参数则和以前相同
- 调整的dpkgrpm包安装的运行脚本中停止omc服务的顺序解决了omc安装包在前端界面自升级时出现无法自动刷新的问题
- 新增 告警前转的两个接口 email 前转和短信前转的系统参数,采用了和网元统一的参数配置方式,
- 优化 修改了 dpkgrpm 包安装后的运行脚本,支持通过环境变量传入参数,并判断传入参数调用 setomc.sh 安装/升级数据库命令格式M_PARAM=upgrade C_PARAM=ba dpkg -I xxxx.deb如果不传入参数则和以前相同
- 调整的 dpkgrpm 包安装的运行脚本中停止 omc 服务的顺序,解决了 omc 安装包在前端界面自升级时出现无法自动刷新的问题
--## 2.2408.5-20240831
- 修复 系统信息读取磁盘获取超时导致返回空数组
- 优化 缓存信息安全清理排除登录用户身份和验证码信息
- 新增 KPI自定义指标功能接口
- 新增 KPI 自定义指标功能接口
- 新增 日志数据导出文件查看功能接口
--## 2.2408.4-20240823
- 优化 网元端文件目录/tmp/omc 上传push 下载pull
- 优化 网元端文件目录/tmp/omc 上传 push 下载 pull
- 新增 网元文件操作可删除本地临时文件
- 新增 系统菜单-信令抓包文件
- 新增 KPI添加CBC
- 更新 CBC参数配置可选属性
- 新增 KPI 添加 CBC
- 更新 CBC 参数配置可选属性
--## 2.2408.3-20240816
- 新增 中间件-接口加解密配合前端CryptoJS加解密
- 新增 KPI添加SMSC
- 更新 IMS参数配置可选属性
- 新增 中间件-接口加解密,配合前端 CryptoJS 加解密
- 新增 KPI 添加 SMSC
- 更新 IMS 参数配置可选属性
--## 2.2408.2-20240809

View File

@@ -1,7 +1,7 @@
# Makefile for rest agent project
PROJECT = OMC
VERSION = 2.2412.3
VERSION = 2.2501.1
PLATFORM = amd64
ARMPLATFORM = aarch64
BUILDDIR = ../../build

View File

@@ -504,3 +504,53 @@ amf:
filter: '{"0":"false","1":"true"}'
display: "statusReportEnabled"
comment: ""
gnbList:
display: "Gnb List Config"
sort: 13
array:
- name: "index"
type: "int"
value: "0"
access: "read-only"
filter: "0~128"
display: "Index"
comment: "0~128"
- name: "name"
type: "string"
value: "Gnb"
access: "read-write"
filter: "0~64"
display: "GNB Name"
comment: "text content length 0~64"
- name: "address"
type: "string"
value: "192.168.8.1"
access: "read-write"
filter: "0~64"
display: "GNB Address"
comment: "text content length 0~64"
- name: "position"
type: "string"
value: "Area-B"
access: "read-write"
filter: "0~64"
display: "Position"
comment: "location description. Prohibition of spaces, length of text content 0-64"
imeiWhitelist:
display: "IMEI White List"
sort: 15
array:
- name: "index"
type: "int"
value: "0"
access: "read-only"
filter: "0~65535"
display: "Index"
comment: "0~65535"
- name: "imeiPrefixValue"
type: "string"
value: ""
access: "read-write"
filter: "^[a-zA-Z0-9]{0,16}$"
display: "IMEI Prefix"
comment: ""

View File

@@ -17,6 +17,27 @@ mme:
filter: '{"0":"false","1":"true"}'
display: "VoLTE Enabled"
comment: "true|false"
- name: "meIdentityCheckPath"
type: "string"
value: "/usr/local/etc/mme/me_identity_check.csv"
access: "read-write"
filter: "0~128"
display: "ME IDENTITY CHECK PATH"
comment: "0~128"
- name: "imeiWhiteListPath"
type: "string"
value: "/usr/local/etc/mme/imei_whitelist.csv"
access: "read-write"
filter: "0~128"
display: "IMEI WHITE LIST PATH"
comment: "0~128"
- name: "dnsServerIp"
type: "string"
value: "127.0.0.53"
access: "read-write"
filter: "0~64"
display: "DNS SERVER IP"
comment: "0~64"
- name: "s1MmeIp"
type: "string"
value: "192.168.1.179"
@@ -80,13 +101,97 @@ mme:
filter: "0~100"
display: "S6A MME Identity"
comment: "0~100"
- name: "localIp"
- name: "s6aLocalIp"
type: "string"
value: "172.16.5.220"
access: "read-write"
filter: "0~20"
display: "S6A MME IP"
comment: "0~20"
- name: "slsLocalIp"
type: "string"
value: "172.16.5.220"
access: "read-write"
filter: "0~20"
display: "SLS MME IP"
comment: "0~20"
- name: "slsRemoteIp"
type: "string"
value: "172.16.5.220"
access: "read-write"
filter: "0~20"
display: "SLS REMOTE IP"
comment: "0~20"
- name: "slsRemotePort"
type: "string"
value: "9082"
access: "read-write"
filter: "0~20"
display: "SLS REMOTE PORT"
comment: "0~20"
- name: "slgIdentity"
type: "string"
value: "gmlc.epc.mnc001.mcc001.3gppnetwork.org"
access: "read-write"
filter: "0~100"
display: "SLG MME Identity"
comment: "0~100"
- name: "slgRealm"
type: "string"
value: "epc.mnc001.mcc001.3gppnetwork.org"
access: "read-write"
filter: "0~100"
display: "SLG MME REALM"
comment: "0~100"
- name: "sbcLocalIp"
type: "string"
value: "192.168.8.220"
access: "read-write"
filter: "0~20"
display: "SBC MME IP"
comment: "0~20"
- name: "svLocalIp"
type: "string"
value: "172.16.5.220"
access: "read-write"
filter: "0~20"
display: "SV MME IP"
comment: "0~20"
- name: "svLocalPort"
type: "string"
value: "9082"
access: "read-write"
filter: "0~20"
display: "SV MME PORT"
comment: "0~20"
- name: "svRemoteIp"
type: "string"
value: "172.16.5.220"
access: "read-write"
filter: "0~20"
display: "SV REMOTE IP"
comment: "0~20"
- name: "svRemotePort"
type: "string"
value: "9082"
access: "read-write"
filter: "0~20"
display: "SV REMOTE PORT"
comment: "0~20"
- name: "s3RemoteIp"
type: "string"
value: "172.16.5.220"
access: "read-write"
filter: "0~20"
display: "S3 REMOTE IP"
comment: "0~20"
- name: "s3RemotePort"
type: "string"
value: "9082"
access: "read-write"
filter: "0~20"
display: "S3 REMOTE PORT"
comment: "0~20"
gummei:
display: "Gummei List"
sort: 3
@@ -307,3 +412,46 @@ mme:
filter: "0~64"
display: "AMF IP"
comment: "0~64"
roam_plmn:
display: "ROAM PLMN List"
sort: 15
array:
- name: "index"
type: "int"
value: "0"
access: "read"
filter: "0~15"
display: "Index"
comment: "0~15"
- name: "mcc"
type: "string"
value: "001"
access: "read-write"
filter: "0~64"
display: "MCC"
comment: "0~64"
- name: "mnc"
type: "string"
value: "01"
access: "read-write"
filter: "0~64"
display: "MNC"
comment: "0~64"
white_list:
display: "WHITE LIST List"
sort: 15
array:
- name: "index"
type: "int"
value: "0"
access: "read"
filter: "0~15"
display: "Index"
comment: "0~15"
- name: "imei"
type: "string"
value: "001"
access: "read-write"
filter: "0~64"
display: "IMEI"
comment: "0~64"

View File

@@ -1,7 +1,7 @@
# Makefile for OMC-OMC-crontask project
PROJECT = OMC
VERSION = 2.2412.3
VERSION = 2.2501.1
LIBDIR = be.ems/lib
BINNAME = crontask

View File

@@ -1,7 +1,7 @@
# Makefile for rest agent project
PROJECT = OMC
VERSION = 2.2412.3
VERSION = 2.2501.1
RelDate = `date +%Y%m%d`
Release = $(RelDate)
RelVer = $(VERSION)-$(RelDate)

File diff suppressed because one or more lines are too long

View File

@@ -134,7 +134,7 @@ INSERT INTO `sys_dict_data` VALUES (1126, 1126, 'menu.dashboard.smscCDR.content'
INSERT INTO `sys_dict_data` VALUES (1127, 1127, 'menu.perf.thresholdRemark', '性能门限菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1128, 1128, 'menu.perf.kpiRemark', '黄金指标菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1129, 1129, 'menu.perf.customTargetRemark', '自定义指标菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (1130, 1130, 'menu.perf.setRemark', '性能通用设置菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1130, 1130, 'menu.dashboard.smfCDRByIMSI', '数据流量报表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1131, 1131, 'menu.mmlRemark', 'MML管理目录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1132, 1132, 'menu.mml.neRemark', '网元操作菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1133, 1133, 'menu.mml.udmRemark', '网元UDM用户数据菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
@@ -153,7 +153,7 @@ INSERT INTO `sys_dict_data` VALUES (1145, 1145, 'menu.system.systemSetRemark', '
INSERT INTO `sys_dict_data` VALUES (1146, 1146, 'menu.system.systemResourceRemark', '系统资源 cpu io network菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (1147, 1147, 'menu.config.configNEFormRemark', '参数配置Form菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (1148, 1148, 'menu.config.configNETreeRemark', '参数配置Tree菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (1149, 1149, 'menu.config.configNETreeTableRemark', '参数配置TreeTable菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1149, 1149, 'menu.neData.baseStation', '基站状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1150, 1150, 'menu.noData', '没有可访问菜单数据!', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1151, 1151, 'menu.errNameExists', '操作菜单【{name}】失败,菜单名称已存在', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1152, 1152, 'menu.errPathExists', '操作菜单【{name}】失败,菜单路由地址已存在', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);

View File

@@ -134,7 +134,7 @@ INSERT INTO `sys_dict_data` VALUES (3126, 3126, 'menu.dashboard.smscCDR.content'
INSERT INTO `sys_dict_data` VALUES (3127, 3127, 'menu.perf.thresholdRemark', 'Performance Threshold Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3128, 3128, 'menu.perf.kpiRemark', 'Key Performance Indicator Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3129, 3129, 'menu.perf.customTargetRemark', 'Custom Indicator Management Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (3130, 3130, 'menu.perf.setRemark', 'Performance General Settings Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3130, 3130, 'menu.dashboard.smfCDRByIMSI', 'Data Usage Report', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3131, 3131, 'menu.mmlRemark', 'MML Management Catalog', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3132, 3132, 'menu.mml.neRemark', 'Network Element Operations Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3133, 3133, 'menu.mml.udmRemark', 'Network Element UDM User Data Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
@@ -153,7 +153,7 @@ INSERT INTO `sys_dict_data` VALUES (3145, 3145, 'menu.system.systemSetRemark', '
INSERT INTO `sys_dict_data` VALUES (3146, 3146, 'menu.system.systemResourceRemark', 'System Resources cpu io network menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (3147, 3147, 'menu.config.configNEFormRemark', 'Parameter Configuration Form Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (3148, 3148, 'menu.config.configNETreeRemark', 'Parameter Configuration Tree Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (3149, 3149, 'menu.config.configNETreeTableRemark', 'Configuring the TreeTable menu with parameters', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3149, 3149, 'menu.neData.baseStation', 'Radio State', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3150, 3150, 'menu.noData', 'There is no accessible menu data!', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3151, 3151, 'menu.errNameExists', 'Failed to operate menu [{name}], menu name already exists!', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3152, 3152, 'menu.errPathExists', 'Failed to operate menu [{name}], menu routing address already exists!', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);

View File

@@ -146,6 +146,7 @@ INSERT INTO `sys_menu` VALUES (2091, 'menu.log.mml', 2089, 30, 'mml', 'logManage
INSERT INTO `sys_menu` VALUES (2092, 'menu.log.alarm', 2089, 40, 'alarm-log', 'logManage/alarm/index', '1', '0', 'M', '1', '1', 'logManage:alarm:index', 'icon-fuzhidaima', 'supervisor', 1700000000000, NULL, 0, 'menu.log.alarmRemark');
INSERT INTO `sys_menu` VALUES (2094, 'menu.log.forwarding', 2089, 41, 'forwarding', 'logManage/forwarding/index', '1', '0', 'M', '1', '1', 'logManage:forwarding:index', 'icon-huizhiguize', 'supervisor', 1700000000000, NULL, 0, 'menu.log.forwardingRemark');
INSERT INTO `sys_menu` VALUES (2095, 'menu.log.set', 2089, 45, 'logSet', 'logManage/logSet/index', '1', '0', 'M', '0', '0', 'logManage:logSet:index', 'icon-you', 'supervisor', 1700000000000, 'supervisor', 1715332370830, 'menu.log.setRemark');
INSERT INTO `sys_menu` VALUES (2096, 'menu.neData.baseStation', 5, 12, 'base-station', 'ne-data/base-station/index', '1', '0', 'M', '1', '1', 'ne-data:base-station:list', 'icon-fenxiang', 'supervisor', 1735634289850, '', 0, '');
INSERT INTO `sys_menu` VALUES (2097, 'menu.fault.history', 2129, 2, 'history-alarm', 'faultManage/history-alarm/index', '1', '1', 'M', '1', '1', 'faultManage/history-alarm/index', 'icon-huizhiguize', 'supervisor', 1700000000000, NULL, 0, 'menu.fault.historyRemark');
INSERT INTO `sys_menu` VALUES (2098, 'menu.fault.set', 2129, 100, 'fault-setting', 'faultManage/fault-setting/index', '1', '0', 'M', '0', '1', 'faultManage/fault-setting/index', 'icon-gonggaodayi', 'supervisor', 1700000000000, NULL, 0, 'menu.fault.setRemark');
INSERT INTO `sys_menu` VALUES (2099, 'menu.perf', 0, 5, 'perfManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.perfRemark');
@@ -167,7 +168,7 @@ INSERT INTO `sys_menu` VALUES (2114, 'menu.system.systemSet', 1, 60, 'setting',
INSERT INTO `sys_menu` VALUES (2115, 'menu.system.systemResource', 1, 6, 'monitor', 'monitor/monitor/index', '1', '1', 'M', '1', '1', 'monitor:monitor:info', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.system.systemResourceRemark');
INSERT INTO `sys_menu` VALUES (2116, 'menu.dashboard.smscCDR.content', 2157, 1, '', '', '1', '1', 'B', '1', '1', 'cdr:smsc:content', '#', 'supervisor', 1734936660956, '', 0, '');
INSERT INTO `sys_menu` VALUES (2117, 'menu.common.delete', 2140, 1, '', '', '1', '1', 'B', '1', '1', 'cdr:ne:remove', '#', 'supervisor', 1734936660956, '', 0, '');
-- INSERT INTO `sys_menu` VALUES (2118, 'menu.config.configNETreeTable', 4, 2, 'configNETreeTable', 'configManage/configParamTreeTable/index', '1', '1', 'M', '1', '0', 'configManage:configParam:index', 'icon-wofaqi', 'supervisor', 1700000000000, NULL, 0, 'menu.config.configNETreeTableRemark');
INSERT INTO `sys_menu` VALUES (2118, 'menu.dashboard.smfCDRByIMSI', 2140, 7, 'smfCDRByIMSI', 'dashboard/smfCDRByIMSI/index', '1', '0', 'M', '1', '1', 'dashboard:cdr:index', 'icon-gerenzhanghu', 'supervisor', 1735010792379, '', 0, '');
INSERT INTO `sys_menu` VALUES (2119, 'menu.ueUser.n3iwf', 5, 8, 'n3iwf', 'neUser/n3iwf/index', '1', '0', 'M', '0', '1', 'neUser:n3iwf:index', 'icon-paixu', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_menu` VALUES (2120, 'menu.ueUser.pcf', 5, 9, 'pcf', 'neUser/pcf/index', '1', '0', 'M', '1', '1', 'neUser:pcf:index', 'icon-paixu', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_menu` VALUES (2121, 'menu.system.user.editRole', 100, 8, NULL, NULL, '1', '1', 'B', '1', '1', 'system:user:editRole', '#', 'supervisor', 1700000000000, NULL, 0, NULL);

View File

@@ -1,18 +1,6 @@
/*
Navicat Premium Data Transfer
Source Server : local_mariadb
Source Server Type : MariaDB
Source Server Version : 100338 (10.3.38-MariaDB)
Source Host : localhost:33066
Source Schema : tenants_db
Target Server Type : MariaDB
Target Server Version : 100338 (10.3.38-MariaDB)
File Encoding : 65001
Date: 04/07/2024 10:15:55
*/
--
-- Table structure for table `ue_event`
--
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

View File

@@ -141,7 +141,7 @@ REPLACE INTO `sys_dict_data` VALUES (1126, 1126, 'menu.dashboard.smscCDR.content
REPLACE INTO `sys_dict_data` VALUES (1127, 1127, 'menu.perf.thresholdRemark', '性能门限菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1128, 1128, 'menu.perf.kpiRemark', '黄金指标菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1129, 1129, 'menu.perf.customTargetRemark', '自定义指标菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1130, 1130, 'menu.perf.setRemark', '性能通用设置菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1130, 1130, 'menu.dashboard.smfCDRByIMSI', '数据流量报表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1131, 1131, 'menu.mmlRemark', 'MML管理目录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1132, 1132, 'menu.mml.neRemark', '网元操作菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1133, 1133, 'menu.mml.udmRemark', '网元UDM用户数据菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
@@ -160,7 +160,7 @@ REPLACE INTO `sys_dict_data` VALUES (1145, 1145, 'menu.system.systemSetRemark',
REPLACE INTO `sys_dict_data` VALUES (1146, 1146, 'menu.system.systemResourceRemark', '系统资源 cpu io network菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (1147, 1147, 'menu.config.configNEFormRemark', '参数配置Form菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (1148, 1148, 'menu.config.configNETreeRemark', '参数配置Tree菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (1149, 1149, 'menu.config.configNETreeTableRemark', '参数配置TreeTable菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1149, 1149, 'menu.neData.baseStation', '基站状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1150, 1150, 'menu.noData', '没有可访问菜单数据!', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1151, 1151, 'menu.errNameExists', '操作菜单【{name}】失败,菜单名称已存在', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1152, 1152, 'menu.errPathExists', '操作菜单【{name}】失败,菜单路由地址已存在', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);

View File

@@ -139,7 +139,7 @@ REPLACE INTO `sys_dict_data` VALUES (3126, 3126, 'menu.dashboard.smscCDR.content
REPLACE INTO `sys_dict_data` VALUES (3127, 3127, 'menu.perf.thresholdRemark', 'Performance Threshold Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3128, 3128, 'menu.perf.kpiRemark', 'Key Performance Indicator Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3129, 3129, 'menu.perf.customTargetRemark', 'Custom Indicator Management Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (3130, 3130, 'menu.perf.setRemark', 'Performance General Settings Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3130, 3130, 'menu.dashboard.smfCDRByIMSI', 'Data Usage Report', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3131, 3131, 'menu.mmlRemark', 'MML Management Catalog', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3132, 3132, 'menu.mml.neRemark', 'Network Element Operations Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3133, 3133, 'menu.mml.udmRemark', 'Network Element UDM User Data Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
@@ -156,7 +156,7 @@ REPLACE INTO `sys_dict_data` VALUES (3143, 3143, 'log.operate.title.sgwcCDR', 'R
REPLACE INTO `sys_dict_data` VALUES (3144, 3144, 'menu.securityRemark', 'Security Management Catalog', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3145, 3145, 'menu.system.systemSetRemark', 'System Settings Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3146, 3146, 'menu.system.systemResourceRemark', 'System Resources cpu io network menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (3149, 3149, 'menu.config.configNETreeTableRemark', 'Configuring the TreeTable menu with parameters', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3149, 3149, 'menu.neData.baseStation', 'Radio State', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3150, 3150, 'menu.noData', 'There is no accessible menu data!', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3151, 3151, 'menu.errNameExists', 'Failed to operate menu [{name}], menu name already exists!', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3152, 3152, 'menu.errPathExists', 'Failed to operate menu [{name}], menu routing address already exists!', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);

View File

@@ -129,6 +129,7 @@ REPLACE INTO `sys_menu` VALUES (2091, 'menu.log.mml', 2089, 30, 'mml', 'logManag
REPLACE INTO `sys_menu` VALUES (2092, 'menu.log.alarm', 2089, 40, 'alarm-log', 'logManage/alarm/index', '1', '0', 'M', '1', '1', 'logManage:alarm:index', 'icon-fuzhidaima', 'supervisor', 1700000000000, NULL, 0, 'menu.log.alarmRemark');
REPLACE INTO `sys_menu` VALUES (2094, 'menu.log.forwarding', 2089, 41, 'forwarding', 'logManage/forwarding/index', '1', '0', 'M', '1', '1', 'logManage:forwarding:index', 'icon-huizhiguize', 'supervisor', 1700000000000, NULL, 0, 'menu.log.forwardingRemark');
REPLACE INTO `sys_menu` VALUES (2095, 'menu.log.set', 2089, 45, 'logSet', 'logManage/logSet/index', '1', '0', 'M', '0', '0', 'logManage:logSet:index', 'icon-you', 'supervisor', 1700000000000, 'supervisor', 1715332370830, 'menu.log.setRemark');
REPLACE INTO `sys_menu` VALUES (2096, 'menu.neData.baseStation', 5, 12, 'base-station', 'ne-data/base-station/index', '1', '0', 'M', '1', '1', 'ne-data:base-station:list', 'icon-fenxiang', 'supervisor', 1735634289850, '', 0, '');
REPLACE INTO `sys_menu` VALUES (2097, 'menu.fault.history', 2129, 2, 'history-alarm', 'faultManage/history-alarm/index', '1', '1', 'M', '1', '1', 'faultManage/history-alarm/index', 'icon-huizhiguize', 'supervisor', 1700000000000, NULL, 0, 'menu.fault.historyRemark');
REPLACE INTO `sys_menu` VALUES (2098, 'menu.fault.set', 2129, 100, 'fault-setting', 'faultManage/fault-setting/index', '1', '0', 'M', '0', '1', 'faultManage/fault-setting/index', 'icon-gonggaodayi', 'supervisor', 1700000000000, NULL, 0, 'menu.fault.setRemark');
REPLACE INTO `sys_menu` VALUES (2099, 'menu.perf', 0, 5, 'perfManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.perfRemark');
@@ -150,7 +151,7 @@ REPLACE INTO `sys_menu` VALUES (2114, 'menu.system.systemSet', 1, 60, 'setting',
REPLACE INTO `sys_menu` VALUES (2115, 'menu.system.systemResource', 1, 6, 'monitor', 'monitor/monitor/index', '1', '1', 'M', '1', '1', 'monitor:monitor:info', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.system.systemResourceRemark');
REPLACE INTO `sys_menu` VALUES (2116, 'menu.dashboard.smscCDR.content', 2157, 1, '', '', '1', '1', 'B', '1', '1', 'cdr:smsc:content', '#', 'supervisor', 1734936660956, '', 0, '');
REPLACE INTO `sys_menu` VALUES (2117, 'menu.common.delete', 2140, 1, '', '', '1', '1', 'B', '1', '1', 'cdr:ne:remove', '#', 'supervisor', 1734936660956, '', 0, '');
-- REPLACE INTO `sys_menu` VALUES (2118, 'menu.config.configNETreeTable', 4, 2, 'configNETreeTable', 'configManage/configParamTreeTable/index', '1', '1', 'M', '1', '0', 'configManage:configParam:index', 'icon-wofaqi', 'supervisor', 1700000000000, NULL, 0, 'menu.config.configNETreeTableRemark');
REPLACE INTO `sys_menu` VALUES (2118, 'menu.dashboard.smfCDRByIMSI', 2140, 7, 'smfCDRByIMSI', 'dashboard/smfCDRByIMSI/index', '1', '0', 'M', '1', '1', 'dashboard:cdr:index', 'icon-gerenzhanghu', 'supervisor', 1735010792379, '', 0, '');
REPLACE INTO `sys_menu` VALUES (2119, 'menu.ueUser.n3iwf', 5, 8, 'n3iwf', 'neUser/n3iwf/index', '1', '0', 'M', '0', '1', 'neUser:n3iwf:index', 'icon-paixu', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_menu` VALUES (2120, 'menu.ueUser.pcf', 5, 9, 'pcf', 'neUser/pcf/index', '1', '0', 'M', '1', '1', 'neUser:pcf:index', 'icon-paixu', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_menu` VALUES (2121, 'menu.system.user.editRole', 100, 8, NULL, NULL, '1', '1', 'B', '1', '1', 'system:user:editRole', '#', 'supervisor', 1700000000000, NULL, 0, NULL);

View File

@@ -1,19 +1,3 @@
/*
Navicat Premium Data Transfer
Source Server : local_mariadb
Source Server Type : MariaDB
Source Server Version : 100338 (10.3.38-MariaDB)
Source Host : localhost:33066
Source Schema : tenants_db
Target Server Type : MariaDB
Target Server Version : 100338 (10.3.38-MariaDB)
File Encoding : 65001
Date: 04/07/2024 10:15:55
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

View File

@@ -1,25 +1,10 @@
/*
Navicat Premium Data Transfer
Source Server : local_mariadb
Source Server Type : MariaDB
Source Server Version : 100338 (10.3.38-MariaDB)
Source Host : localhost:33066
Source Schema : tenants_db
Target Server Type : MariaDB
Target Server Version : 100338 (10.3.38-MariaDB)
File Encoding : 65001
Date: 04/07/2024 10:41:59
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for ue_event_amf
-- ----------------------------
DROP TABLE IF EXISTS `ue_event_amf`;
CREATE TABLE IF NOT EXISTS `ue_event_amf` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ne_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

View File

@@ -1,25 +1,10 @@
/*
Navicat Premium Data Transfer
Source Server : local_mariadb
Source Server Type : MariaDB
Source Server Version : 100338 (10.3.38-MariaDB)
Source Host : localhost:33066
Source Schema : tenants_db
Target Server Type : MariaDB
Target Server Version : 100338 (10.3.38-MariaDB)
File Encoding : 65001
Date: 04/07/2024 10:16:18
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for ue_event_mme
-- ----------------------------
DROP TABLE IF EXISTS `ue_event_mme`;
CREATE TABLE IF NOT EXISTS `ue_event_mme` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ne_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,

View File

@@ -1,19 +1,17 @@
package event
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"time"
"be.ems/lib/core/ctx"
"be.ems/lib/dborm"
"be.ems/lib/global"
"be.ems/lib/log"
"be.ems/lib/services"
"be.ems/restagent/config"
"be.ems/src/framework/utils/parse"
neService "be.ems/src/modules/network_element/service"
wsService "be.ems/src/modules/ws/service"
"github.com/gin-gonic/gin"
@@ -37,34 +35,100 @@ type UEEvent struct {
TenantID string `json:"tenantID" xorm:"tenant_id"`
}
// 旧AMF上报处理
func PostUEEventFromAMF(c *gin.Context) {
log.Info("PostUEEventFromAMF processing... ")
body, err := io.ReadAll(io.LimitReader(c.Request.Body, global.RequestBodyMaxLen))
if err != nil {
log.Error("Failed to io.ReadAll: ", err)
services.ResponseNotFound404UriNotExist(c.Writer, c.Request)
return
}
//vars := mux.Vars(c.Request)
eventType, ok := c.Params.Get("eventType")
if !ok || eventType == "" {
log.Error("eventType is empty")
services.ResponseNotFound404UriNotExist(c.Writer, c.Request)
return
}
ueEvent := new(UEEvent)
err = json.Unmarshal(body, &ueEvent.EventJson)
if err != nil {
var body map[string]any
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
log.Error("Failed to Unmarshal ueEvent:", err)
services.ResponseInternalServerError500ProcessError(c.Writer, err)
return
}
ueEvent.NeType = "AMF"
ueEvent.Timestamp = time.Now().Unix()
ueEvent.EventType = eventType
log.Trace("ueEvent AMF:", ueEvent)
ueEvent := UEEvent{
NeType: "AMF",
Timestamp: time.Now().Unix(),
EventType: eventType,
}
// 从eventJson中获取rmUID
if v, ok := body["rmUID"]; ok {
ueEvent.RmUID = fmt.Sprint(v)
} else {
ueEvent.RmUID = "4400HXAMF001"
}
if v, ok := body["neName"]; ok {
ueEvent.NeName = fmt.Sprint(v)
} else {
ueEvent.NeName = "AMF_001"
}
// 统一格式
eventJson := map[string]any{"cellID": 0, "gNBID": "", "imsi": "", "onlineNumber": 0, "result": "", "tacID": 0, "timestamp": 0, "time": 0, "type": eventType}
switch eventType {
case "auth-result":
// {"authCode":"200","authMessage":"成功","authTime":"2024-12-07 16:48:37","cellID":"3","gNBID":"1","imsi":"460002082100000","onlineNumber":1,"tacID":"81"}
if v, ok := body["imsi"]; ok {
eventJson["imsi"] = fmt.Sprint(v)
}
if v, ok := body["cellID"]; ok {
eventJson["cellID"] = fmt.Sprint(v)
}
if v, ok := body["gNBID"]; ok {
eventJson["gNBID"] = fmt.Sprint(v)
}
if v, ok := body["tacID"]; ok {
eventJson["tacID"] = fmt.Sprint(v)
}
if v, ok := body["onlineNumber"]; ok {
eventJson["onlineNumber"] = parse.Number(v)
}
if v, ok := body["authCode"]; ok {
eventJson["result"] = fmt.Sprint(v)
}
if v, ok := body["authTime"]; ok {
eventJson["timestamp"] = ueEvent.Timestamp
eventJson["time"] = fmt.Sprint(v)
}
case "detach":
// {"detachResult":0,"detachTime":"2024-12-07 18:00:47","imsi":"460002082100000"}
if v, ok := body["imsi"]; ok {
eventJson["imsi"] = fmt.Sprint(v)
}
if v, ok := body["detachResult"]; ok {
if fmt.Sprint(v) == "0" {
eventJson["result"] = "200"
} else {
eventJson["result"] = "500"
}
}
if v, ok := body["detachTime"]; ok {
eventJson["timestamp"] = ueEvent.Timestamp
eventJson["time"] = fmt.Sprint(v)
}
case "cm-state":
// {"changeTime":"2024-12-07 17:07:52","imsi":"460002082100000","onlineNumber":1,"status":2}
if v, ok := body["imsi"]; ok {
eventJson["imsi"] = fmt.Sprint(v)
}
if v, ok := body["onlineNumber"]; ok {
eventJson["onlineNumber"] = parse.Number(v)
}
if v, ok := body["status"]; ok {
eventJson["result"] = fmt.Sprint(v)
}
if v, ok := body["changeTime"]; ok {
eventJson["timestamp"] = ueEvent.Timestamp
eventJson["time"] = fmt.Sprint(v)
}
}
ueEvent.EventJson = eventJson
// for multi-tenancy
where := fmt.Sprintf("status='1' and tenancy_type='IMSI' and '%v' like tenancy_key", ueEvent.EventJson["imsi"])
@@ -83,13 +147,20 @@ func PostUEEventFromAMF(c *gin.Context) {
return
}
// AMF没有RmUID直接推送
// 推送到ws订阅组
wsService.NewWSSend.ByGroupID(wsService.GROUP_AMF_UE, ueEvent)
// 发送到匹配的网元
neInfo := neService.NewNeInfo.SelectNeInfoByRmuid(ueEvent.RmUID)
if neInfo.RmUID == ueEvent.RmUID {
// 推送到ws订阅组
if ueEvent.NeType == "AMF" {
wsService.NewWSSend.ByGroupID(wsService.GROUP_AMF_UE, ueEvent)
wsService.NewWSSend.ByGroupID(wsService.GROUP_AMF_UE+"_"+neInfo.NeId, ueEvent)
}
}
services.ResponseStatusOK204NoContent(c.Writer)
}
// UE上报处理
func PostUEEvent(w http.ResponseWriter, r *http.Request) {
log.Info("PostUEEvent processing... ")
@@ -124,7 +195,12 @@ func PostUEEvent(w http.ResponseWriter, r *http.Request) {
if neInfo.RmUID == ueEvent.RmUID {
// 推送到ws订阅组
if ueEvent.NeType == "MME" {
wsService.NewWSSend.ByGroupID(wsService.GROUP_MME_UE+neInfo.NeId, ueEvent)
wsService.NewWSSend.ByGroupID(wsService.GROUP_MME_UE, ueEvent)
wsService.NewWSSend.ByGroupID(wsService.GROUP_MME_UE+"_"+neInfo.NeId, ueEvent)
}
if ueEvent.NeType == "AMF" {
wsService.NewWSSend.ByGroupID(wsService.GROUP_AMF_UE, ueEvent)
wsService.NewWSSend.ByGroupID(wsService.GROUP_AMF_UE+"_"+neInfo.NeId, ueEvent)
}
}

View File

@@ -3,7 +3,7 @@
ProjectL = omc
ProjectU = OMC
PROJECT = $(ProjectL)
VERSION = 2.2412.3
VERSION = 2.2501.1
RelDate = `date +%Y%m%d`
Release = $(RelDate)
RelVer = $(VERSION)-$(RelDate)

View File

@@ -2,7 +2,7 @@
ProcList="restagent crontask sshsvc captrace data2html"
ProjectL=omc
VERSION=2.2412.3
VERSION=2.2501.1
RelDate=`date +%Y%m%d`
Release=${RelDate}
RelVer=${VERSION}-${RelDate}

View File

@@ -1,7 +1,7 @@
# Makefile for rest agent project
PROJECT = OMC
VERSION = 2.2412.3
VERSION = 2.2501.1
PLATFORM = amd64
ARMPLATFORM = aarch64
BUILDDIR = ../../build

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

@@ -136,6 +136,10 @@ func Setup(router *gin.Engine) {
middleware.PreAuthorize(nil),
controller.NewAMF.NbInfoList,
)
amfGroup.GET("/nb/list-cfg",
middleware.PreAuthorize(nil),
controller.NewAMF.NbStateList,
)
}
// 网元UPF

View File

@@ -1,10 +1,18 @@
package service
import (
"encoding/json"
"fmt"
"strconv"
"be.ems/src/framework/i18n"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"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"
sysService "be.ems/src/modules/system/service"
)
// 实例化数据层 CDREventIMS 结构体
@@ -42,3 +50,100 @@ func (r *CDREventIMS) DeleteByIds(cdrIds []string) (int64, error) {
// 删除信息失败!
return 0, fmt.Errorf("delete fail")
}
// ExportXlsx 导出数据到 xlsx 文件
func (r CDREventIMS) ExportXlsx(rows []model.CDREventIMS, fileName, language string) (string, error) {
// 第一行表头标题
headerCells := map[string]string{
"A1": "ID",
"B1": "Record Behavior",
"C1": "Type",
"D1": "Caller",
"E1": "Called",
"F1": "Duration",
"G1": "Result",
"H1": "Time",
}
// 读取字典数据 CDR SIP响应代码类别类型
dictCDRSipCode := sysService.NewSysDictData.SelectDictDataByType("cdr_sip_code")
// 读取字典数据 CDR 呼叫类型
dictCDRCallType := sysService.NewSysDictData.SelectDictDataByType("cdr_call_type")
// 从第二行开始的数据
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
}
// 记录类型
recordType := ""
if v, ok := cdrJSON["recordType"]; ok && v != nil {
recordType = v.(string)
}
// 呼叫类型
callType := "sms"
callTypeLable := "SMS"
if v, ok := cdrJSON["callType"]; ok && v != nil {
callType = v.(string)
for _, v := range dictCDRCallType {
if callType == v.DictValue {
callTypeLable = i18n.TKey(language, v.DictLabel)
break
}
}
}
// 被叫
called := ""
if v, ok := cdrJSON["calledParty"]; ok && v != nil {
called = v.(string)
}
// 主叫
caller := ""
if v, ok := cdrJSON["callerParty"]; ok && v != nil {
caller = v.(string)
}
// 时长
duration := "-"
if v, ok := cdrJSON["callDuration"]; ok && v != nil && callType != "sms" {
duration = fmt.Sprint(parse.Number(v))
}
// 呼叫结果 非短信都有code作为结果 sms短信都ok
callResult := "Success"
if v, ok := cdrJSON["cause"]; ok && v != nil && callType != "sms" {
cause := fmt.Sprint(v)
for _, v := range dictCDRSipCode {
if cause == v.DictValue {
callResult = i18n.TKey(language, v.DictLabel)
break
}
}
}
// 取时间
timeStr := ""
if v, ok := cdrJSON["releaseTime"]; ok && v != nil {
if releaseTime := parse.Number(v); releaseTime > 0 {
timeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ)
} else {
timeStr = v.(string)
}
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.ID,
"B" + idx: recordType,
"C" + idx: callTypeLable,
"D" + idx: caller,
"E" + idx: called,
"F" + idx: duration,
"G" + idx: callResult,
"H" + idx: timeStr,
})
}
// 导出数据表格
return file.WriteSheet(headerCells, dataCells, fileName, "")
}

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"
)
@@ -42,3 +47,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, "")
}

View File

@@ -1,10 +1,18 @@
package service
import (
"encoding/json"
"fmt"
"strconv"
"be.ems/src/framework/i18n"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"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"
sysService "be.ems/src/modules/system/service"
)
// 实例化数据层 CDREventSMSC 结构体
@@ -42,3 +50,91 @@ func (r *CDREventSMSC) DeleteByIds(cdrIds []string) (int64, error) {
// 删除信息失败!
return 0, fmt.Errorf("delete fail")
}
// ExportXlsx 导出数据到 xlsx 文件
func (r CDREventSMSC) ExportXlsx(rows []model.CDREventSMSC, fileName, language string) (string, error) {
// 第一行表头标题
headerCells := map[string]string{
"A1": "ID",
"B1": "Record Behavior",
"C1": "Service Type",
"D1": "Caller",
"E1": "Called",
"F1": "Result",
"G1": "Time",
}
// 读取字典数据 CDR 原因码
dictCDRCauseCode := sysService.NewSysDictData.SelectDictDataByType("cdr_cause_code")
// 从第二行开始的数据
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
}
// 记录类型
recordType := ""
if v, ok := cdrJSON["recordType"]; ok && v != nil {
recordType = v.(string)
}
// 服务类型
serviceType := ""
if v, ok := cdrJSON["serviceType"]; ok && v != nil {
serviceType = v.(string)
}
// 被叫
called := ""
if v, ok := cdrJSON["calledParty"]; ok && v != nil {
called = v.(string)
}
// 主叫
caller := ""
if v, ok := cdrJSON["callerParty"]; ok && v != nil {
caller = v.(string)
}
// 呼叫结果 0失败1成功
callResult := "Fail"
if v, ok := cdrJSON["result"]; ok && v != nil {
resultVal := parse.Number(v)
if resultVal == 1 {
callResult = "Success"
}
}
// 结果原因
if v, ok := cdrJSON["cause"]; ok && v != nil && callResult == "Fail" {
cause := fmt.Sprint(v)
for _, v := range dictCDRCauseCode {
if cause == v.DictValue {
callResult = fmt.Sprintf("%s, %s", callResult, i18n.TKey(language, v.DictLabel))
break
}
}
}
// 取时间
timeStr := ""
if v, ok := cdrJSON["updateTime"]; ok && v != nil {
if releaseTime := parse.Number(v); releaseTime > 0 {
timeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ)
} else {
timeStr = v.(string)
}
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.ID,
"B" + idx: recordType,
"C" + idx: serviceType,
"D" + idx: caller,
"E" + idx: called,
"F" + idx: callResult,
"G" + idx: timeStr,
})
}
// 导出数据表格
return file.WriteSheet(headerCells, dataCells, fileName, "")
}

View File

@@ -1,10 +1,16 @@
package service
import (
"encoding/json"
"fmt"
"strconv"
"be.ems/src/framework/i18n"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/file"
"be.ems/src/modules/network_data/model"
"be.ems/src/modules/network_data/repository"
sysService "be.ems/src/modules/system/service"
)
// 实例化数据层 UEEventAMF 结构体
@@ -14,8 +20,7 @@ var NewUEEventAMF = &UEEventAMF{
// UEEventAMF UE会话事件AMF 服务层处理
type UEEventAMF struct {
// UE会话事件数据信息
ueEventRepository *repository.UEEventAMF
ueEventRepository *repository.UEEventAMF // UE会话事件数据信息
}
// SelectPage 根据条件分页查询
@@ -43,3 +48,96 @@ func (r *UEEventAMF) DeleteByIds(ueIds []string) (int64, error) {
// 删除信息失败!
return 0, fmt.Errorf("delete fail")
}
// ExportXlsx 导出数据到 xlsx 文件
func (r UEEventAMF) ExportXlsx(rows []model.UEEventAMF, fileName, language string) (string, error) {
// 第一行表头标题
headerCells := map[string]string{
"A1": "ID",
"B1": "IMSI",
"C1": "Event Type",
"D1": "Result",
"E1": "Time",
}
// 读取字典数据 UE 事件类型
dictUEEventType := sysService.NewSysDictData.SelectDictDataByType("ue_event_type")
// 读取字典数据 UE 事件认证代码类型
dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code")
// 读取字典数据 UE 事件CM状态
dictUEEventCmState := sysService.NewSysDictData.SelectDictDataByType("ue_event_cm_state")
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
for i, row := range rows {
idx := strconv.Itoa(i + 2)
// 解析 JSON 字符串为 map
var eventJSON map[string]interface{}
err := json.Unmarshal([]byte(row.EventJSONStr), &eventJSON)
if err != nil {
logger.Warnf("UEExport Error parsing JSON: %s", err.Error())
continue
}
// 取IMSI
imsi := ""
if v, ok := eventJSON["imsi"]; ok && v != nil {
imsi = v.(string)
}
// 取类型
eventType := ""
for _, v := range dictUEEventType {
if row.EventType == v.DictValue {
eventType = i18n.TKey(language, v.DictLabel)
break
}
}
// 取结果
eventResult := ""
// 取时间
timeStr := ""
if row.EventType == "auth-result" {
if v, ok := eventJSON["authTime"]; ok && v != nil {
timeStr = v.(string)
}
if v, ok := eventJSON["authCode"]; ok && v != nil {
eventResult = v.(string)
for _, v := range dictUEAauthCode {
if eventResult == v.DictValue {
eventResult = i18n.TKey(language, v.DictLabel)
break
}
}
}
}
if row.EventType == "detach" {
if v, ok := eventJSON["detachTime"]; ok && v != nil {
timeStr = v.(string)
}
eventResult = "Success"
}
if row.EventType == "cm-state" {
if v, ok := eventJSON["changeTime"]; ok && v != nil {
timeStr = v.(string)
}
if v, ok := eventJSON["status"]; ok && v != nil {
eventResult = fmt.Sprint(v)
for _, v := range dictUEEventCmState {
if eventResult == v.DictValue {
eventResult = i18n.TKey(language, v.DictLabel)
break
}
}
}
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.ID,
"B" + idx: imsi,
"C" + idx: eventType,
"D" + idx: eventResult,
"E" + idx: timeStr,
})
}
// 导出数据表格
return file.WriteSheet(headerCells, dataCells, fileName, "")
}

View File

@@ -1,10 +1,18 @@
package service
import (
"encoding/json"
"fmt"
"strconv"
"be.ems/src/framework/i18n"
"be.ems/src/framework/logger"
"be.ems/src/framework/utils/date"
"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"
sysService "be.ems/src/modules/system/service"
)
// 实例化数据层 UEEventMME 结构体
@@ -42,3 +50,86 @@ func (r *UEEventMME) DeleteByIds(ueIds []string) (int64, error) {
// 删除信息失败!
return 0, fmt.Errorf("delete fail")
}
// ExportXlsx 导出数据到 xlsx 文件
func (r UEEventMME) ExportXlsx(rows []model.UEEventMME, fileName, language string) (string, error) {
// 第一行表头标题
headerCells := map[string]string{
"A1": "ID",
"B1": "IMSI",
"C1": "Event Type",
"D1": "Result",
"E1": "Time",
}
// 读取字典数据 UE 事件类型
dictUEEventType := sysService.NewSysDictData.SelectDictDataByType("ue_event_type")
// 读取字典数据 UE 事件认证代码类型
dictUEAauthCode := sysService.NewSysDictData.SelectDictDataByType("ue_auth_code")
// 读取字典数据 UE 事件CM状态
dictUEEventCmState := sysService.NewSysDictData.SelectDictDataByType("ue_event_cm_state")
// 从第二行开始的数据
dataCells := make([]map[string]any, 0)
for i, row := range rows {
idx := strconv.Itoa(i + 2)
// 解析 JSON 字符串为 map
var eventJSON map[string]interface{}
err := json.Unmarshal([]byte(row.EventJSONStr), &eventJSON)
if err != nil {
logger.Warnf("UEExport Error parsing JSON: %s", err.Error())
continue
}
// 取IMSI
imsi := ""
if v, ok := eventJSON["imsi"]; ok && v != nil {
imsi = v.(string)
}
// 取类型
eventType := row.EventType
for _, v := range dictUEEventType {
if row.EventType == v.DictValue {
eventType = i18n.TKey(language, v.DictLabel)
break
}
}
// 取结果
eventResult := ""
if v, ok := eventJSON["result"]; ok && v != nil {
eventResult = v.(string)
if row.EventType == "auth-result" {
for _, v := range dictUEAauthCode {
if eventResult == v.DictValue {
eventResult = i18n.TKey(language, v.DictLabel)
break
}
}
}
if row.EventType == "cm-state" {
for _, v := range dictUEEventCmState {
if eventResult == v.DictValue {
eventResult = i18n.TKey(language, v.DictLabel)
break
}
}
}
}
// 取时间
timeStr := ""
if v, ok := eventJSON["timestamp"]; ok && v != nil {
rowTime := parse.Number(v)
timeStr = date.ParseDateToStr(rowTime, date.YYYY_MM_DDTHH_MM_SSZ)
}
dataCells = append(dataCells, map[string]any{
"A" + idx: row.ID,
"B" + idx: imsi,
"C" + idx: eventType,
"D" + idx: eventResult,
"E" + idx: timeStr,
})
}
// 导出数据表格
return file.WriteSheet(headerCells, dataCells, fileName, "")
}

View File

@@ -12,14 +12,14 @@ import (
// AMFNbInfoList AMF基站信息
//
// 查询参数 {"nbId":"7"}
// 查询参数 {"id":"7"}
//
// 返回结果 []
func AMFNbInfoList(neInfo model.NeInfo, data map[string]string) ([]map[string]any, error) {
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/amf/objectType/nbInfo", neInfo.IP, neInfo.Port)
// 查询参数拼接
query := []string{}
if v, ok := data["nbId"]; ok && v != "" {
if v, ok := data["id"]; ok && v != "" {
query = append(query, fmt.Sprintf("nbId=%s", v))
}
if len(query) > 0 {
@@ -44,7 +44,47 @@ func AMFNbInfoList(neInfo model.NeInfo, data map[string]string) ([]map[string]an
// 固定返回字段,方便前端解析
if v, ok := resData["data"]; ok && v != nil {
return v.([]map[string]any), nil
if arr := v.([]any); len(arr) > 0 {
result := make([]map[string]any, len(arr))
for i, item := range arr {
result[i] = item.(map[string]any)
}
return result, nil
}
}
return []map[string]any{}, nil
}
// AMFGnbStateList AMF基站状态信息对比配置项gnbList
//
// 返回结果 []
func AMFGnbStateList(neInfo model.NeInfo) ([]map[string]any, error) {
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/amf/objectType/nbState", neInfo.IP, neInfo.Port)
resBytes, err := fetch.Get(neUrl, nil, 60_000)
if err != nil {
errStr := err.Error()
logger.Warnf("AMFNbInfoList Get \"%s\"", neUrl)
logger.Errorf("AMFNbInfoList %s", errStr)
return nil, fmt.Errorf("NeService AMF API Error")
}
// 序列化结果 {"data":[{"name": "Gnb","address": "192.168.8.1","state": "INACTIVE"}]}
var resData map[string]any
err = json.Unmarshal(resBytes, &resData)
if err != nil {
logger.Errorf("AMFNbInfoList Unmarshal %s", err.Error())
return nil, err
}
// 固定返回字段,方便前端解析
if v, ok := resData["data"]; ok && v != nil {
if arr := v.([]any); len(arr) > 0 {
result := make([]map[string]any, len(arr))
for i, item := range arr {
result[i] = item.(map[string]any)
}
return result, nil
}
}
return []map[string]any{}, nil
}

View File

@@ -88,7 +88,13 @@ func IMSUeSessionList(neInfo model.NeInfo, data map[string]string) ([]map[string
// 固定返回字段,方便前端解析
if v, ok := resData["data"]; ok && v != nil {
return v.([]map[string]any), nil
if arr := v.([]any); len(arr) > 0 {
result := make([]map[string]any, len(arr))
for i, item := range arr {
result[i] = item.(map[string]any)
}
return result, nil
}
}
return []map[string]any{}, nil
}

View File

@@ -12,14 +12,14 @@ import (
// MMENbInfoList AMF基站信息
//
// 查询参数 {"nbId":"7"}
// 查询参数 {"id":"7"}
//
// 返回结果 []
func MMENbInfoList(neInfo model.NeInfo, data map[string]string) ([]map[string]any, error) {
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/mme/objectType/nbInfo", neInfo.IP, neInfo.Port)
// 查询参数拼接
query := []string{}
if v, ok := data["nbId"]; ok && v != "" {
if v, ok := data["id"]; ok && v != "" {
query = append(query, fmt.Sprintf("nbId=%s", v))
}
if len(query) > 0 {
@@ -44,7 +44,13 @@ func MMENbInfoList(neInfo model.NeInfo, data map[string]string) ([]map[string]an
// 固定返回字段,方便前端解析
if v, ok := resData["data"]; ok && v != nil {
return v.([]map[string]any), nil
if arr := v.([]any); len(arr) > 0 {
result := make([]map[string]any, len(arr))
for i, item := range arr {
result[i] = item.(map[string]any)
}
return result, nil
}
}
return []map[string]any{}, nil
}

View File

@@ -68,6 +68,10 @@ func NeConfigInfo(neInfo model.NeInfo, paramName string) (map[string]any, error)
logger.Errorf("NeConfigInfo Unmarshal %s", err.Error())
return nil, err
}
// 网元参数配置信息为空时是{}需要补充data属性
if _, ok := resData["data"]; !ok {
resData["data"] = []map[string]any{}
}
return resData, nil
}

View File

@@ -513,6 +513,10 @@ func (r *NeVersion) operateCommand(action, neType string, neFilePaths []string)
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i 's/TAC = 1;/TAC = %s;/g' /usr/local/etc/mme/mme.conf \n", para5GData["TAC"]))
// SMF开启
cmdStrArr = append(cmdStrArr, "sudo sed -i \"/^ *gxcfg:/,/^ *[^ ]/{s/enable: false/enable: true/;b};\" /usr/local/etc/smf/smf_conf.yaml \n")
// hss host udm
mnc_mcc := fmt.Sprintf("mnc%s.mcc%s", para5GData["MNC_DOMAIN"], para5GData["MCC"])
hssHost := fmt.Sprintf("%s hss.ims.%s.3gppnetwork.org hss", para5GData["UDM_IP"], mnc_mcc)
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s' /etc/hosts || echo '%s' | sudo tee -a /etc/hosts \n", hssHost, hssHost))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s mme' /etc/hosts || echo '%s mme' | sudo tee -a /etc/hosts \n", para5GData["MME_IP"], para5GData["MME_IP"]))
}
// N3IWF配置修改
@@ -683,7 +687,7 @@ func (r *NeVersion) operateDome(action string, neVersion model.NeVersion) error
}
// ========= 网元OAM配置文件 end ===========
// SMSC配置修改IMSUDM 配置
// SMSC配置修改 IMS/UDM 配置
if neInfo.NeType == "SMSC" {
para5GData := NewNeInfo.Para5GData
mnc_mcc := fmt.Sprintf("mnc%s.mcc%s", para5GData["MNC_DOMAIN"], para5GData["MCC"])

View File

@@ -8,6 +8,7 @@ import (
"be.ems/src/framework/vo/result"
neDataModel "be.ems/src/modules/network_data/model"
neDataService "be.ems/src/modules/network_data/service"
neService "be.ems/src/modules/network_element/service"
)
// GetUEConnectByAMF 获取UE会话事件-AMF
@@ -20,6 +21,13 @@ func GetUEConnectByAMF(requestID string, data any) ([]byte, error) {
return nil, fmt.Errorf("query data structure error")
}
// 查询网元获取IP
neInfo := neService.NewNeInfo.SelectNeInfoByNeTypeAndNeID("AMF", query.NeID)
if neInfo.NeId != query.NeID || neInfo.IP == "" {
return nil, fmt.Errorf("not fount neId info")
}
query.RmUID = neInfo.RmUID
rows, total := neDataService.NewUEEventAMF.SelectPage(query)
resultByte, err := json.Marshal(result.Ok(map[string]any{
"requestId": requestID,
@@ -38,6 +46,13 @@ func GetUEConnectByMME(requestID string, data any) ([]byte, error) {
return nil, fmt.Errorf("query data structure error")
}
// 查询网元获取IP
neInfo := neService.NewNeInfo.SelectNeInfoByNeTypeAndNeID("MME", query.NeID)
if neInfo.NeId != query.NeID || neInfo.IP == "" {
return nil, fmt.Errorf("not fount neId info")
}
query.RmUID = neInfo.RmUID
rows, total := neDataService.NewUEEventMME.SelectPage(query)
resultByte, err := json.Marshal(result.Ok(map[string]any{
"requestId": requestID,

View File

@@ -30,10 +30,10 @@ const (
GROUP_SMSC_CDR = "1007_"
// 组号-SGWC_CDR会话事件 1008_neId
GROUP_SGWC_CDR = "1008_"
// 组号-AMF_UE会话事件
// 组号-AMF_UE会话事件 1010_neId
GROUP_AMF_UE = "1010"
// 组号-MME_UE会话事件 1011_neId
GROUP_MME_UE = "1011_"
GROUP_MME_UE = "1011"
)
// 实例化服务层 WSSend 结构体

View File

@@ -1,7 +1,7 @@
# Makefile for OMC-OMC-crontask project
PROJECT = OMC
VERSION = 2.2412.3
VERSION = 2.2501.1
LIBDIR = be.ems/lib
BINNAME = sshsvc