diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c0591f1..02231fe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # 版本发布日志 +## 2.2409.3-20240920 + +- 修复 字典多语言序号重复问题 +- 更新 UDM用户数据表,SMSC参数配置属性,字典数据和跟踪相关表 +- 新增 跟踪任务HLR免登录接口 +- 新增 跟踪任务相关接口初始化,跟踪任务新增非201/400时接收信息 +- 修复 抓包文件下载zip时目录同名导致删除压缩无内容 + +## 2.2409.1-20240909 + +- 新增 告警前转的两个接口email前转和短信前转的系统参数,采用了和网元统一的参数配置方式, +- 优化 修改了dpkg和rpm包安装后的运行脚本,支持通过环境变量传入参数,并判断传入参数调用setomc.sh安装/升级数据库,命令格式:M_PARAM=upgrade C_PARAM=ba dpkg -I xxxx.deb,如果不传入参数则和以前相同 +- 调整的dpkg和rpm包安装的运行脚本中停止omc服务的顺序,解决了omc安装包在前端界面自升级时出现无法自动刷新的问题 + +## 2.2408.5-20240831 + +- 修复 系统信息读取磁盘获取超时导致返回空数组 +- 优化 缓存信息安全清理排除登录用户身份和验证码信息 +- 新增 KPI自定义指标功能接口 +- 新增 日志数据导出文件查看功能接口 + ## 2.2408.4-20240823 - 优化 网元端文件目录/tmp/omc 上传push 下载pull diff --git a/README.md b/README.md index 7cd472fd..5c215d36 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ | --------------------- | -------------------------- | | /usr/local/omc/static | 网管静态资源文件路径 | | /usr/local/omc/upload | 网管上传文件资源路径 | +| /usr/local/etc/omc | 网管与网元之间相关文件 | | /tmp/omc | 存放从网元拉取到本地的文件 | ## redis 配置文件相关 @@ -57,6 +58,10 @@ go mod download # 调试启动 go run restagent.go -c ./etc/restconf.yaml --env local +# 调试分析 +# http://127.0.0.1:33060/debug/pprof/ +go tool pprof -http=:9090 http://127.0.0.1:33060/debug/pprof/goroutine + # 打包命名 restagent go build -ldflags="-s -w" -o restagent ``` @@ -79,8 +84,12 @@ go build -o crontask -v -ldflags="-s -w -X 'be.ems/lib/global.Version=2.240620.1 ## 安装 ```sh --- BA初始安装 +# BA初始安装 /usr/local/omc/bin/setomc.sh -m install -c ba /usr/local/omc/bin/setomc.sh -m upgrade -c ba /usr/local/omc/bin/setomc.sh -m skip -c ba + +# 安装包安装 +sudo M_PARAM=install C_PARAM=ba dpkg -i /usr/local/omc/bin/ems_2.240620.1_amd64.deb +sudo M_PARAM=upgrade C_PARAM=ba dpkg -i /usr/local/omc/bin/ems_2.240620.1_amd64.deb ``` diff --git a/captrace/makefile b/captrace/makefile index 1e6a7958..13059799 100644 --- a/captrace/makefile +++ b/captrace/makefile @@ -1,7 +1,7 @@ # Makefile for rest agent project PROJECT = OMC -VERSION = 2.2408.1 +VERSION = 2.2409.3 PLATFORM = amd64 ARMPLATFORM = aarch64 BUILDDIR = ../../build diff --git a/config/etc/default/restconf.yaml b/config/etc/default/restconf.yaml index dbc3cd5a..eee4d267 100644 --- a/config/etc/default/restconf.yaml +++ b/config/etc/default/restconf.yaml @@ -80,6 +80,12 @@ mml: password: admin mmlHome: ./mmlhome +# Tracking configuration +trace: + enabled: true + host: "172.16.5.100" # Fill in the specific IP address + port: 33033 + # NE config ne: user: omcuser @@ -126,28 +132,35 @@ omc: # Alarm module setting # Forward interface: -# email/sms/smsc +# TLS Skip verify: true/false +# email/sms +# smProxy: sms(Short Message Service)/smsc(SMS Centre) +# dataCoding: 0:UCS2, 1:ASCII, 2:LATIN1 alarm: - forwardAlarm: true - email: - smtp: smtp.xxx.com + alarmEmailForward: + enable: true + emailList: + smtp: mail.smtp.com port: 25 - user: smtpuser@xxx.com - password: xxxxxx - # TLS skip verify: true/false + user: smtpext@smtp.com + password: "1000smtp@omc!" tlsSkipVerify: true - smProxy: smsc - sms: - apiURL: http://smsc.xxx.com - accessKeyID: xxx - accessKeySecret: xxx - signName: XXX SMSC - templateCode: 1000 - smsc: - addr: "192.168.13.114:2775" - systemID: "alarmsmsfw" + alarmSMSForward: + enable: true + mobileList: + smscAddr: "192.168.13.114:2775" + systemID: "omc" password: "omc123" - systemType: "" + systemType: "UTRAN" + dataCoding: 0 + serviceNumber: "OMC" + sms: + apiURL: http://smsc.xxx.com/ + accessKeyID: xxxx + accessKeySecret: xxxx + signName: xxx SMSC + templateCode: 1000 + smProxy: smsc # User authorized information # crypt: mysql/md5/bcrypt diff --git a/config/etc/default/sshsvc.yaml b/config/etc/default/sshsvc.yaml index 9c4f530a..8b5d6c24 100644 --- a/config/etc/default/sshsvc.yaml +++ b/config/etc/default/sshsvc.yaml @@ -23,13 +23,48 @@ logmml: # session: single/multiple session for one user sshd: listenAddr: 0.0.0.0 - listenPort: 22222 + listenPort: 32222 privateKey: /usr/local/omc/.ssh/id_rsa - maxConnNum: 20 + maxConnNum: 2 timeout: 1800 session: multiple mmlHome: /usr/local/omc/mmlhome + userName: manager + password: pass123 + authType: local + tagNE: hlr +# authType: local/omc +telnetServer: + listenAddr: 0.0.0.0 + listenPort: 32323 + maxConnNum: 2 + timeout: 1800 + session: multiple + mmlHome: /usr/local/omc/mmlhome + userName: manager + password: pass123 + authType: local + tagNE: hlr + +# authproto: NoAuth/MD5/SHA +# privProto: NoPriv/DES/AES/AES192/AES256 +snmpServer: + listenAddr: '[::]' + listenPort: 34957 + userName: manager + authPass: pass123 + authproto: MD5 + privPass: "3F2A1B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1B2C3D4E" + privProto: DES + engineID: "8000000004323030313a6462383a3a39313636" + trapPort: 34958 + trapListen: true + trapBool: true + trapTick: 60 + timeOut: 5 + trapTarget: "2001:db8::9219" + database: type: mysql user: root diff --git a/config/param/mme_param_config.yaml b/config/param/mme_param_config.yaml index d4f994bb..8a21f5a0 100644 --- a/config/param/mme_param_config.yaml +++ b/config/param/mme_param_config.yaml @@ -169,6 +169,13 @@ mme: filter: "0~128" display: "HSS Hostname" comment: "0~128" + - name: "hssRealm" + type: "string" + value: "ims.mnc001.mcc001.3gppnetwork.org" + access: "read-write" + filter: "0~128" + display: "HSS Realm" + comment: "0~128" - name: "protocol" type: "string" value: "SCTP" diff --git a/config/param/omc_param_config.yaml b/config/param/omc_param_config.yaml new file mode 100644 index 00000000..b2c96186 --- /dev/null +++ b/config/param/omc_param_config.yaml @@ -0,0 +1,114 @@ +omc: + alarmEmailForward: + display: "Alarm Email Forward Interface" + sort: 3 + list: + - name: "enable" + type: "bool" + value: "true" + access: "rw" + filter: "true;false" + display: "Enable" + comment: "Is it enabled forward alarm with Email interface" + - name: "emailList" + type: "string" + value: "" + access: "rw" + filter: "" + display: "Email List" + comment: "" + - name: "smtp" + type: "string" + value: "" + access: "rw" + filter: "" + display: "SMTP Server" + comment: "Email SMTP server" + - name: "port" + type: "int" + value: "" + access: "rw" + filter: "0~65535" + display: "Port" + comment: "" + - name: "user" + type: "string" + value: "" + access: "rw" + filter: "" + display: "User" + comment: "" + - name: "password" + type: "string" + value: "" + access: "rw" + filter: "" + display: "Password" + comment: "" + - name: "tlsSkipVerify" + type: "bool" + value: "true" + access: "rw" + filter: "true;false" + display: "TLS Skip Verify" + comment: "If skip TLS verify (true/false)" + alarmSMSForward: + display: "Alarm SMS Forward Interface" + sort: 4 + list: + - name: "enable" + type: "bool" + value: "true" + access: "rw" + filter: "true;false" + display: "Enable" + comment: "Is it enabled forward alarm with SMS interface" + - name: "mobileList" + type: "string" + value: "" + access: "rw" + filter: "" + display: "Mobile List" + comment: "" + - name: "smscAddr" + type: "string" + value: "" + access: "rw" + filter: "" + display: "SMSC Address" + comment: "The SMSC SMPP Address" + - name: "systemID" + type: "string" + value: "" + access: "rw" + filter: "" + display: "System ID" + comment: "" + - name: "password" + type: "string" + value: "" + access: "rw" + filter: "" + display: "Password" + comment: "" + - name: "systemType" + type: "string" + value: "" + access: "rw" + filter: "" + display: "System Type" + comment: "" + - name: "dataCoding" + type: "enum" + value: "ASCII" + access: "rw" + filter: '{"0":"UCS2","1":"ASCII","2":"LATIN1"}' + display: "Data Coding" + comment: "Short message coding type" + - name: "serviceNumber" + type: "string" + value: "OMC" + access: "rw" + filter: "3~20" + display: "Service Number" + comment: "It is the source address and length is between 3 and 20" \ No newline at end of file diff --git a/config/param/smsc_param_config.yaml b/config/param/smsc_param_config.yaml index 1f06e7d6..a3e2d3c1 100644 --- a/config/param/smsc_param_config.yaml +++ b/config/param/smsc_param_config.yaml @@ -101,6 +101,48 @@ smsc: filter: "0~16" display: "SCF Address" comment: "" + - name: "mtIdFormatFlag" + type: "bool" + value: "0" + access: "read-write" + filter: '{"0":"false","1":"true"}' + display: "MT Id Format Flag" + comment: "If add plus then set false" + - name: "mcastFlag" + type: "bool" + value: "0" + access: "read-write" + filter: '{"0":"false","1":"true"}' + display: "Mcast Flag" + comment: "enable mcast sms" + - name: "logLevel" + type: "enum" + value: "0" + access: "read-write" + filter: '{"0":"none","1":"error","2":"debug"}' + display: "Log Level" + comment: "" + - name: "logSize" + type: "int" + value: "200" + access: "read-write" + filter: "1-1000" + display: "Log Size" + comment: "The MB sizeof log file" + - name: "logNum" + type: "int" + value: "10" + access: "read-write" + filter: "1-20" + display: "Log Number" + comment: "The number of log file" + - name: "logDir" + type: "string" + value: "/var/log/" + access: "read-write" + filter: "0~128" + display: "Log Directory" + comment: "" msisdnsegment: display: "MSISDN Segment List" sort: 3 @@ -130,6 +172,7 @@ smsc: smpplink: display: "SMPP Link List" sort: 5 + perms: "post,delete" array: - name: "index" type: "int" @@ -208,3 +251,188 @@ smsc: filter: '{"0":"server","1":"client"}' display: "Role Type" comment: "" + convprefix: + display: "Conv Prefix List" + sort: 7 + perms: "post,delete" + array: + - name: "index" + type: "int" + value: "0" + access: "read-only" + filter: "0~127" + display: "Index" + comment: "0~127" + - name: "prefix" + type: "string" + value: "0" + access: "read-write" + filter: "0~16" + display: "Prefix" + comment: "" + - name: "deleteLength" + type: "int" + value: "0" + access: "read-write" + filter: "0-16" + display: "Delete Length" + comment: "" + - name: "addLength" + type: "int" + value: "0" + access: "read-write" + filter: "0-16" + display: "Add Length" + comment: "" + - name: "addDigits" + type: "string" + value: "0" + access: "read-write" + filter: "0~16" + display: "Add Digits" + comment: "" + - name: "numberLength" + type: "int" + value: "0" + access: "read-write" + filter: "0-32" + display: "Number Length" + comment: "" + smppparam: + display: "SMPP Param List" + sort: 9 + perms: "put" + array: + - name: "index" + type: "int" + value: "0" + access: "read-only" + filter: "0~31" + display: "Index" + comment: "0~31" + - name: "linkAlias" + type: "string" + value: "0" + access: "read-write" + filter: "0-8" + display: "Link Alias" + comment: "" + - name: "linkType" + type: "enum" + value: "0" + access: "read-write" + filter: '{"0":"udp","1":"tcp"}' + display: "Link Type" + comment: "" + - name: "serverType" + type: "enum" + value: "0" + access: "read-write" + filter: '{"0":"client","1":"server"}' + display: "Server Type" + comment: "" + - name: "sessionType" + type: "enum" + value: "0" + access: "read-write" + filter: '{"0":"bindTX","1":"bindRX","2":"bindTRX"}' + display: "Session Type" + comment: "" + - name: "systemID" + type: "string" + value: "0" + access: "read-write" + filter: "0-16" + display: "System ID" + comment: "" + - name: "password" + type: "string" + value: "0" + access: "read-write" + filter: "0-8" + display: "Password" + comment: "" + - name: "systemType" + type: "string" + value: "0" + access: "read-write" + filter: "0-12" + display: "System Type" + comment: "" + - name: "localGTT" + type: "string" + value: "0" + access: "read-write" + filter: "0-16" + display: "Local GTT" + comment: "" + - name: "remoteGTT" + type: "string" + value: "0" + access: "read-write" + filter: "0-16" + display: "Remote GTT" + comment: "" + - name: "localIP" + type: "string" + value: "0" + access: "read-write" + filter: "0-32" + display: "Local IP" + comment: "" + - name: "remoteIP" + type: "string" + value: "0" + access: "read-write" + filter: "0-32" + display: "Remote IP" + comment: "" + - name: "sessionInitTimer" + type: "int" + value: "0" + access: "read-write" + filter: "0-65535" + display: "Session Init Timer" + comment: "" + - name: "enquireLinkTimer" + type: "int" + value: "0" + access: "read-write" + filter: "0-65535" + display: "Enquire Link Timer" + comment: "" + - name: "inactivityTimer" + type: "int" + value: "0" + access: "read-write" + filter: "0-65535" + display: "Inactivity Timer" + comment: "" + - name: "responseTimer" + type: "int" + value: "0" + access: "read-write" + filter: "0-65535" + display: "Response Timer" + comment: "" + - name: "localSSN" + type: "int" + value: "0" + access: "read-write" + filter: "0-255" + display: "Local SSN" + comment: "" + - name: "remoteSSN" + type: "int" + value: "0" + access: "read-write" + filter: "0-255" + display: "Remote SSN" + comment: "" + - name: "enable" + type: "bool" + value: "1" + access: "read-write" + filter: '{"0":"false","1":"true"}' + display: "Enable Flag" + comment: "" diff --git a/crontask/makefile b/crontask/makefile index 297e77a0..c066c402 100644 --- a/crontask/makefile +++ b/crontask/makefile @@ -1,7 +1,7 @@ # Makefile for OMC-OMC-crontask project PROJECT = OMC -VERSION = 2.2408.1 +VERSION = 2.2409.3 LIBDIR = be.ems/lib BINNAME = crontask diff --git a/data2html/makefile b/data2html/makefile index d67b4dbe..9218ce11 100644 --- a/data2html/makefile +++ b/data2html/makefile @@ -1,7 +1,7 @@ # Makefile for rest agent project PROJECT = OMC -VERSION = 2.2408.1 +VERSION = 2.2409.3 RelDate = `date +%Y%m%d` Release = $(RelDate) RelVer = $(VERSION)-$(RelDate) diff --git a/database/common/ne_config.sql b/database/common/ne_config.sql index 298b49d9..45f8c522 100644 --- a/database/common/ne_config.sql +++ b/database/common/ne_config.sql @@ -14,7 +14,7 @@ CREATE TABLE `ne_config` ( `param_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '参数名', `param_display` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参数显示名', `param_type` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参数类型 list列表单层 array数组多层', - `param_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'accesss属性控制:只读read-only/read/ro 读写read-write', + `param_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'accesss属性控制: 只读read-only/read/ro 读写read-write', `param_sort` int DEFAULT '0' COMMENT '参数排序', `param_perms` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '操作权限 get只读 put可编辑 delete可删除 post可新增', `update_time` bigint DEFAULT NULL COMMENT '更新时间', @@ -36,13 +36,15 @@ INSERT INTO `ne_config` VALUES (8, 'IMS', 'plmn', 'PLMN List', 'array', '[{\"acc INSERT INTO `ne_config` VALUES (9, 'IMS', 'mmtel_dialplan', 'MMTEL Dialplan', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-only\",\"comment\":\"\",\"display\":\"NaName\",\"filter\":\"0~128\",\"name\":\"naName\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Title\",\"filter\":\"0~128\",\"name\":\"title\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Method\",\"filter\":\"0-2\",\"name\":\"method\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Prefix\",\"filter\":\"0~128\",\"name\":\"prefix\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Start\",\"filter\":\"0~128\",\"name\":\"start\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"End\",\"filter\":\"0~128\",\"name\":\"end\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Attrib\",\"filter\":\"0~128\",\"name\":\"attrib\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Number Len\",\"filter\":\"0~128\",\"name\":\"numberLen\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Rsc\",\"filter\":\"0~128\",\"name\":\"rsc\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"E164 Nai\",\"filter\":\"0~128\",\"name\":\"e164Nai\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"E164 Delete\",\"filter\":\"0~128\",\"name\":\"e164Delete\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"E164 Insert\",\"filter\":\"0~128\",\"name\":\"e164Insert\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"Enable: Close/Open\",\"display\":\"Admin State\",\"filter\":\"{\\\"0\\\":\\\"Close\\\", \\\"1\\\":\\\"Open\\\"}\",\"name\":\"adminState\",\"type\":\"enum\",\"value\":\"0\"}]', 5, '', 1723716862110); INSERT INTO `ne_config` VALUES (10, 'IMS', 'ds_system', 'DS System', 'list', '[{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Dispatch System Indicator\",\"filter\":\"{\\\"0\\\":\\\"false\\\", \\\"1\\\":\\\"true\\\"}\",\"name\":\"dispatchSystemInd\",\"type\":\"bool\",\"value\":\"false\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Transcode Indicator\",\"filter\":\"{\\\"0\\\":\\\"false\\\", \\\"1\\\":\\\"true\\\"}\",\"name\":\"transcodeInd\",\"type\":\"bool\",\"value\":\"false\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Dispatch System IPv4\",\"filter\":\"\",\"name\":\"dispatchSystemIP\",\"type\":\"ipv4\",\"value\":\"1.0.0.1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Dispatch System Port\",\"filter\":\"\",\"name\":\"dispatchSystemPort\",\"type\":\"int\",\"value\":\"5060\"}]', 7, '', 1723716862113); -INSERT INTO `ne_config` VALUES (11, 'MME', 'system', 'System Config', 'list', '[{\"access\":\"read-write\",\"comment\":\"true|false\",\"display\":\"CSFB Enabled\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"csfbEnabled\",\"type\":\"bool\",\"value\":\"false\"},{\"access\":\"read-write\",\"comment\":\"true|false\",\"display\":\"VoLTE Enabled\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"volteEnabled\",\"type\":\"bool\",\"value\":\"false\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"S1 MME IP\",\"filter\":\"0~64\",\"name\":\"s1MmeIp\",\"type\":\"string\",\"value\":\"192.168.1.179\"},{\"access\":\"read-only\",\"comment\":\"0~65535\",\"display\":\"S1 MME Port\",\"filter\":\"0~65535\",\"name\":\"s1MmePort\",\"type\":\"int\",\"value\":\"36412\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"S11 MME IP\",\"filter\":\"0~64\",\"name\":\"s11MmeIp\",\"type\":\"string\",\"value\":\"192.168.1.179\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"S11 MME Port\",\"filter\":\"0~65535\",\"name\":\"s11MmePort\",\"type\":\"int\",\"value\":\"2123\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"S10 MME IP\",\"filter\":\"0~64\",\"name\":\"s10MmeIp\",\"type\":\"string\",\"value\":\"192.168.1.178\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"S10 MME Port\",\"filter\":\"0~65535\",\"name\":\"s10MmePort\",\"type\":\"int\",\"value\":\"2123\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"SGs MME IP\",\"filter\":\"0~64\",\"name\":\"sgsMmeIp\",\"type\":\"string\",\"value\":\"192.168.1.179\"},{\"access\":\"read-only\",\"comment\":\"0~65535\",\"display\":\"SGs MME Port\",\"filter\":\"0~65535\",\"name\":\"sgsMmePort\",\"type\":\"int\",\"value\":\"29118\"},{\"access\":\"read-write\",\"comment\":\"0~100\",\"display\":\"S6A MME Identity\",\"filter\":\"0~100\",\"name\":\"s6aIdentity\",\"type\":\"string\",\"value\":\"mme.epc.mnc001.mcc001.3gppnetwork.org\"},{\"access\":\"read-write\",\"comment\":\"0~20\",\"display\":\"S6A MME IP\",\"filter\":\"0~20\",\"name\":\"localIp\",\"type\":\"string\",\"value\":\"172.16.5.220\"}]', 1, '', 1719831209702); -INSERT INTO `ne_config` VALUES (12, 'MME', 'gummei', 'Gummei List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"Group ID\",\"filter\":\"0~65535\",\"name\":\"groupId\",\"type\":\"int\",\"value\":\"4\"},{\"access\":\"read-write\",\"comment\":\"0~255\",\"display\":\"Code\",\"filter\":\"0~255\",\"name\":\"code\",\"type\":\"int\",\"value\":\"1\"}]', 3, '', 1719831209759); -INSERT INTO `ne_config` VALUES (13, 'MME', 'tai', 'TAI List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"TAC\",\"filter\":\"0~65535\",\"name\":\"tac\",\"type\":\"int\",\"value\":\"1\"}]', 5, '', 1719831209792); -INSERT INTO `ne_config` VALUES (14, 'MME', 'hss', 'HSS List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{1,15}$\",\"display\":\"IMSI Prefix\",\"filter\":\"^[0-9]{1,15}$\",\"name\":\"imsiPre\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~128\",\"display\":\"HSS Hostname\",\"filter\":\"0~128\",\"name\":\"hssHostname\",\"type\":\"string\",\"value\":\"hss.ims.mnc001.mcc001.3gppnetwork.org\"},{\"access\":\"read-write\",\"comment\":\"SCTP|TCP\",\"display\":\"Protocol\",\"filter\":\"0~8\",\"name\":\"protocol\",\"type\":\"string\",\"value\":\"SCTP\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"HSS Port\",\"filter\":\"0~65535\",\"name\":\"hssPort\",\"type\":\"int\",\"value\":\"3868\"}]', 7, '', 1719831209841); -INSERT INTO `ne_config` VALUES (15, 'MME', 'sgw', 'SGW List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"TAC\",\"filter\":\"0~65535\",\"name\":\"tac\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"SGW IP\",\"filter\":\"0~64\",\"name\":\"sgwIp\",\"type\":\"string\",\"value\":\"172.16.5.150\"}]', 9, '', 1719831209876); -INSERT INTO `ne_config` VALUES (16, 'MME', 'pgw', 'PGW List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~128\",\"display\":\"APN\",\"filter\":\"0~128\",\"name\":\"apn\",\"type\":\"string\",\"value\":\"internet\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"PGW IP\",\"filter\":\"0~64\",\"name\":\"pgwIp\",\"type\":\"string\",\"value\":\"192.168.1.181\"}]', 11, '', 1719831209927); -INSERT INTO `ne_config` VALUES (17, 'MME', 'amf', 'AMF List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~16777215\",\"display\":\"TAC\",\"filter\":\"0~16777215\",\"name\":\"tac\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~255\",\"display\":\"Region ID\",\"filter\":\"0~255\",\"name\":\"regionId\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~1023\",\"display\":\"Set ID\",\"filter\":\"0~1023\",\"name\":\"setId\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~63\",\"display\":\"Pointer\",\"filter\":\"0~63\",\"name\":\"pointer\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"AMF IP\",\"filter\":\"0~64\",\"name\":\"amfIp\",\"type\":\"string\",\"value\":\"172.16.5.120\"}]', 13, '', 1719831209992); +-- 更新 MME 配置 20240906 +INSERT INTO `ne_config` VALUES (11, 'MME', 'system', 'System Config', 'list', '[{\"access\":\"read-write\",\"comment\":\"true|false\",\"display\":\"CSFB Enabled\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"csfbEnabled\",\"type\":\"bool\",\"value\":\"false\"},{\"access\":\"read-write\",\"comment\":\"true|false\",\"display\":\"VoLTE Enabled\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"volteEnabled\",\"type\":\"bool\",\"value\":\"false\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"S1 MME IP\",\"filter\":\"0~64\",\"name\":\"s1MmeIp\",\"type\":\"string\",\"value\":\"192.168.1.179\"},{\"access\":\"read-only\",\"comment\":\"0~65535\",\"display\":\"S1 MME Port\",\"filter\":\"0~65535\",\"name\":\"s1MmePort\",\"type\":\"int\",\"value\":\"36412\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"S11 MME IP\",\"filter\":\"0~64\",\"name\":\"s11MmeIp\",\"type\":\"string\",\"value\":\"192.168.1.179\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"S11 MME Port\",\"filter\":\"0~65535\",\"name\":\"s11MmePort\",\"type\":\"int\",\"value\":\"2123\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"S10 MME IP\",\"filter\":\"0~64\",\"name\":\"s10MmeIp\",\"type\":\"string\",\"value\":\"192.168.1.178\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"S10 MME Port\",\"filter\":\"0~65535\",\"name\":\"s10MmePort\",\"type\":\"int\",\"value\":\"2123\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"SGs MME IP\",\"filter\":\"0~64\",\"name\":\"sgsMmeIp\",\"type\":\"string\",\"value\":\"192.168.1.179\"},{\"access\":\"read-only\",\"comment\":\"0~65535\",\"display\":\"SGs MME Port\",\"filter\":\"0~65535\",\"name\":\"sgsMmePort\",\"type\":\"int\",\"value\":\"29118\"},{\"access\":\"read-write\",\"comment\":\"0~100\",\"display\":\"S6A MME Identity\",\"filter\":\"0~100\",\"name\":\"s6aIdentity\",\"type\":\"string\",\"value\":\"mme.epc.mnc001.mcc001.3gppnetwork.org\"},{\"access\":\"read-write\",\"comment\":\"0~20\",\"display\":\"S6A MME IP\",\"filter\":\"0~20\",\"name\":\"localIp\",\"type\":\"string\",\"value\":\"172.16.5.220\"}]', 1, '', 1725610815287); +INSERT INTO `ne_config` VALUES (12, 'MME', 'gummei', 'Gummei List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"Group ID\",\"filter\":\"0~65535\",\"name\":\"groupId\",\"type\":\"int\",\"value\":\"4\"},{\"access\":\"read-write\",\"comment\":\"0~255\",\"display\":\"Code\",\"filter\":\"0~255\",\"name\":\"code\",\"type\":\"int\",\"value\":\"1\"}]', 3, '', 1725610815301); +INSERT INTO `ne_config` VALUES (13, 'MME', 'tai', 'TAI List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"TAC\",\"filter\":\"0~65535\",\"name\":\"tac\",\"type\":\"int\",\"value\":\"1\"}]', 5, '', 1725610815306); +INSERT INTO `ne_config` VALUES (14, 'MME', 'hss', 'HSS List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{1,15}$\",\"display\":\"IMSI Prefix\",\"filter\":\"^[0-9]{1,15}$\",\"name\":\"imsiPre\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~128\",\"display\":\"HSS Hostname\",\"filter\":\"0~128\",\"name\":\"hssHostname\",\"type\":\"string\",\"value\":\"hss.ims.mnc001.mcc001.3gppnetwork.org\"},{\"access\":\"read-write\",\"comment\":\"0~128\",\"display\":\"HSS Realm\",\"filter\":\"0~128\",\"name\":\"hssRealm\",\"type\":\"string\",\"value\":\"ims.mnc001.mcc001.3gppnetwork.org\"},{\"access\":\"read-write\",\"comment\":\"SCTP|TCP\",\"display\":\"Protocol\",\"filter\":\"0~8\",\"name\":\"protocol\",\"type\":\"string\",\"value\":\"SCTP\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"HSS Port\",\"filter\":\"0~65535\",\"name\":\"hssPort\",\"type\":\"int\",\"value\":\"3868\"}]', 7, '', 1725610815311); +INSERT INTO `ne_config` VALUES (15, 'MME', 'sgw', 'SGW List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"TAC\",\"filter\":\"0~65535\",\"name\":\"tac\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"SGW IP\",\"filter\":\"0~64\",\"name\":\"sgwIp\",\"type\":\"string\",\"value\":\"172.16.5.150\"}]', 9, '', 1725610815316); +INSERT INTO `ne_config` VALUES (16, 'MME', 'pgw', 'PGW List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~128\",\"display\":\"APN\",\"filter\":\"0~128\",\"name\":\"apn\",\"type\":\"string\",\"value\":\"internet\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"PGW IP\",\"filter\":\"0~64\",\"name\":\"pgwIp\",\"type\":\"string\",\"value\":\"192.168.1.181\"}]', 11, '', 1725610815320); +INSERT INTO `ne_config` VALUES (17, 'MME', 'amf', 'AMF List', 'array', '[{\"access\":\"read\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"^[0-9]{5,6}$\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~16777215\",\"display\":\"TAC\",\"filter\":\"0~16777215\",\"name\":\"tac\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~255\",\"display\":\"Region ID\",\"filter\":\"0~255\",\"name\":\"regionId\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~1023\",\"display\":\"Set ID\",\"filter\":\"0~1023\",\"name\":\"setId\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~63\",\"display\":\"Pointer\",\"filter\":\"0~63\",\"name\":\"pointer\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~64\",\"display\":\"AMF IP\",\"filter\":\"0~64\",\"name\":\"amfIp\",\"type\":\"string\",\"value\":\"172.16.5.120\"}]', 13, '', 1725610815323); + INSERT INTO `ne_config` VALUES (18, 'MOCNGW', 'system', 'System Config', 'list', '[{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"S1AP South Address\",\"filter\":\"0~64\",\"name\":\"s1apSouthAddr\",\"type\":\"string\",\"value\":\"192.168.7.163\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"S1AP North Address\",\"filter\":\"0~64\",\"name\":\"s1apNorthAddr\",\"type\":\"string\",\"value\":\"192.168.8.163\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"TAC\",\"filter\":\"0~65535\",\"name\":\"tac\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"0~1048575\",\"display\":\"ENB ID\",\"filter\":\"0~1048575\",\"name\":\"enbId\",\"type\":\"int\",\"value\":\"24\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"User Plane Enabled\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"userPlaneEnabled\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"PFCP Address\",\"filter\":\"0~64\",\"name\":\"pfcpAddr\",\"type\":\"string\",\"value\":\"192.168.7.163\"}]', 1, '', 1719831210071); INSERT INTO `ne_config` VALUES (19, 'MOCNGW', 'mme', 'MME List', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"S1AP Address\",\"filter\":\"0~64\",\"name\":\"s1apAddr\",\"type\":\"string\",\"value\":\"192.168.1.161\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"S1AP Port\",\"filter\":\"0~65535\",\"name\":\"s1apPort\",\"type\":\"int\",\"value\":\"36412\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"}]', 3, '', 1719831210273); INSERT INTO `ne_config` VALUES (20, 'MOCNGW', 'upgw', 'UPGW Config', 'list', '[{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"PFCP Address\",\"filter\":\"0~64\",\"name\":\"pfcpAddr\",\"type\":\"string\",\"value\":\"192.168.1.159\"},{\"access\":\"read-write\",\"comment\":\"0~65535\",\"display\":\"PFCP Port\",\"filter\":\"0~65535\",\"name\":\"pfcpPort\",\"type\":\"int\",\"value\":\"8805\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"GTP-U South Address\",\"filter\":\"0~64\",\"name\":\"gtpuSouthAddr\",\"type\":\"string\",\"value\":\"10.10.1.2\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"GTP-U North Address\",\"filter\":\"0~64\",\"name\":\"gtpuNorthAddr\",\"type\":\"string\",\"value\":\"192.168.7.123\"}]', 5, '', 1719831210320); @@ -71,9 +73,6 @@ INSERT INTO `ne_config` VALUES (42, 'SMF', 'dnnSelectUpf', 'DNN Select UPF', 'ar INSERT INTO `ne_config` VALUES (43, 'SMF', 'dnnTaiSelectUpf', 'DNN TAI Select UPF', 'array', '[{\"access\":\"read-only\",\"comment\":\"\",\"display\":\"Index\",\"filter\":\"0~65535\",\"name\":\"index\",\"type\":\"int\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"DNN\",\"filter\":\"1~64\",\"name\":\"dnn\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"MCC+MNC+TAC\",\"display\":\"TAI\",\"filter\":\"1~64\",\"name\":\"tai\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"UPF ID\",\"filter\":\"1~64\",\"name\":\"upfId\",\"type\":\"string\",\"value\":\"upf2-Id\"}]', 9, '', 1719831211733); INSERT INTO `ne_config` VALUES (44, 'SMF', 'snssaiSelectUpf', 'SNSSAI Select UPF', 'array', '[{\"access\":\"read-only\",\"comment\":\"\",\"display\":\"Index\",\"filter\":\"0~65535\",\"name\":\"index\",\"type\":\"int\",\"value\":\"\"},{\"access\":\"read-write\",\"display\":\"Enable\",\"filter\":\"false;true;\",\"name\":\"enable\",\"type\":\"bool\",\"value\":\"true\"},{\"access\":\"read-write\",\"comment\":\"sst1-sd1;sst2-sd2;sst3-sd3\",\"display\":\"SNSSAI\",\"filter\":\"1~64\",\"name\":\"snssai\",\"type\":\"string\",\"value\":\"1-000001\"},{\"access\":\"read-write\",\"comment\":\"upf1-id;upf2-id;upf3-id\",\"display\":\"UPF ID\",\"filter\":\"1~64\",\"name\":\"upfId\",\"type\":\"string\",\"value\":\"upf1-Id\"}]', 11, '', 1719831211854); INSERT INTO `ne_config` VALUES (45, 'SMF', 'offlineChargingConfig', 'Offline Charging Config', 'list', '[{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CDR File Name\",\"filter\":\"1~64\",\"name\":\"cdrFileName\",\"type\":\"string\",\"value\":\"smf.cdr\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CDR File Path\",\"filter\":\"1~256\",\"name\":\"cdrFilePath\",\"type\":\"string\",\"value\":\"/var/log/smfCdr\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CDR File Num\",\"filter\":\"1~999999999\",\"name\":\"cdrFileNum\",\"type\":\"int\",\"value\":\"50\"},{\"access\":\"read-write\",\"comment\":\"Megabytes\",\"display\":\"CDR File Size\",\"filter\":\"1~999999\",\"name\":\"cdrFileSize\",\"type\":\"int\",\"value\":\"300\"},{\"access\":\"read-write\",\"comment\":\"Days\",\"display\":\"CDR File Max Age\",\"filter\":\"0~9999\",\"name\":\"cdrFileMaxAge\",\"type\":\"int\",\"value\":\"30\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Free Subscribers CDR Enable\",\"filter\":\"\",\"name\":\"freeSubsCdrEnable\",\"type\":\"bool\",\"value\":\"false\"},{\"access\":\"read-write\",\"comment\":\"Seconds\",\"display\":\"Time Threshold\",\"filter\":\"0~999999999\",\"name\":\"timeThreshold\",\"type\":\"int\",\"value\":\"600\"},{\"access\":\"read-write\",\"comment\":\"Bytes\",\"display\":\"Volume Threshold\",\"filter\":\"0~999999999999999\",\"name\":\"volumeThreshold\",\"type\":\"int\",\"value\":\"0\"}]', 13, '', 1719831211901); -INSERT INTO `ne_config` VALUES (46, 'SMSC', 'system', 'System', 'list', '[{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CDR Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"cdrFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SM Validity\",\"filter\":\"0-2147483647\",\"name\":\"smValidity\",\"type\":\"int\",\"value\":\"259200\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"logFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable local users.\",\"display\":\"Local Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"localPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable outbound roaming users.\",\"display\":\"Local Roaming Out Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"localRoamingOutPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable inbound roaming users.\",\"display\":\"Visitor Roaming In Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"visitorRoamingInPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to other unattainable users.\",\"display\":\"Other Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"otherPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Define the maximum port number that the queue of pending SMS may grow to.\",\"display\":\"Polling Number\",\"filter\":\"0-64\",\"name\":\"pollingNumber\",\"type\":\"int\",\"value\":\"64\"},{\"access\":\"read-write\",\"comment\":\"Specify the priority parameter of SM_RP_PRI. true = High; false = Low.\",\"display\":\"Priority Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"priorityFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable TP-Reply-Path parameter in the SMS-DELIVER data unit.\",\"display\":\"TP Reply Path Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"tpReplyPathFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SMSC Domain\",\"filter\":\"0~16\",\"name\":\"smscDomain\",\"type\":\"string\",\"value\":\"0.0.0.0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CSFB VoLTE Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"csfbVolteFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Camel Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"camelFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SCF Address\",\"filter\":\"0~16\",\"name\":\"scfAddress\",\"type\":\"string\",\"value\":\"0.0.0.0\"}]', 1, '', 1719831212029); -INSERT INTO `ne_config` VALUES (47, 'SMSC', 'msisdnsegment', 'MSISDN Segment List', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Start MSISDN\",\"filter\":\"0~32\",\"name\":\"startMSISDN\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"End MSISDN\",\"filter\":\"0~32\",\"name\":\"endMSISDN\",\"type\":\"string\",\"value\":\"0\"}]', 3, 'put', 1719831212149); -INSERT INTO `ne_config` VALUES (48, 'SMSC', 'smpplink', 'SMPP Link List', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~63\",\"display\":\"Index\",\"filter\":\"0~63\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Link Alias\",\"filter\":\"0~32\",\"name\":\"linkAlias\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Session Type\",\"filter\":\"{\\\"0\\\":\\\"bindTX\\\",\\\"1\\\":\\\"bindRX\\\",\\\"2\\\":\\\"bindTRX\\\"}\",\"name\":\"sessionType\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Service Number\",\"filter\":\"0~32\",\"name\":\"serviceNumber\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Data Coding Scheme\",\"filter\":\"{\\\"0\\\":\\\"smpp7def7\\\",\\\"1\\\":\\\"smpp8dcs4def7\\\",\\\"2\\\":\\\"smpp8dcs0def7\\\",\\\"16\\\":\\\"smpp7def8\\\",\\\"17\\\":\\\"smpp8dcs4def8\\\",\\\"18\\\":\\\"smpp8dcs0def8\\\"}\",\"name\":\"dataCodingScheme\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Platform Num\",\"filter\":\"{\\\"0\\\":\\\"plat0\\\",\\\"1\\\":\\\"plat1\\\",\\\"2\\\":\\\"ignore\\\"}\",\"name\":\"platformNum\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Time To Live\",\"filter\":\"0-2147483647\",\"name\":\"timeToLive\",\"type\":\"int\",\"value\":\"604800\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Manipulation Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"manipulationFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Type of Number\",\"filter\":\"{\\\"0\\\":\\\"unknown\\\",\\\"1\\\":\\\"international\\\",\\\"2\\\":\\\"national\\\",\\\"3\\\":\\\"networkSpecific\\\",\\\"4\\\":\\\"subscriberNumber\\\",\\\"5\\\":\\\"alphanumeric\\\",\\\"6\\\":\\\"abbreviated\\\"}\",\"name\":\"ton\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Number Plan Indicator\",\"filter\":\"{\\\"0\\\":\\\"unknown\\\",\\\"1\\\":\\\"isdn\\\",\\\"3\\\":\\\"data\\\",\\\"4\\\":\\\"telex\\\",\\\"6\\\":\\\"landMobile\\\",\\\"8\\\":\\\"national\\\",\\\"9\\\":\\\"private\\\",\\\"10\\\":\\\"ermes\\\",\\\"14\\\":\\\"internet\\\",\\\"18\\\":\\\"wapClientID\\\"}\",\"name\":\"npi\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Role Type\",\"filter\":\"{\\\"0\\\":\\\"server\\\",\\\"1\\\":\\\"client\\\"}\",\"name\":\"roleType\",\"type\":\"enum\",\"value\":\"0\"}]', 5, '', 1719831212227); INSERT INTO `ne_config` VALUES (49, 'UDM', 'system', 'System', 'list', '[{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Service IP\",\"filter\":\"\",\"name\":\"serviceIP\",\"type\":\"ipv4\",\"value\":\"172.16.5.140\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Service Port\",\"filter\":\"0~65535\",\"name\":\"servicePort\",\"type\":\"int\",\"value\":\"8080\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"NRF URI\",\"filter\":\"\",\"name\":\"nrfUri\",\"type\":\"string\",\"value\":\"http://172.16.5.180:8080\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"AUSF IP\",\"filter\":\"\",\"name\":\"ausfIP\",\"type\":\"ipv4\",\"value\":\"172.16.5.130\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"FQDN\",\"filter\":\"\",\"name\":\"fqdn\",\"type\":\"string\",\"value\":\"omc.com\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Priority\",\"filter\":\"0~4095\",\"name\":\"priority\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Capacity\",\"filter\":\"0~65535\",\"name\":\"capacity\",\"type\":\"int\",\"value\":\"4096\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Group ID\",\"filter\":\"\",\"name\":\"groupId\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Supported Plmn1\",\"filter\":\"^\\\\d{5,6}$\",\"name\":\"supportedPlmn1\",\"type\":\"string\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Supported Plmn2\",\"filter\":\"^\\\\d{5,6}$\",\"name\":\"supportedPlmn2\",\"type\":\"string\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Supported Plmn3\",\"filter\":\"^\\\\d{5,6}$\",\"name\":\"supportedPlmn3\",\"type\":\"string\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Supported Plmn4\",\"filter\":\"^\\\\d{5,6}$\",\"name\":\"supportedPlmn4\",\"type\":\"string\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SUPI Ranges\",\"filter\":\"^imsi-\\\\d{15}~imsi-\\\\d{15}$\",\"name\":\"supiRanges\",\"type\":\"regex\",\"value\":\"imsi-001010100080000~imsi-001010100080099\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"GPSI Ranges\",\"filter\":\"^msisdn-\\\\d{2,15}~msisdn-\\\\d{2,15}$\",\"name\":\"gpsiRanges\",\"type\":\"regex\",\"value\":\"msisdn-69072000~msisdn-69072099\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Scheme\",\"filter\":\"{\\\"0\\\":\\\"HTTP\\\", \\\"1\\\":\\\"HTTPS\\\"}\",\"name\":\"scheme\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Redis Link\",\"filter\":\"{\\\"0\\\":\\\"TCP\\\",\\\"1\\\":\\\"SCTP\\\"}\",\"name\":\"redisLink\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Redis Address\",\"filter\":\"\",\"name\":\"redisAddr\",\"type\":\"string\",\"value\":\"172.16.5.140:6379\"}]', 1, '', 1719831212399); INSERT INTO `ne_config` VALUES (50, 'UDM', 'subsUEAmbr', 'Subs UE AMBR', 'array', '[{\"access\":\"read-only\",\"comment\":\"\",\"display\":\"Index\",\"filter\":\"1~16\",\"name\":\"index\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Name\",\"filter\":\"^.{1,32}$\",\"name\":\"name\",\"type\":\"string\",\"value\":\"def_ambr\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Uplink\",\"filter\":\"^\\\\d+(\\\\.\\\\d+)?( ?)(bps|Kbps|Mbps|Gbps|Tbps)$\",\"name\":\"uplink\",\"type\":\"regex\",\"value\":\"1 Gbps\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Downlink\",\"filter\":\"^\\\\d+(\\\\.\\\\d+)?( ?)(bps|Kbps|Mbps|Gbps|Tbps)$\",\"name\":\"downlink\",\"type\":\"regex\",\"value\":\"2 Gbps\"}]', 3, '', 1719831212494); INSERT INTO `ne_config` VALUES (51, 'UDM', 'subsNssais', 'Subs NSSAIs', 'array', '[{\"access\":\"read-only\",\"comment\":\"\",\"display\":\"Index\",\"filter\":\"1~16\",\"name\":\"index\",\"type\":\"int\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Name\",\"filter\":\"^.{1,32}$\",\"name\":\"name\",\"type\":\"string\",\"value\":\"def_nssai\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Supported Features\",\"filter\":\"^[0-9a-fA-F]{8}$\",\"name\":\"supportedFeatures\",\"type\":\"regex\",\"value\":\"00000001\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Default Single NSSAIs\",\"filter\":\"\",\"name\":\"defaultSingleNSSAIs\",\"type\":\"string\",\"value\":\"1-000001\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Single NSSAIs\",\"filter\":\"\",\"name\":\"singleNssais\",\"type\":\"string\",\"value\":\"1-000002\"}]', 5, '', 1719831212590); @@ -111,4 +110,15 @@ INSERT INTO `ne_config` VALUES (80, 'CBC', 'system', 'System Config', 'list', '[ INSERT INTO `ne_config` VALUES (81, 'CBC', 'amfProfile', 'AMF Profile', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"NF Name\",\"filter\":\"0~64\",\"name\":\"name\",\"type\":\"string\",\"value\":\"AMF\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"AMF URI\",\"filter\":\"0~64\",\"name\":\"uri\",\"type\":\"string\",\"value\":\"http://172.16.5.130:8080\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~16777215\",\"display\":\"TAC\",\"filter\":\"0~8\",\"name\":\"tac\",\"type\":\"string\",\"value\":\"1\"}]', 3, '', 1724327154499); INSERT INTO `ne_config` VALUES (82, 'CBC', 'mmeProfile', 'MME Profile', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"NF Name\",\"filter\":\"0~64\",\"name\":\"name\",\"type\":\"string\",\"value\":\"MME\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"MME URI\",\"filter\":\"0~64\",\"name\":\"uri\",\"type\":\"string\",\"value\":\"sctp://192.168.1.1:9090\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"PLMN ID\",\"filter\":\"^[0-9]{5,6}$\",\"name\":\"plmnId\",\"type\":\"regex\",\"value\":\"00101\"},{\"access\":\"read-write\",\"comment\":\"0~16777215\",\"display\":\"TAC\",\"filter\":\"0~8\",\"name\":\"tac\",\"type\":\"string\",\"value\":\"1\"}]', 5, '', 1724327154504); +-- OMC parameter config +INSERT INTO `ne_config` VALUES (83, 'OMC', 'alarmEmailForward', 'Alarm Email Forward Interface', 'list', '[{\"access\":\"rw\",\"comment\":\"Is it enabled forward alarm with Email interface\",\"display\":\"Enable\",\"filter\":\"true;false\",\"name\":\"enable\",\"type\":\"bool\",\"value\":\"true\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Email List\",\"filter\":\"\",\"name\":\"emailList\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"Email SMTP server\",\"display\":\"SMTP Server\",\"filter\":\"\",\"name\":\"smtp\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Port\",\"filter\":\"0~65535\",\"name\":\"port\",\"type\":\"int\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"User\",\"filter\":\"\",\"name\":\"user\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Password\",\"filter\":\"\",\"name\":\"password\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"If skip TLS verify (true/false)\",\"display\":\"TLS Skip Verify\",\"filter\":\"true;false\",\"name\":\"tlsSkipVerify\",\"type\":\"bool\",\"value\":\"true\"}]', 3, '', 1725505025649); +INSERT INTO `ne_config` VALUES (84, 'OMC', 'alarmSMSForward', 'Alarm SMS Forward Interface', 'list', '[{\"access\":\"rw\",\"comment\":\"Is it enabled forward alarm with SMS interface\",\"display\":\"Enable\",\"filter\":\"true;false\",\"name\":\"enable\",\"type\":\"bool\",\"value\":\"true\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Mobile List\",\"filter\":\"\",\"name\":\"mobileList\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"The SMSC SMPP Address\",\"display\":\"SMSC Address\",\"filter\":\"\",\"name\":\"smscAddr\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"System ID\",\"filter\":\"\",\"name\":\"systemID\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Password\",\"filter\":\"\",\"name\":\"password\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"System Type\",\"filter\":\"\",\"name\":\"systemType\",\"type\":\"string\",\"value\":\"\"}]', 4, '', 1725505025660); + +-- 更新 SMSC 配置 20240920 +INSERT INTO `ne_config` VALUES (90, 'SMSC', 'system', 'System', 'list', '[{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CDR Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"cdrFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SM Validity\",\"filter\":\"0-2147483647\",\"name\":\"smValidity\",\"type\":\"int\",\"value\":\"259200\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"logFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable local users.\",\"display\":\"Local Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"localPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable outbound roaming users.\",\"display\":\"Local Roaming Out Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"localRoamingOutPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable inbound roaming users.\",\"display\":\"Visitor Roaming In Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"visitorRoamingInPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to other unattainable users.\",\"display\":\"Other Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"otherPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Define the maximum port number that the queue of pending SMS may grow to.\",\"display\":\"Polling Number\",\"filter\":\"0-64\",\"name\":\"pollingNumber\",\"type\":\"int\",\"value\":\"64\"},{\"access\":\"read-write\",\"comment\":\"Specify the priority parameter of SM_RP_PRI. true = High; false = Low.\",\"display\":\"Priority Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"priorityFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable TP-Reply-Path parameter in the SMS-DELIVER data unit.\",\"display\":\"TP Reply Path Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"tpReplyPathFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SMSC Domain\",\"filter\":\"0~16\",\"name\":\"smscDomain\",\"type\":\"string\",\"value\":\"0.0.0.0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CSFB VoLTE Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"csfbVolteFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Camel Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"camelFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SCF Address\",\"filter\":\"0~16\",\"name\":\"scfAddress\",\"type\":\"string\",\"value\":\"0.0.0.0\"},{\"access\":\"read-write\",\"comment\":\"If add plus then set false\",\"display\":\"MT Id Format Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"mtIdFormatFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"enable mcast sms\",\"display\":\"Mcast Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"mcastFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Level\",\"filter\":\"{\\\"0\\\":\\\"none\\\",\\\"1\\\":\\\"error\\\",\\\"2\\\":\\\"debug\\\"}\",\"name\":\"logLevel\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"The MB sizeof log file\",\"display\":\"Log Size\",\"filter\":\"1-1000\",\"name\":\"logSize\",\"type\":\"int\",\"value\":\"200\"},{\"access\":\"read-write\",\"comment\":\"The number of log file\",\"display\":\"Log Number\",\"filter\":\"1-20\",\"name\":\"logNum\",\"type\":\"int\",\"value\":\"10\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Directory\",\"filter\":\"0~128\",\"name\":\"logDir\",\"type\":\"string\",\"value\":\"/var/log/\"}]', 1, '', 1726802301029); +INSERT INTO `ne_config` VALUES (91, 'SMSC', 'msisdnsegment', 'MSISDN Segment List', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~15\",\"display\":\"Index\",\"filter\":\"0~15\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Start MSISDN\",\"filter\":\"0~32\",\"name\":\"startMSISDN\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"End MSISDN\",\"filter\":\"0~32\",\"name\":\"endMSISDN\",\"type\":\"string\",\"value\":\"0\"}]', 3, 'put', 1726802301041); +INSERT INTO `ne_config` VALUES (92, 'SMSC', 'smpplink', 'SMPP Link List', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~63\",\"display\":\"Index\",\"filter\":\"0~63\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Link Alias\",\"filter\":\"0~32\",\"name\":\"linkAlias\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Session Type\",\"filter\":\"{\\\"0\\\":\\\"bindTX\\\",\\\"1\\\":\\\"bindRX\\\",\\\"2\\\":\\\"bindTRX\\\"}\",\"name\":\"sessionType\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Service Number\",\"filter\":\"0~32\",\"name\":\"serviceNumber\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Data Coding Scheme\",\"filter\":\"{\\\"0\\\":\\\"smpp7def7\\\",\\\"1\\\":\\\"smpp8dcs4def7\\\",\\\"2\\\":\\\"smpp8dcs0def7\\\",\\\"16\\\":\\\"smpp7def8\\\",\\\"17\\\":\\\"smpp8dcs4def8\\\",\\\"18\\\":\\\"smpp8dcs0def8\\\"}\",\"name\":\"dataCodingScheme\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Platform Num\",\"filter\":\"{\\\"0\\\":\\\"plat0\\\",\\\"1\\\":\\\"plat1\\\",\\\"2\\\":\\\"ignore\\\"}\",\"name\":\"platformNum\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Time To Live\",\"filter\":\"0-2147483647\",\"name\":\"timeToLive\",\"type\":\"int\",\"value\":\"604800\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Manipulation Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"manipulationFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Type of Number\",\"filter\":\"{\\\"0\\\":\\\"unknown\\\",\\\"1\\\":\\\"international\\\",\\\"2\\\":\\\"national\\\",\\\"3\\\":\\\"networkSpecific\\\",\\\"4\\\":\\\"subscriberNumber\\\",\\\"5\\\":\\\"alphanumeric\\\",\\\"6\\\":\\\"abbreviated\\\"}\",\"name\":\"ton\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Number Plan Indicator\",\"filter\":\"{\\\"0\\\":\\\"unknown\\\",\\\"1\\\":\\\"isdn\\\",\\\"3\\\":\\\"data\\\",\\\"4\\\":\\\"telex\\\",\\\"6\\\":\\\"landMobile\\\",\\\"8\\\":\\\"national\\\",\\\"9\\\":\\\"private\\\",\\\"10\\\":\\\"ermes\\\",\\\"14\\\":\\\"internet\\\",\\\"18\\\":\\\"wapClientID\\\"}\",\"name\":\"npi\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Role Type\",\"filter\":\"{\\\"0\\\":\\\"server\\\",\\\"1\\\":\\\"client\\\"}\",\"name\":\"roleType\",\"type\":\"enum\",\"value\":\"0\"}]', 5, 'post,delete', 1726802301049); +INSERT INTO `ne_config` VALUES (93, 'SMSC', 'convprefix', 'Conv Prefix List', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~127\",\"display\":\"Index\",\"filter\":\"0~127\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Prefix\",\"filter\":\"0~16\",\"name\":\"prefix\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Delete Length\",\"filter\":\"0-16\",\"name\":\"deleteLength\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Add Length\",\"filter\":\"0-16\",\"name\":\"addLength\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Add Digits\",\"filter\":\"0~16\",\"name\":\"addDigits\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Number Length\",\"filter\":\"0-32\",\"name\":\"numberLength\",\"type\":\"int\",\"value\":\"0\"}]', 7, 'post,delete', 1726802301054); +INSERT INTO `ne_config` VALUES (94, 'SMSC', 'smppparam', 'SMPP Param List', 'array', '[{\"access\":\"read-only\",\"comment\":\"0~31\",\"display\":\"Index\",\"filter\":\"0~31\",\"name\":\"index\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Link Alias\",\"filter\":\"0-8\",\"name\":\"linkAlias\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Link Type\",\"filter\":\"{\\\"0\\\":\\\"udp\\\",\\\"1\\\":\\\"tcp\\\"}\",\"name\":\"linkType\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Server Type\",\"filter\":\"{\\\"0\\\":\\\"client\\\",\\\"1\\\":\\\"server\\\"}\",\"name\":\"serverType\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Session Type\",\"filter\":\"{\\\"0\\\":\\\"bindTX\\\",\\\"1\\\":\\\"bindRX\\\",\\\"2\\\":\\\"bindTRX\\\"}\",\"name\":\"sessionType\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"System ID\",\"filter\":\"0-16\",\"name\":\"systemID\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Password\",\"filter\":\"0-8\",\"name\":\"password\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"System Type\",\"filter\":\"0-12\",\"name\":\"systemType\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Local GTT\",\"filter\":\"0-16\",\"name\":\"localGTT\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Remote GTT\",\"filter\":\"0-16\",\"name\":\"remoteGTT\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Local IP\",\"filter\":\"0-32\",\"name\":\"localIP\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Remote IP\",\"filter\":\"0-32\",\"name\":\"remoteIP\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Session Init Timer\",\"filter\":\"0-65535\",\"name\":\"sessionInitTimer\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Enquire Link Timer\",\"filter\":\"0-65535\",\"name\":\"enquireLinkTimer\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Inactivity Timer\",\"filter\":\"0-65535\",\"name\":\"inactivityTimer\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Response Timer\",\"filter\":\"0-65535\",\"name\":\"responseTimer\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Local SSN\",\"filter\":\"0-255\",\"name\":\"localSSN\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Remote SSN\",\"filter\":\"0-255\",\"name\":\"remoteSSN\",\"type\":\"int\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Enable Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"enable\",\"type\":\"bool\",\"value\":\"1\"}]', 9, 'put', 1726802301058); + SET FOREIGN_KEY_CHECKS=1; diff --git a/database/install/function.sql b/database/install/function.sql index 4dbfface..1fb14ece 100644 --- a/database/install/function.sql +++ b/database/install/function.sql @@ -1,16 +1,17 @@ DELIMITER // CREATE FUNCTION IF NOT EXISTS omc_get_dict_value(field_value VARCHAR(255), type VARCHAR(255)) -RETURNS VARCHAR(255) +RETURNS VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci DETERMINISTIC BEGIN DECLARE result VARCHAR(255); SELECT `dict_value` INTO result -FROM `sys_dict_data` -WHERE `dict_label` = field_value AND `dict_type` = type limit 1; +FROM `sys_dict_data` +WHERE `dict_label` = field_value AND `dict_type` = type +LIMIT 1; RETURN result; END // -DELIMITER; \ No newline at end of file +DELIMITER ; diff --git a/database/install/kpi_c_report.sql b/database/install/kpi_c_report.sql new file mode 100644 index 00000000..7c538aec --- /dev/null +++ b/database/install/kpi_c_report.sql @@ -0,0 +1,41 @@ +/* + 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: 29/08/2024 14:53:38 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for kpi_c_report_upf +-- ---------------------------- +DROP TABLE IF EXISTS `kpi_c_report`; +CREATE TABLE `kpi_c_report` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ne_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `ne_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '', + `rm_uid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `date` date NOT NULL, + `start_time` time NULL DEFAULT NULL, + `end_time` time NULL DEFAULT NULL, + `index` smallint(6) NOT NULL, + `granularity` tinyint(4) NULL DEFAULT 60 COMMENT 'Time granualarity: 5/10/.../60/300 (second)', + `kpi_values` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL, + `created_at` timestamp NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_timestamp`(`created_at`) USING BTREE, + INDEX `idx_uid_datetime`(`rm_uid`, `date`, `start_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 654904 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/install/kpi_c_title.sql b/database/install/kpi_c_title.sql new file mode 100644 index 00000000..9430160b --- /dev/null +++ b/database/install/kpi_c_title.sql @@ -0,0 +1,39 @@ +/* + 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 : omc_db + + Target Server Type : MariaDB + Target Server Version : 100338 (10.3.38-MariaDB) + File Encoding : 65001 + + Date: 29/08/2024 17:21:06 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for kpi_c_title +-- ---------------------------- +DROP TABLE IF EXISTS `kpi_c_title`; +CREATE TABLE `kpi_c_title` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ne_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `kpi_id` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `expression` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `unit` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `status` enum('Active','Inactive','Deleted') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'Active' COMMENT 'enum:Active/Inactive/Deleted', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `created_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `updated_at` datetime NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_ne_kpi_id`(`ne_type`, `kpi_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/install/sys_dict_data0.sql b/database/install/sys_dict_data0.sql index 389c24f9..eca436b7 100644 --- a/database/install/sys_dict_data0.sql +++ b/database/install/sys_dict_data0.sql @@ -49,36 +49,36 @@ INSERT INTO `sys_dict_data` VALUES (21, 6, 'dictData.operType.export', '5', 'sys INSERT INTO `sys_dict_data` VALUES (22, 7, 'dictData.operType.import', '6', 'sys_oper_type', NULL, 'orange', '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (23, 8, 'dictData.operType.forced quit', '7', 'sys_oper_type', NULL, 'default', '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (24, 9, 'dictData.operType.clear', '8', 'sys_oper_type', NULL, '#f50', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (25, 1, 'dictData.trace.interface', 'Interface', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (26, 2, 'dictData.trace.device', 'Device', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (27, 3, 'dictData.trace.user', 'UE', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (28, 1, 'dictData.logType.download', 'DOWNLOAD', 'operation_log_type', NULL, 'pink', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (29, 2, 'dictData.logType.activation', 'Activation', 'operation_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (30, 3, 'dictData.logType.add', 'ADD', 'operation_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (31, 4, 'dictData.logType.other', 'AUTO', 'operation_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (32, 5, 'dictData.logType.back', 'BACK', 'operation_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (33, 6, 'dictData.logType.delete', 'DELETE', 'operation_log_type', NULL, 'red', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (34, 7, 'dictData.logType.distribute', 'Distribute', 'operation_log_type', NULL, 'yellow', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (35, 8, 'dictData.logType.export', 'EXPORT', 'operation_log_type', NULL, 'green', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (36, 9, 'dictData.logType.query', 'SELECT', 'operation_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (37, 10, 'dictData.logType.setup', 'SET', 'operation_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (38, 11, 'dictData.logType.update', 'UPDATE', 'operation_log_type', NULL, 'magenta', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (39, 12, 'dictData.logType.upload', 'UPLOAD', 'operation_log_type', NULL, 'yellow', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (40, 13, 'dictData.logType.view', 'View', 'operation_log_type', NULL, 'purple', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (41, 14, 'dictData.logType.login', '0', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (42, 15, 'dictData.logType.logout', '1', 'security_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (43, 1, 'dictData.securityLogType.add', '2', 'security_log_type', NULL, 'green', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (44, 2, 'dictData.securityLogType.update', '3', 'security_log_type', NULL, 'lime', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (45, 3, 'dictData.securityLogType.delete', '4', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (46, 4, 'dictData.securityLogType.lock', '5', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (47, 5, 'dictData.securityLogType.unlock', '6', 'security_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (48, 6, 'dictData.securityLogType.reset', '7', 'security_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (49, 7, 'dictData.securityLogType.deactivate', '8', 'security_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (25, 1, 'dictData.trace.interface', '1', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (26, 2, 'dictData.trace.device', '2', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (27, 3, 'dictData.trace.user', '3', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (28, 1, 'dictData.logType.download', 'DOWNLOAD', 'operation_log_type', NULL, 'pink', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (29, 2, 'dictData.logType.activation', 'Activation', 'operation_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (30, 3, 'dictData.logType.add', 'ADD', 'operation_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (31, 4, 'dictData.logType.other', 'AUTO', 'operation_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (32, 5, 'dictData.logType.back', 'BACK', 'operation_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (33, 6, 'dictData.logType.delete', 'DELETE', 'operation_log_type', NULL, 'red', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (34, 7, 'dictData.logType.distribute', 'Distribute', 'operation_log_type', NULL, 'yellow', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (35, 8, 'dictData.logType.export', 'EXPORT', 'operation_log_type', NULL, 'green', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (36, 9, 'dictData.logType.query', 'SELECT', 'operation_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (37, 10, 'dictData.logType.setup', 'SET', 'operation_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (38, 11, 'dictData.logType.update', 'UPDATE', 'operation_log_type', NULL, 'magenta', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (39, 12, 'dictData.logType.upload', 'UPLOAD', 'operation_log_type', NULL, 'yellow', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (40, 13, 'dictData.logType.view', 'View', 'operation_log_type', NULL, 'purple', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (41, 14, 'dictData.logType.login', '0', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (42, 15, 'dictData.logType.logout', '1', 'security_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (43, 1, 'dictData.securityLogType.add', '2', 'security_log_type', NULL, 'green', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (44, 2, 'dictData.securityLogType.update', '3', 'security_log_type', NULL, 'lime', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (45, 3, 'dictData.securityLogType.delete', '4', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (46, 4, 'dictData.securityLogType.lock', '5', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (47, 5, 'dictData.securityLogType.unlock', '6', 'security_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (48, 6, 'dictData.securityLogType.reset', '7', 'security_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (49, 7, 'dictData.securityLogType.deactivate', '8', 'security_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (50, 8, 'dictData.jobSaveLog.no', '0', 'sys_job_save_log', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (51, 9, 'dictData.jobSaveLog.yes', '1', 'sys_job_save_log', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (52, 1, 'dictData.neVersionStatus.upload', 'Uploaded', 'ne_version_status', NULL, 'processing', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (53, 2, 'dictData.neVersionStatus.inactive', 'Inactive', 'ne_version_status', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (54, 3, 'dictData.neVersionStatus.active', 'Active', 'ne_version_status', NULL, 'success', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (52, 1, 'dictData.neVersionStatus.upload', 'Uploaded', 'ne_version_status', NULL, 'processing', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (53, 2, 'dictData.neVersionStatus.inactive', 'Inactive', 'ne_version_status', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (54, 3, 'dictData.neVersionStatus.active', 'Active', 'ne_version_status', NULL, 'success', '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (55, 1, 'dictData.alarmStatus.history', '0', 'alarm_status', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (56, 2, 'dictData.alarmStatus.active', '1', 'alarm_status', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (57, 1, 'dictData.datascope.all', '1', 'sys_role_datascope', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); @@ -153,10 +153,21 @@ INSERT INTO `sys_dict_data` VALUES (125, 0, 'dictData.ne_version_status.0', '0', INSERT INTO `sys_dict_data` VALUES (126, 1, 'dictData.ne_version_status.1', '1', 'ne_version_status', '', 'success', '1', 'supervisor', 1706620000000, 'supervisor', 1712720201349, ''); INSERT INTO `sys_dict_data` VALUES (127, 1, 'dictData.ne_version_status.2', '2', 'ne_version_status', '', 'purple', '1', 'supervisor', 1706620000000, 'supervisor', 1712720201349, ''); INSERT INTO `sys_dict_data` VALUES (128, 1, 'dictData.ne_version_status.3', '3', 'ne_version_status', '', 'processing', '1', 'supervisor', 1706620000000, 'supervisor', 1712720201349, ''); --- INSERT INTO `sys_dict_data` VALUES (129, 0, 'dictData.udm_sub_cn_type.0', '0', 'udm_sub_cn_type', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); --- INSERT INTO `sys_dict_data` VALUES (130, 1, 'dictData.udm_sub_cn_type.1', '1', 'udm_sub_cn_type', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); --- INSERT INTO `sys_dict_data` VALUES (131, 2, 'dictData.udm_sub_cn_type.2', '2', 'udm_sub_cn_type', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); --- INSERT INTO `sys_dict_data` VALUES (132, 3, 'dictData.udm_sub_cn_type.3', '3', 'udm_sub_cn_type', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (129, 0, 'dictData.cdr_cause_code.0', '0', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (130, 1, 'dictData.cdr_cause_code.8', '8', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (131, 2, 'dictData.cdr_cause_code.10', '10', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (132, 10, 'dictData.cdr_cause_code.21', '21', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (133, 11, 'dictData.cdr_cause_code.22', '22', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (134, 12, 'dictData.cdr_cause_code.27', '27', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (135, 13, 'dictData.cdr_cause_code.28', '28', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (136, 14, 'dictData.cdr_cause_code.29', '29', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (137, 15, 'dictData.cdr_cause_code.30', '30', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (138, 16, 'dictData.cdr_cause_code.38', '38', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (139, 20, 'dictData.cdr_cause_code.41', '41', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (140, 21, 'dictData.cdr_cause_code.41', '41', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (141, 22, 'dictData.cdr_cause_code.42', '42', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (142, 23, 'dictData.cdr_cause_code.47', '47', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (143, 30, 'dictData.cdr_cause_code.50', '50', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); -- 多租户 INSERT INTO `sys_dict_data` VALUES (10000, 10000, 'dictData.tenancy.imsi', 'IMSI', 'tenancy_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); diff --git a/database/install/sys_dict_data1_i18n_zh.sql b/database/install/sys_dict_data1_i18n_zh.sql index 0b70ecde..5fb94e44 100644 --- a/database/install/sys_dict_data1_i18n_zh.sql +++ b/database/install/sys_dict_data1_i18n_zh.sql @@ -188,28 +188,28 @@ INSERT INTO `sys_dict_data` VALUES (1423, 1423, 'dictData.operType.clear', '清 INSERT INTO `sys_dict_data` VALUES (1424, 1424, 'dictData.trace.interface', '接口跟踪', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1425, 1425, 'dictData.trace.device', '设备跟踪', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1426, 1426, 'dictData.trace.user', '用户跟踪', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1427, 1427, 'dictData.logType.download', '下载', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1428, 1428, 'dictData.logType.activation', '激活', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1429, 1429, 'dictData.logType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1430, 1430, 'dictData.logType.other', '其他', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1431, 1431, 'dictData.logType.back', '回退', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1432, 1432, 'dictData.logType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1433, 1433, 'dictData.logType.distribute', '分配', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1434, 1434, 'dictData.logType.export', '导出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1435, 1435, 'dictData.logType.query', '查询', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1436, 1436, 'dictData.logType.setup', '设置', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1437, 1437, 'dictData.logType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1438, 1438, 'dictData.logType.upload', '上传', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1439, 1439, 'dictData.logType.view', '查看', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1440, 1440, 'dictData.logType.login', '登录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1441, 1441, 'dictData.logType.logout', '登出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1442, 1442, 'dictData.securityLogType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1443, 1443, 'dictData.securityLogType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1444, 1444, 'dictData.securityLogType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1445, 1445, 'dictData.securityLogType.lock', '锁定', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1446, 1446, 'dictData.securityLogType.unlock', '解锁', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1447, 1447, 'dictData.securityLogType.reset', '重置', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1448, 1448, 'dictData.securityLogType.deactivate', '停用', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1427, 1427, 'dictData.logType.download', '下载', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1428, 1428, 'dictData.logType.activation', '激活', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1429, 1429, 'dictData.logType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1430, 1430, 'dictData.logType.other', '其他', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1431, 1431, 'dictData.logType.back', '回退', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1432, 1432, 'dictData.logType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1433, 1433, 'dictData.logType.distribute', '分配', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1434, 1434, 'dictData.logType.export', '导出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1435, 1435, 'dictData.logType.query', '查询', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1436, 1436, 'dictData.logType.setup', '设置', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1437, 1437, 'dictData.logType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1438, 1438, 'dictData.logType.upload', '上传', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1439, 1439, 'dictData.logType.view', '查看', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1440, 1440, 'dictData.logType.login', '登录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1441, 1441, 'dictData.logType.logout', '登出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1442, 1442, 'dictData.securityLogType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1443, 1443, 'dictData.securityLogType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1444, 1444, 'dictData.securityLogType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1445, 1445, 'dictData.securityLogType.lock', '锁定', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1446, 1446, 'dictData.securityLogType.unlock', '解锁', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1447, 1447, 'dictData.securityLogType.reset', '重置', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1448, 1448, 'dictData.securityLogType.deactivate', '停用', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1449, 1449, 'dictData.jobSaveLog.no', '不记录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1450, 1450, 'dictData.jobSaveLog.yes', '记录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1451, 1451, 'dictData.neVersionStatus.upload', '已上传', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -239,9 +239,9 @@ INSERT INTO `sys_dict_data` VALUES (1505, 1505, 'dictType.sys_yes_no', '系统 INSERT INTO `sys_dict_data` VALUES (1506, 1506, 'dictType.sys_oper_type', '操作类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1507, 1507, 'dictType.sys_common_status', '系统状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1508, 1508, 'dictType.trace_type', '跟踪类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1509, 1509, 'dictType.operation_log_type', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1509, 1509, 'dictType.operation_log_type', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1510, 1510, 'dictType.alarm_status', '告警日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1511, 1511, 'dictType.security_log_type', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1511, 1511, 'dictType.security_log_type', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1512, 1512, 'dictType.ne_version_status', '网元软件版本状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1513, 1513, 'dictType.i18n_en', '多语言-英文', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1514, 1514, 'dictType.i18n_zh', '多语言-中文', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -254,9 +254,9 @@ INSERT INTO `sys_dict_data` VALUES (1520, 1520, 'dictType.sys_yes_no_remark', ' INSERT INTO `sys_dict_data` VALUES (1521, 1521, 'dictType.sys_oper_type_remark', '操作类型列表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1522, 1522, 'dictType.sys_common_status_remark', '登录状态列表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1523, 1523, 'dictType.trace_type_remark', '跟踪类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1524, 1524, 'dictType.operation_log_type_remark', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1524, 1524, 'dictType.operation_log_type_remark', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1525, 1525, 'dictType.alarm_status_remark', '告警日志状态类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (1526, 1526, 'dictType.security_log_type_remark', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (1526, 1526, 'dictType.security_log_type_remark', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1527, 1527, 'dictType.ne_version_status_remark', '网元软件版本状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1528, 1528, 'dictType.i18n_en_remark', 'Internationalization - English', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1529, 1529, 'dictType.i18n_zh_remark', 'Internationalization - Chinese', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -671,6 +671,24 @@ INSERT INTO `sys_dict_data` VALUES (2160, 2160, 'table.sys_log_operate', '操作 INSERT INTO `sys_dict_data` VALUES (2161, 2161, 'table.cdr_event_ims', '语音话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (2162, 2162, 'table.cdr_event_smf', '数据话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (2163, 2163, 'table.cdr_event_smsc', '短信话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2164, 2164, 'menu.log.exportFile', '导出文件管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2165, 2165, 'menu.perf.kpiCReport', '自定义指标数据', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2166, 2166, 'menu.trace.taskHLR', '跟踪任务 HLR', 'i18n_zh', '', '', '1', 'supervisor', 1726626822538, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2167, 2167, 'dictType.cdr_cause_code', 'CDR 响应原因代码类别类型', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2168, 2168, 'dictData.cdr_cause_code.0', '其他', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2169, 2169, 'dictData.cdr_cause_code.8', '运营者要求禁止', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2170, 2170, 'dictData.cdr_cause_code.10', '呼叫禁止', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2171, 2171, 'dictData.cdr_cause_code.21', '短信传输拒绝', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2172, 2172, 'dictData.cdr_cause_code.22', '内存超限', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2173, 2173, 'dictData.cdr_cause_code.27', '目的地出错', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2174, 2174, 'dictData.cdr_cause_code.28', '用户身份不明', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2175, 2175, 'dictData.cdr_cause_code.29', '功能拒绝错误', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2176, 2176, 'dictData.cdr_cause_code.30', '未知用户', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2177, 2177, 'dictData.cdr_cause_code.38', '网络出错', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2178, 2178, 'dictData.cdr_cause_code.41', '临时错误', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2179, 2179, 'dictData.cdr_cause_code.42', '拥塞', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2180, 2180, 'dictData.cdr_cause_code.47', '资源不可用', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2181, 2181, 'dictData.cdr_cause_code.50', '请求的设施未订阅', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); -- 多租户 INSERT INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -714,5 +732,4 @@ INSERT INTO `sys_dict_data` VALUES (11037, 11000, 'tenant.errHasChildUse', '操 INSERT INTO `sys_dict_data` VALUES (11038, 11000, 'tenant.errHasUserUse', '不允许删除,租户已分配用户数:{num}', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (11039, 11000, 'tenant.errAssetExists', '租赁资产[{type}:{key}]与现有的资产有冲突', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); - SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/install/sys_dict_data2_i18n_en.sql b/database/install/sys_dict_data2_i18n_en.sql index 9af59384..d095a8b7 100644 --- a/database/install/sys_dict_data2_i18n_en.sql +++ b/database/install/sys_dict_data2_i18n_en.sql @@ -121,7 +121,7 @@ INSERT INTO `sys_dict_data` VALUES (3113, 3113, 'menu.perf.data', 'Performance D INSERT INTO `sys_dict_data` VALUES (3114, 3114, 'menu.perf.report', 'Performance Reports', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3115, 3115, 'menu.perf.threshold', 'Performance Thresholds', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3116, 3116, 'menu.perf.kpi', 'Key Performance Indicators', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3117, 3117, 'menu.perf.customTarget', 'Custom Metrics', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (3117, 3117, 'menu.perf.customTarget', 'Custom Indicator Management', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3118, 3118, 'menu.perf.set', 'Performance General Settings', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3119, 3119, 'menu.mml', 'MML', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3120, 3120, 'menu.mml.ne', 'NE Operation', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -133,7 +133,7 @@ INSERT INTO `sys_dict_data` VALUES (3125, 3125, 'menu.perf.dataRemark', 'Perform INSERT INTO `sys_dict_data` VALUES (3126, 3126, 'menu.perf.reportRemark', 'Performance Report Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); 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 Metrics 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 (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); @@ -188,28 +188,28 @@ INSERT INTO `sys_dict_data` VALUES (3423, 3423, 'dictData.operType.clear', 'Clea INSERT INTO `sys_dict_data` VALUES (3424, 3424, 'dictData.trace.interface', 'Interface Tracing', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3425, 3425, 'dictData.trace.device', 'Module Tracing', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3426, 3426, 'dictData.trace.user', 'User Tracing', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3427, 3427, 'dictData.logType.download', 'Download', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3428, 3428, 'dictData.logType.activation', 'Activation', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3429, 3429, 'dictData.logType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3430, 3430, 'dictData.logType.other', 'Other', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3431, 3431, 'dictData.logType.back', 'Rollback', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3432, 3432, 'dictData.logType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3433, 3433, 'dictData.logType.distribute', 'Assign', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3434, 3434, 'dictData.logType.export', 'Export', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3435, 3435, 'dictData.logType.query', 'Query', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3436, 3436, 'dictData.logType.setup', 'Setup', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3437, 3437, 'dictData.logType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3438, 3438, 'dictData.logType.upload', 'Upload', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3439, 3439, 'dictData.logType.view', 'View', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3440, 3440, 'dictData.logType.login', 'Login', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3441, 3441, 'dictData.logType.logout', 'Logout', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3442, 3442, 'dictData.securityLogType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3443, 3443, 'dictData.securityLogType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3444, 3444, 'dictData.securityLogType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3445, 3445, 'dictData.securityLogType.lock', 'Locked', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3446, 3446, 'dictData.securityLogType.unlock', 'Unlock', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3447, 3447, 'dictData.securityLogType.reset', 'Reset', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3448, 3448, 'dictData.securityLogType.deactivate', 'Deactivate', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3427, 3427, 'dictData.logType.download', 'Download', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3428, 3428, 'dictData.logType.activation', 'Activation', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3429, 3429, 'dictData.logType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3430, 3430, 'dictData.logType.other', 'Other', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3431, 3431, 'dictData.logType.back', 'Rollback', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3432, 3432, 'dictData.logType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3433, 3433, 'dictData.logType.distribute', 'Assign', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3434, 3434, 'dictData.logType.export', 'Export', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3435, 3435, 'dictData.logType.query', 'Query', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3436, 3436, 'dictData.logType.setup', 'Setup', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3437, 3437, 'dictData.logType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3438, 3438, 'dictData.logType.upload', 'Upload', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3439, 3439, 'dictData.logType.view', 'View', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3440, 3440, 'dictData.logType.login', 'Login', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3441, 3441, 'dictData.logType.logout', 'Logout', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3442, 3442, 'dictData.securityLogType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3443, 3443, 'dictData.securityLogType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3444, 3444, 'dictData.securityLogType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3445, 3445, 'dictData.securityLogType.lock', 'Locked', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3446, 3446, 'dictData.securityLogType.unlock', 'Unlock', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3447, 3447, 'dictData.securityLogType.reset', 'Reset', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3448, 3448, 'dictData.securityLogType.deactivate', 'Deactivate', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3449, 3449, 'dictData.jobSaveLog.no', 'No Record', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3450, 3450, 'dictData.jobSaveLog.yes', 'Recorded', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3451, 3451, 'dictData.neVersionStatus.upload', 'Uploaded', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -239,12 +239,12 @@ INSERT INTO `sys_dict_data` VALUES (3505, 3505, 'dictType.sys_yes_no', 'System o INSERT INTO `sys_dict_data` VALUES (3506, 3506, 'dictType.sys_oper_type', 'Operation Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3507, 3507, 'dictType.sys_common_status', 'System Status', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3508, 3508, 'dictType.trace_type', 'Trace Types', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3509, 3509, 'dictType.operation_log_type', 'Operation Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3509, 3509, 'dictType.operation_log_type', 'Operation Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3510, 3510, 'dictType.alarm_status', 'Alarm Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3511, 3511, 'dictType.security_log_type', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3511, 3511, 'dictType.security_log_type', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3512, 3512, 'dictType.ne_version_status', 'Network element software version status', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3513, 3513, 'dictType.i18n_en', 'Multi-language - English', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3514, 3514, 'dictType.i18n_zh', 'Multi-language - Chinese', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (3514, 3514, 'dictType.i18n_en', 'Multi-language - Chinese', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3515, 3515, 'dictType.sys_user_sex_remark', 'User gender list', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3516, 3516, 'dictType.sys_show_hide_remark', 'Menu Status List', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3517, 3517, 'dictType.sys_normal_disable_remark', 'System switch list', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -254,12 +254,12 @@ INSERT INTO `sys_dict_data` VALUES (3520, 3520, 'dictType.sys_yes_no_remark', 'S INSERT INTO `sys_dict_data` VALUES (3521, 3521, 'dictType.sys_oper_type_remark', 'Operation type list', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3522, 3522, 'dictType.sys_common_status_remark', 'Login Status List', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3523, 3523, 'dictType.trace_type_remark', 'Trace Types', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3524, 3524, 'dictType.operation_log_type_remark', 'Operation log type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3524, 3524, 'dictType.operation_log_type_remark', 'Operation log type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3525, 3525, 'dictType.alarm_status_remark', 'Alarm Log Status Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3526, 3526, 'dictType.security_log_type_remark', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- INSERT INTO `sys_dict_data` VALUES (3526, 3526, 'dictType.security_log_type_remark', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3527, 3527, 'dictType.ne_version_status_remark', 'Network element software version status', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3528, 3528, 'dictType.i18n_en_remark', 'Internationalization - English', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3529, 3529, 'dictType.i18n_zh_remark', 'Internationalization - Chinese', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (3529, 3529, 'dictType.i18n_en_remark', 'Internationalization - Chinese', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3530, 3530, 'dictType.export.id', 'Dictionary Number', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3531, 3531, 'dictType.export.name', 'Dictionary Name', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3532, 3532, 'dictType.export.type', 'Dictionary Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -325,7 +325,7 @@ INSERT INTO `sys_dict_data` VALUES (3705, 3705, 'job.deleteExpiredAlarmRecordRem INSERT INTO `sys_dict_data` VALUES (3706, 3706, 'job.deleteExpiredKpiRecord', 'Delete expired KPI records', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3707, 3707, 'job.deleteExpiredKpiRecordRemark', 'KPI record retention for {duration} days', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3708, 3708, 'job.backupEtcFromNE', 'Network Element Configuration Auto Backup Task', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3709, 3709, 'job.backupEtcFromNERemark', 'Automatically backs up the configuration files in the network element\'s etc directory.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (3709, 3709, 'job.backupEtcFromNERemark', 'Automatically backs up the configuration files in the NE etc directory.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3710, 3710, 'job.export.jobID', 'ID', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3711, 3711, 'job.export.jobName', 'Name', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3712, 3712, 'job.export.jobGroupName', 'Group', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -444,7 +444,7 @@ INSERT INTO `sys_dict_data` VALUES (3933, 3933, 'log.login.export.browser', 'Bro INSERT INTO `sys_dict_data` VALUES (3934, 3934, 'log.login.export.os', 'Operating System', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3935, 3935, 'log.login.export.msg', 'Login Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3936, 3936, 'log.login.export.time', 'Login Time', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT INTO `sys_dict_data` VALUES (3937, 3937, 'trace.tcpdump.noData', 'Can\'t find {type} {id} information of the corresponding network element.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (3937, 3937, 'trace.tcpdump.noData', 'Can it find {type} {id} information of the corresponding network element.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3938, 3938, 'register.errUsername', 'The account number cannot start with a number, but can contain upper and lower case letters, numbers, and not less than 5 digits.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3939, 3939, 'register.errPasswd', 'The password must contain at least 6 upper and lower case letters, numbers, and special symbols.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3940, 3940, 'register.errPasswdNotEq', 'User confirms password inconsistency', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -671,6 +671,24 @@ INSERT INTO `sys_dict_data` VALUES (4160, 4160, 'table.sys_log_operate', 'Operat INSERT INTO `sys_dict_data` VALUES (4161, 4161, 'table.cdr_event_ims', 'Voice CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (4162, 4162, 'table.cdr_event_smf', 'Data CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (4163, 4163, 'table.cdr_event_smsc', 'SMS CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4164, 4164, 'menu.log.exportFile', 'Exported File Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4165, 4165, 'menu.perf.kpiCReport', 'Custom Indicator Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4166, 4166, 'menu.trace.taskHLR', 'Tracking Tasks HLR', 'i18n_en', '', '', '1', 'supervisor', 1726626822538, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4167, 4167, 'dictType.cdr_cause_code', 'CDR Response Reason Code Category Type', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4168, 4168, 'dictData.cdr_cause_code.0', 'Other', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4169, 4169, 'dictData.cdr_cause_code.8', 'OPERATOR_DETERMINED_BARRING', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4170, 4170, 'dictData.cdr_cause_code.10', 'CALL_BARRED', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4171, 4171, 'dictData.cdr_cause_code.21', 'SM Trans Reject', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4172, 4172, 'dictData.cdr_cause_code.22', 'Memory Exceeded', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4173, 4173, 'dictData.cdr_cause_code.27', 'Destination Out Order', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4174, 4174, 'dictData.cdr_cause_code.28', 'Unidentified Subscriber', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4175, 4175, 'dictData.cdr_cause_code.29', 'Facility Reject Error', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4176, 4176, 'dictData.cdr_cause_code.30', 'Unknown Subscriber', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4177, 4177, 'dictData.cdr_cause_code.38', 'Network Out Order', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4178, 4178, 'dictData.cdr_cause_code.41', 'Temp Fail', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4179, 4179, 'dictData.cdr_cause_code.42', 'Congestion', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4180, 4180, 'dictData.cdr_cause_code.47', 'Resources Unavailable Unspec', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4181, 4181, 'dictData.cdr_cause_code.50', 'Requested Facility Not Subscribed', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); -- 多租户 INSERT INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); diff --git a/database/install/sys_dict_type.sql b/database/install/sys_dict_type.sql index f9d0cf4f..333680f0 100644 --- a/database/install/sys_dict_type.sql +++ b/database/install/sys_dict_type.sql @@ -32,9 +32,9 @@ INSERT INTO `sys_dict_type` VALUES (6, 'dictType.sys_yes_no', 'sys_yes_no', '1', INSERT INTO `sys_dict_type` VALUES (9, 'dictType.sys_oper_type', 'sys_oper_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.sys_oper_type_remark'); INSERT INTO `sys_dict_type` VALUES (10, 'dictType.sys_common_status', 'sys_common_status', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.sys_common_status_remark'); INSERT INTO `sys_dict_type` VALUES (100, 'dictType.trace_type', 'trace_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.trace_type_remark'); -INSERT INTO `sys_dict_type` VALUES (101, 'dictType.operation_log_type', 'operation_log_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.operation_log_type_remark'); +-- INSERT INTO `sys_dict_type` VALUES (101, 'dictType.operation_log_type', 'operation_log_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.operation_log_type_remark'); INSERT INTO `sys_dict_type` VALUES (102, 'dictType.alarm_status', 'alarm_status', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.alarm_status_remark'); -INSERT INTO `sys_dict_type` VALUES (103, 'dictType.security_log_type', 'security_log_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.security_log_type_remark'); +-- INSERT INTO `sys_dict_type` VALUES (103, 'dictType.security_log_type', 'security_log_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.security_log_type_remark'); INSERT INTO `sys_dict_type` VALUES (104, 'dictType.ne_version_status', 'ne_version_status', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.ne_version_status_remark'); INSERT INTO `sys_dict_type` VALUES (105, 'dictType.i18n_en', 'i18n_en', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.i18n_en_remark'); INSERT INTO `sys_dict_type` VALUES (106, 'dictType.i18n_zh', 'i18n_zh', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.i18n_zh_remark'); @@ -55,7 +55,7 @@ INSERT INTO `sys_dict_type` VALUES (120, 'dictType.ne_host_authMode', 'ne_host_a INSERT INTO `sys_dict_type` VALUES (121, 'dictType.ne_host_cmd_groupId', 'ne_host_cmd_groupId', '1', 'supervisor', 1702020000000, '', 0, ''); INSERT INTO `sys_dict_type` VALUES (122, 'dictType.ne_info_status', 'ne_info_status', '1', 'supervisor', 1702020000000, '', 0, ''); INSERT INTO `sys_dict_type` VALUES (123, 'dictType.ne_license_status', 'ne_license_status', '1', 'supervisor', 1702020000000, '', 0, ''); --- INSERT INTO `sys_dict_type` VALUES (124, 'dictType.udm_sub_cn_type', 'udm_sub_cn_type', '1', 'supervisor', 1702020000000, '', 0, ''); +INSERT INTO `sys_dict_type` VALUES (124, 'dictType.cdr_cause_code', 'cdr_cause_code', '1', 'supervisor', 1725877564156, '', 0, ''); -- Multi-tenancy INSERT INTO `sys_dict_type` VALUES (10000, 'dictType.tenancy_type', 'tenancy_type', '1', 'supervisor', 1702020000000, '', 0, ''); diff --git a/database/install/sys_menu.sql b/database/install/sys_menu.sql index f7db8d58..11bd5d2e 100644 --- a/database/install/sys_menu.sql +++ b/database/install/sys_menu.sql @@ -140,14 +140,14 @@ INSERT INTO `sys_menu` VALUES (2092, 'menu.log.alarm', 2089, 40, 'alarm-log', 'l 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 (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', '1', '1', 'faultManage/fault-setting/index', 'icon-gonggaodayi', 'supervisor', 1700000000000, NULL, 0, 'menu.fault.setRemark'); +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'); INSERT INTO `sys_menu` VALUES (2100, 'menu.perf.task', 2099, 1, 'taskManage', 'perfManage/taskManage/index', '1', '1', 'M', '0', '1', 'perfManage:taskManage:index', 'icon-wofaqi', 'supervisor', 1700000000000, 'admin', 1713177036412, 'menu.perf.taskRemark'); INSERT INTO `sys_menu` VALUES (2101, 'menu.perf.data', 2099, 2, 'perfData', 'perfManage/perfData/index', '1', '1', 'M', '0', '1', 'perfManage:perfData:index', 'icon-soutubiao', 'supervisor', 1700000000000, 'admin', 1713177042915, 'menu.perf.dataRemark'); INSERT INTO `sys_menu` VALUES (2102, 'menu.perf.report', 2099, 3, 'perfReport', 'perfManage/perfReport/index', '1', '0', 'M', '0', '0', 'perfManage:perfReport:index', 'icon-gonggaodayi', 'supervisor', 1700000000000, NULL, 0, 'menu.perf.reportRemark'); INSERT INTO `sys_menu` VALUES (2103, 'menu.perf.threshold', 2099, 4, 'perfThreshold', 'perfManage/perfThreshold/index', '1', '0', 'M', '0', '0', 'perfManage:perfThreshold:index', 'icon-zhuanrang', 'supervisor', 1700000000000, 'supervisor', 1715417264697, 'menu.perf.thresholdRemark'); INSERT INTO `sys_menu` VALUES (2104, 'menu.perf.kpi', 2099, 5, 'goldTarget', 'perfManage/goldTarget/index', '1', '1', 'M', '1', '1', 'perfManage:goldTarget:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.perf.kpiRemark'); -INSERT INTO `sys_menu` VALUES (2105, 'menu.perf.customTarget', 2099, 6, 'customTarget', 'perfManage/customTarget/index', '1', '1', 'M', '0', '0', 'perfManage:customTarget:index', 'icon-fanhui1', 'supervisor', 1700000000000, 'admin', 1712807948673, 'menu.perf.customTargetRemark'); +INSERT INTO `sys_menu` VALUES (2105, 'menu.perf.customTarget', 2099, 6, 'customTarget', 'perfManage/customTarget/index', '1', '1', 'M', '1', '1', 'perfManage:customTarget:index', 'icon-fanhui1', 'supervisor', 1700000000000, 'admin', 1712807948673, 'menu.perf.customTargetRemark'); INSERT INTO `sys_menu` VALUES (2106, 'menu.perf.set', 2099, 7, 'perfSet', 'perfManage/perfSet/index', '1', '0', 'M', '0', '0', 'perfManage:perfSet:index', 'icon-gonggao', 'supervisor', 1700000000000, NULL, 0, 'menu.perf.setRemark'); INSERT INTO `sys_menu` VALUES (2107, 'menu.mml', 0, 8, 'mmlManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-zhizuoliucheng', 'supervisor', 1700000000000, NULL, 0, 'menu.mmlRemark'); INSERT INTO `sys_menu` VALUES (2108, 'menu.mml.ne', 2107, 1, 'neOperate', 'mmlManage/neOperate/index', '1', '1', 'M', '1', '1', 'mmlManage:neOperate:index', 'icon-huizhiguize', 'supervisor', 1700000000000, NULL, 0, 'menu.mml.neRemark'); @@ -197,6 +197,9 @@ INSERT INTO `sys_menu` VALUES (2155, 'menu.common.delete', 2154, 1, '#', '', '1' INSERT INTO `sys_menu` VALUES (2156, 'menu.common.edit', 2154, 2, '#', '', '1', '1', 'B', '1', '1', 'ne:neConfigBackup:edit', '#', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_menu` VALUES (2157, 'menu.dashboard.smscCDR', 2140, 9, 'smscCDR', 'dashboard/smscCDR/index', '1', '0', 'M', '1', '1', 'dashboard:cdr:index', 'icon-paixu', 'supervisor', 1723107637982, 'supervisor', 1723107637982, ''); INSERT INTO `sys_menu` VALUES (2158, 'menu.trace.pcapFile', 2083, 4, 'pcap/inline/file', 'traceManage/pcap/file', '1', '1', 'M', '0', '1', 'traceManage:pcap:index', '#', 'supervisor', 1724144595914, '', 0, ''); +INSERT INTO `sys_menu` VALUES (2159, 'menu.log.exportFile', 2089, 100, 'exportFile', 'logManage/exportFile/index', '1', '1', 'M', '1', '1', 'logManage:exportFile:index', 'icon-wenjian', 'supervisor', 1724144595914, '', 0, ''); +INSERT INTO `sys_menu` VALUES (2160, 'menu.perf.kpiCReport', 2099, 100, 'kpiCReport', 'perfManage/kpiCReport/index', '1', '1', 'M', '1', '1', 'perfManage:kpiCReport:index', 'icon-tubiaoku', 'supervisor', 1724144595914, '', 0, ''); +INSERT INTO `sys_menu` VALUES (2161, 'menu.trace.taskHLR', 2083, 10, 'taskHLR', 'traceManage/task-hlr/index', '1', '0', 'M', '1', '1', 'traceManage:taskHLR:index', 'icon-gengduo', 'supervisor', 1724144595914, '', 0, ''); -- tenant management for admin user INSERT INTO `sys_menu` VALUES (10000, 'menu.security.tenant', 2113, 5, 'tenant', 'system/tenant/index', '1', '1', 'M', '1', '1', 'system:tenant:list', 'icon-yuzhanghao1', 'supervisor', 1700000000000, NULL, 0, 'menu.security.tenantRemark'); diff --git a/database/install/sys_role_menu.sql b/database/install/sys_role_menu.sql index 2776938e..eefaa171 100644 --- a/database/install/sys_role_menu.sql +++ b/database/install/sys_role_menu.sql @@ -160,6 +160,8 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2155); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2156); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2157); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2158); +INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2159); +INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2160); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 1); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 4); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 5); @@ -182,8 +184,6 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2080); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2081); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2082); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2083); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2084); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2085); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2086); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2087); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2088); @@ -194,26 +194,17 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2094); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2097); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2098); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2099); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2100); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2101); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2102); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2103); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2104); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2105); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2106); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2107); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2108); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2109); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2111); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2113); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2118); +INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2114); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2119); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2120); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2123); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2124); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2125); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2126); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2127); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2128); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2129); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2130); @@ -225,6 +216,7 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2138); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2140); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2141); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2143); +INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2146); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2147); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2148); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2149); diff --git a/database/install/trace_data.sql b/database/install/trace_data.sql index e840e17e..2cf29ab6 100644 --- a/database/install/trace_data.sql +++ b/database/install/trace_data.sql @@ -1,52 +1,24 @@ --- MariaDB dump 10.19 Distrib 10.6.16-MariaDB, for debian-linux-gnu (x86_64) --- --- Host: 192.168.2.219 Database: omc_db --- ------------------------------------------------------ --- Server version 10.3.38-MariaDB - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8mb4 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - -- -- Table structure for table `trace_data` -- DROP TABLE IF EXISTS `trace_data`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; + CREATE TABLE `trace_data` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `task_id` int(11) DEFAULT NULL, - `imsi` varchar(16) DEFAULT NULL, - `msisdn` varchar(16) DEFAULT NULL, - `src_addr` varchar(128) DEFAULT NULL, - `dst_addr` varchar(128) DEFAULT NULL, - `if_type` int(11) DEFAULT 0, - `msg_type` int(11) DEFAULT NULL, - `msg_direct` int(11) DEFAULT NULL, - `length` int(11) DEFAULT NULL, - `timestamp` bigint(20) DEFAULT NULL, - `raw_msg` blob DEFAULT NULL, - `dec_msg` blob DEFAULT NULL, + `id` int NOT NULL AUTO_INCREMENT, + `task_id` int NOT NULL COMMENT '跟踪任务ID', + `imsi` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '', + `msisdn` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '', + `src_addr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '源地址带端口', + `dst_addr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '目标地址带端口', + `if_type` int DEFAULT NULL COMMENT '接口类型,未分类', + `msg_type` int DEFAULT NULL, + `msg_direct` int DEFAULT NULL, + `length` int DEFAULT NULL COMMENT '去除头后的原始数据byte长度', + `timestamp` bigint DEFAULT '0' COMMENT '毫秒', + `raw_msg` text COLLATE utf8mb4_general_ci COMMENT '去除头后的原始数据byteBase64', + `dec_msg` text COLLATE utf8mb4_general_ci COMMENT 'TCP内容消息', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=311486 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='跟踪_任务数据'; -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2024-03-06 17:26:59 +-- Dump completed on 2024-09-19 14:26:59 diff --git a/database/install/trace_task.sql b/database/install/trace_task.sql index 7de1d8fb..1e009e1d 100644 --- a/database/install/trace_task.sql +++ b/database/install/trace_task.sql @@ -1,60 +1,31 @@ --- MariaDB dump 10.19 Distrib 10.6.16-MariaDB, for debian-linux-gnu (x86_64) --- --- Host: 192.168.2.219 Database: omc_db --- ------------------------------------------------------ --- Server version 10.3.38-MariaDB - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8mb4 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `trace_task` -- DROP TABLE IF EXISTS `trace_task`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; + CREATE TABLE `trace_task` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `trace_type` enum('Interface','Device','UE') DEFAULT NULL, - `start_time` datetime DEFAULT NULL, - `end_time` datetime DEFAULT NULL, - `imsi` varchar(16) DEFAULT NULL, - `msisdn` varchar(16) DEFAULT NULL, - `src_ip` varchar(50) DEFAULT NULL, - `dst_ip` varchar(50) DEFAULT NULL, - `signal_port` smallint(6) DEFAULT NULL, - `spc` varchar(30) DEFAULT NULL, - `dpc` varchar(30) DEFAULT NULL, - `ne_type` varchar(32) DEFAULT NULL, - `ne_id` varchar(32) DEFAULT NULL, - `ue_ip` varchar(50) DEFAULT NULL, - `interfaces` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, - `status` enum('Inactive','Active','Failed') DEFAULT 'Inactive', - `account_id` varchar(32) DEFAULT NULL, - `comment` varchar(255) DEFAULT NULL, - `succ_nes` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, - `fail_nes` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, - `update_time` datetime DEFAULT current_timestamp(), + `id` int NOT NULL AUTO_INCREMENT COMMENT '跟踪任务ID', + `trace_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '1-Interface,2-Device,3-User', + `start_time` bigint DEFAULT '0' COMMENT '开始时间 毫秒', + `end_time` bigint DEFAULT '0' COMMENT '结束时间 毫秒', + `ue_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '设备跟踪必须 IP', + `interfaces` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '' COMMENT '接口跟踪必须 例如 N8,N10', + `imsi` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户跟踪必须', + `msisdn` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户跟踪可选', + `src_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '源地址IP', + `dst_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '目标地址IP', + `signal_port` int DEFAULT '0' COMMENT '地址IP端口', + `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` bigint DEFAULT '0' COMMENT '创建时间', + `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` bigint DEFAULT '0' COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '' COMMENT '备注', + `ne_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '网元类型', + `ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '网元ID', + `notify_url` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '信息数据通知回调地址UDP 例如udp:192.168.5.58:29500', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=89 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='跟踪_任务'; -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2024-03-06 17:26:59 +-- Dump completed on 2024-09-19 14:26:59 diff --git a/database/install/trace_task_hlr.sql b/database/install/trace_task_hlr.sql new file mode 100644 index 00000000..a84cd918 --- /dev/null +++ b/database/install/trace_task_hlr.sql @@ -0,0 +1,24 @@ +-- +-- Table structure for table `trace_task_hlr` +-- + +DROP TABLE IF EXISTS `trace_task_hlr`; + +CREATE TABLE `trace_task_hlr` ( + `id` int NOT NULL AUTO_INCREMENT, + `trace_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '任务编号', + `imsi` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'IMSI', + `msisdn` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'MSISDN', + `start_time` bigint DEFAULT '0' COMMENT '开始时间', + `end_time` bigint DEFAULT '0' COMMENT '结束时间', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '任务状态(0停止 1进行)', + `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '任务信息', + `remark` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '备注说明', + `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '创建者', + `create_time` bigint DEFAULT '0' COMMENT '创建时间', + `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者', + `update_time` bigint DEFAULT '0' COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='跟踪_任务给HRL网元'; + +-- Dump completed on 2024-09-19 14:26:59 diff --git a/database/install/u_auth_user.sql b/database/install/u_auth_user.sql index 7f7ad262..f4d0ef48 100644 --- a/database/install/u_auth_user.sql +++ b/database/install/u_auth_user.sql @@ -1,49 +1,20 @@ --- MariaDB dump 10.19 Distrib 10.6.16-MariaDB, for debian-linux-gnu (x86_64) --- --- Host: 192.168.2.219 Database: omc_db --- ------------------------------------------------------ --- Server version 10.3.38-MariaDB - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8mb4 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - -- -- Table structure for table `u_auth_user` -- DROP TABLE IF EXISTS `u_auth_user`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; + CREATE TABLE `u_auth_user` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', - `msisdn` varchar(16) DEFAULT NULL COMMENT '相当手机号', - `imsi` varchar(50) DEFAULT NULL COMMENT 'SIM卡号', - `amf` varchar(50) DEFAULT NULL COMMENT 'AMF', - `status` varchar(50) DEFAULT NULL COMMENT '状态', - `ki` varchar(50) DEFAULT NULL COMMENT 'ki', - `algo_index` varchar(50) DEFAULT NULL COMMENT 'algoIndex', - `opc` varchar(50) DEFAULT NULL COMMENT 'OPC', - `ne_id` varchar(50) DEFAULT NULL COMMENT 'UDM网元标识-子系统', + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', + `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM卡/USIM卡ID', + `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'UDM网元标识', + `amf` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'AMF', + `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '状态', + `ki` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'ki', + `algo_index` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'algoIndex', + `opc` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'OPC', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_neid唯一主键' -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='UDM鉴权用户'; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='UDM鉴权用户'; -- Dump completed on 2024-03-06 17:26:59 diff --git a/database/install/u_sub_user.sql b/database/install/u_sub_user.sql index 944ed750..8e77213d 100644 --- a/database/install/u_sub_user.sql +++ b/database/install/u_sub_user.sql @@ -1,18 +1,6 @@ -/* - Navicat Premium Data Transfer - - Source Server : root@192.168.2.166 - Source Server Type : MariaDB - Source Server Version : 100616 (10.6.16-MariaDB-0ubuntu0.22.04.1) - Source Host : 192.168.2.166:33066 - Source Schema : tenants_db - - Target Server Type : MariaDB - Target Server Version : 100616 (10.6.16-MariaDB-0ubuntu0.22.04.1) - File Encoding : 65001 - - Date: 19/06/2024 14:30:41 -*/ +-- +-- Table structure for table `u_sub_user` +-- SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; @@ -20,36 +8,33 @@ SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for u_sub_user -- ---------------------------- -DROP TABLE IF EXISTS `u_sub_user`; -CREATE TABLE `u_sub_user` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', - `msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '相当手机号', - `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'SIM卡号', - `ambr` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'SubUeAMBRTemp', - `nssai` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'SubSNSSAITemp', - `rat` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'rat', - `arfb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'forbiddenAreasTemp', - `sar` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'serviceAreaRestrictTemp', - `cn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'cnType', - `sm_data` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'smData', - `smf_sel` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'smfSel', - `eps_dat` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Eps', - `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'UDM网元标识-子系统', - `eps_flag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'epsFlag', - `eps_odb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'epsOdb', - `hplmn_odb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'hplmnOdb', - `ard` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Ard', - `epstpl` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Epstpl', - `context_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ContextId', - `apn_context` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'apnContext', - `static_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'staticIpstatic_ip指给4G UE分配的静态IP,没有可不带此字段名', +DROP TABLE IF EXISTS `u_sub_user`; +CREATE TABLE `u_sub_user` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', + `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM卡/USIM卡ID', + `msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户电话号码', + `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'UDM网元标识', + `ambr` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'SubUeAMBRTemp', + `nssai` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'SubSNSSAITemp', + `rat` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'rat VIRTUAL|WLAN|EUTRA|NR', + `arfb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'forbiddenAreasTemp', + `sar` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'serviceAreaRestrictTemp', + `cn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'cnType EPC|5GC', + `sm_data` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'smData', + `smf_sel` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'smfSel', + `eps_dat` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Eps', + `eps_flag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'epsFlag', + `eps_odb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'epsOdb', + `hplmn_odb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'hplmnOdb', + `ard` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Ard', + `epstpl` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Epstpl', + `context_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'ContextId', + `apn_context` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'apnContext', + `static_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'staticIpstatic_ip指给4G UE分配的静态IP,没有可不带此字段名', + `cag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'CAG', `tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'multi-tenancy refer to sys_tenant.tenant_id', PRIMARY KEY (`id`) USING BTREE, - UNIQUE INDEX `imsi_ne`(`imsi`, `ne_id`) USING BTREE COMMENT 'imsi_ne唯一索引' -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM签约用户' ROW_FORMAT = Dynamic; - --- ---------------------------- --- Records of u_sub_user --- ---------------------------- + UNIQUE KEY `imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_ne唯一索引' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='UDM签约用户'; SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/install/u_user_info.sql b/database/install/u_user_info.sql new file mode 100644 index 00000000..23a06d2e --- /dev/null +++ b/database/install/u_user_info.sql @@ -0,0 +1,17 @@ +-- +-- Table structure for table `u_user_info` +-- + +DROP TABLE IF EXISTS `u_user_info`; + +CREATE TABLE `u_user_info` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '默认ID', + `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM卡/USIM卡ID', + `msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户电话号码', + `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'UDM网元标识', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_ne唯一索引' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='UDM用户IMSI扩展信息'; + +-- Dump completed on 2024-09-19 11:26:59 diff --git a/database/upgrade/upg_function.sql b/database/upgrade/upg_function.sql index 3c426344..1fb14ece 100644 --- a/database/upgrade/upg_function.sql +++ b/database/upgrade/upg_function.sql @@ -1,16 +1,17 @@ -DELIMITER / / +DELIMITER // CREATE FUNCTION IF NOT EXISTS omc_get_dict_value(field_value VARCHAR(255), type VARCHAR(255)) -RETURNS VARCHAR(255) +RETURNS VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci DETERMINISTIC BEGIN DECLARE result VARCHAR(255); SELECT `dict_value` INTO result -FROM `sys_dict_data` -WHERE `dict_label` = field_value AND `dict_type` = type limit 1; +FROM `sys_dict_data` +WHERE `dict_label` = field_value AND `dict_type` = type +LIMIT 1; RETURN result; END // -DELIMITER; \ No newline at end of file +DELIMITER ; diff --git a/database/upgrade/upg_kpi_c_report.sql b/database/upgrade/upg_kpi_c_report.sql new file mode 100644 index 00000000..d4166f33 --- /dev/null +++ b/database/upgrade/upg_kpi_c_report.sql @@ -0,0 +1,40 @@ +/* + 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: 29/08/2024 14:53:38 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for kpi_c_report_upf +-- ---------------------------- +CREATE TABLE IF NOT EXISTS `kpi_c_report` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ne_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `ne_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '', + `rm_uid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `date` date NOT NULL, + `start_time` time NULL DEFAULT NULL, + `end_time` time NULL DEFAULT NULL, + `index` smallint(6) NOT NULL, + `granularity` tinyint(4) NULL DEFAULT 60 COMMENT 'Time granualarity: 5/10/.../60/300 (second)', + `kpi_values` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL, + `created_at` timestamp NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_timestamp`(`created_at`) USING BTREE, + INDEX `idx_uid_datetime`(`rm_uid`, `date`, `start_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 654904 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/upgrade/upg_kpi_c_title.sql b/database/upgrade/upg_kpi_c_title.sql new file mode 100644 index 00000000..a3f3158a --- /dev/null +++ b/database/upgrade/upg_kpi_c_title.sql @@ -0,0 +1,38 @@ +/* + 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 : omc_db + + Target Server Type : MariaDB + Target Server Version : 100338 (10.3.38-MariaDB) + File Encoding : 65001 + + Date: 29/08/2024 17:21:06 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for kpi_c_title +-- ---------------------------- +CREATE TABLE IF NOT EXISTS `kpi_c_title` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ne_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `kpi_id` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `expression` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `unit` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `status` enum('Active','Inactive','Deleted') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'Active' COMMENT 'enum:Active/Inactive/Deleted', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `created_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, + `updated_at` datetime NULL DEFAULT current_timestamp(), + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_ne_kpi_id`(`ne_type`, `kpi_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/upgrade/upg_sys_dict_data0.sql b/database/upgrade/upg_sys_dict_data0.sql index 25b67191..125aa3e2 100644 --- a/database/upgrade/upg_sys_dict_data0.sql +++ b/database/upgrade/upg_sys_dict_data0.sql @@ -49,36 +49,36 @@ INSERT IGNORE INTO `sys_dict_data` VALUES (21, 6, 'dictData.operType.export', '5 INSERT IGNORE INTO `sys_dict_data` VALUES (22, 7, 'dictData.operType.import', '6', 'sys_oper_type', NULL, 'orange', '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (23, 8, 'dictData.operType.forced quit', '7', 'sys_oper_type', NULL, 'default', '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (24, 9, 'dictData.operType.clear', '8', 'sys_oper_type', NULL, '#f50', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (25, 1, 'dictData.trace.interface', 'Interface', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (26, 2, 'dictData.trace.device', 'Device', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (27, 3, 'dictData.trace.user', 'UE', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (28, 1, 'dictData.logType.download', 'DOWNLOAD', 'operation_log_type', NULL, 'pink', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (29, 2, 'dictData.logType.activation', 'Activation', 'operation_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (30, 3, 'dictData.logType.add', 'ADD', 'operation_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (31, 4, 'dictData.logType.other', 'AUTO', 'operation_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (32, 5, 'dictData.logType.back', 'BACK', 'operation_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (33, 6, 'dictData.logType.delete', 'DELETE', 'operation_log_type', NULL, 'red', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (34, 7, 'dictData.logType.distribute', 'Distribute', 'operation_log_type', NULL, 'yellow', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (35, 8, 'dictData.logType.export', 'EXPORT', 'operation_log_type', NULL, 'green', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (36, 9, 'dictData.logType.query', 'SELECT', 'operation_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (37, 10, 'dictData.logType.setup', 'SET', 'operation_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (38, 11, 'dictData.logType.update', 'UPDATE', 'operation_log_type', NULL, 'magenta', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (39, 12, 'dictData.logType.upload', 'UPLOAD', 'operation_log_type', NULL, 'yellow', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (40, 13, 'dictData.logType.view', 'View', 'operation_log_type', NULL, 'purple', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (41, 14, 'dictData.logType.login', '0', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (42, 15, 'dictData.logType.logout', '1', 'security_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (43, 1, 'dictData.securityLogType.add', '2', 'security_log_type', NULL, 'green', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (44, 2, 'dictData.securityLogType.update', '3', 'security_log_type', NULL, 'lime', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (45, 3, 'dictData.securityLogType.delete', '4', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (46, 4, 'dictData.securityLogType.lock', '5', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (47, 5, 'dictData.securityLogType.unlock', '6', 'security_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (48, 6, 'dictData.securityLogType.reset', '7', 'security_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (49, 7, 'dictData.securityLogType.deactivate', '8', 'security_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +INSERT IGNORE INTO `sys_dict_data` VALUES (25, 1, 'dictData.trace.interface', '1', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +INSERT IGNORE INTO `sys_dict_data` VALUES (26, 2, 'dictData.trace.device', '2', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +INSERT IGNORE INTO `sys_dict_data` VALUES (27, 3, 'dictData.trace.user', '3', 'trace_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (28, 1, 'dictData.logType.download', 'DOWNLOAD', 'operation_log_type', NULL, 'pink', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (29, 2, 'dictData.logType.activation', 'Activation', 'operation_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (30, 3, 'dictData.logType.add', 'ADD', 'operation_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (31, 4, 'dictData.logType.other', 'AUTO', 'operation_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (32, 5, 'dictData.logType.back', 'BACK', 'operation_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (33, 6, 'dictData.logType.delete', 'DELETE', 'operation_log_type', NULL, 'red', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (34, 7, 'dictData.logType.distribute', 'Distribute', 'operation_log_type', NULL, 'yellow', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (35, 8, 'dictData.logType.export', 'EXPORT', 'operation_log_type', NULL, 'green', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (36, 9, 'dictData.logType.query', 'SELECT', 'operation_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (37, 10, 'dictData.logType.setup', 'SET', 'operation_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (38, 11, 'dictData.logType.update', 'UPDATE', 'operation_log_type', NULL, 'magenta', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (39, 12, 'dictData.logType.upload', 'UPLOAD', 'operation_log_type', NULL, 'yellow', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (40, 13, 'dictData.logType.view', 'View', 'operation_log_type', NULL, 'purple', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (41, 14, 'dictData.logType.login', '0', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (42, 15, 'dictData.logType.logout', '1', 'security_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (43, 1, 'dictData.securityLogType.add', '2', 'security_log_type', NULL, 'green', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (44, 2, 'dictData.securityLogType.update', '3', 'security_log_type', NULL, 'lime', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (45, 3, 'dictData.securityLogType.delete', '4', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (46, 4, 'dictData.securityLogType.lock', '5', 'security_log_type', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (47, 5, 'dictData.securityLogType.unlock', '6', 'security_log_type', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (48, 6, 'dictData.securityLogType.reset', '7', 'security_log_type', NULL, 'cyan', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (49, 7, 'dictData.securityLogType.deactivate', '8', 'security_log_type', NULL, 'blue ', '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (50, 8, 'dictData.jobSaveLog.no', '0', 'sys_job_save_log', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (51, 9, 'dictData.jobSaveLog.yes', '1', 'sys_job_save_log', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (52, 1, 'dictData.neVersionStatus.upload', 'Uploaded', 'ne_version_status', NULL, 'processing', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (53, 2, 'dictData.neVersionStatus.inactive', 'Inactive', 'ne_version_status', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (54, 3, 'dictData.neVersionStatus.active', 'Active', 'ne_version_status', NULL, 'success', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (52, 1, 'dictData.neVersionStatus.upload', 'Uploaded', 'ne_version_status', NULL, 'processing', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (53, 2, 'dictData.neVersionStatus.inactive', 'Inactive', 'ne_version_status', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL); +-- INSERT IGNORE INTO `sys_dict_data` VALUES (54, 3, 'dictData.neVersionStatus.active', 'Active', 'ne_version_status', NULL, 'success', '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (55, 1, 'dictData.alarmStatus.history', '0', 'alarm_status', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (56, 2, 'dictData.alarmStatus.active', '1', 'alarm_status', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (57, 1, 'dictData.datascope.all', '1', 'sys_role_datascope', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL); @@ -153,10 +153,22 @@ INSERT IGNORE INTO `sys_dict_data` VALUES (125, 0, 'dictData.ne_version_status.0 INSERT IGNORE INTO `sys_dict_data` VALUES (126, 1, 'dictData.ne_version_status.1', '1', 'ne_version_status', '', 'success', '1', 'supervisor', 1706620000000, 'supervisor', 1712720201349, ''); INSERT IGNORE INTO `sys_dict_data` VALUES (127, 1, 'dictData.ne_version_status.2', '2', 'ne_version_status', '', 'purple', '1', 'supervisor', 1706620000000, 'supervisor', 1712720201349, ''); INSERT IGNORE INTO `sys_dict_data` VALUES (128, 1, 'dictData.ne_version_status.3', '3', 'ne_version_status', '', 'processing', '1', 'supervisor', 1706620000000, 'supervisor', 1712720201349, ''); --- INSERT IGNORE INTO `sys_dict_data` VALUES (129, 0, 'dictData.udm_sub_cn_type.0', '0', 'udm_sub_cn_type', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); --- INSERT IGNORE INTO `sys_dict_data` VALUES (130, 1, 'dictData.udm_sub_cn_type.1', '1', 'udm_sub_cn_type', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); --- INSERT IGNORE INTO `sys_dict_data` VALUES (131, 2, 'dictData.udm_sub_cn_type.2', '2', 'udm_sub_cn_type', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); --- INSERT IGNORE INTO `sys_dict_data` VALUES (132, 3, 'dictData.udm_sub_cn_type.3', '3', 'udm_sub_cn_type', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (129, 0, 'dictData.cdr_cause_code.0', '0', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (130, 1, 'dictData.cdr_cause_code.8', '8', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (131, 2, 'dictData.cdr_cause_code.10', '10', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (132, 10, 'dictData.cdr_cause_code.21', '21', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (133, 11, 'dictData.cdr_cause_code.22', '22', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (134, 12, 'dictData.cdr_cause_code.27', '27', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (135, 13, 'dictData.cdr_cause_code.28', '28', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (136, 14, 'dictData.cdr_cause_code.29', '29', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (137, 15, 'dictData.cdr_cause_code.30', '30', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (138, 16, 'dictData.cdr_cause_code.38', '38', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (139, 20, 'dictData.cdr_cause_code.41', '41', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (140, 21, 'dictData.cdr_cause_code.41', '41', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (141, 22, 'dictData.cdr_cause_code.42', '42', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (142, 23, 'dictData.cdr_cause_code.47', '47', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); +INSERT IGNORE INTO `sys_dict_data` VALUES (143, 30, 'dictData.cdr_cause_code.50', '50', 'cdr_cause_code', '', '', '1', 'supervisor', 1712720201349, '', 0, ''); + -- 指定记录条件更新 diff --git a/database/upgrade/upg_sys_dict_data1_i18n_zh.sql b/database/upgrade/upg_sys_dict_data1_i18n_zh.sql index ff062f2e..c7e02075 100644 --- a/database/upgrade/upg_sys_dict_data1_i18n_zh.sql +++ b/database/upgrade/upg_sys_dict_data1_i18n_zh.sql @@ -195,28 +195,28 @@ REPLACE INTO `sys_dict_data` VALUES (1423, 1423, 'dictData.operType.clear', '清 REPLACE INTO `sys_dict_data` VALUES (1424, 1424, 'dictData.trace.interface', '接口跟踪', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1425, 1425, 'dictData.trace.device', '设备跟踪', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1426, 1426, 'dictData.trace.user', '用户跟踪', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1427, 1427, 'dictData.logType.download', '下载', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1428, 1428, 'dictData.logType.activation', '激活', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1429, 1429, 'dictData.logType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1430, 1430, 'dictData.logType.other', '其他', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1431, 1431, 'dictData.logType.back', '回退', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1432, 1432, 'dictData.logType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1433, 1433, 'dictData.logType.distribute', '分配', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1434, 1434, 'dictData.logType.export', '导出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1435, 1435, 'dictData.logType.query', '查询', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1436, 1436, 'dictData.logType.setup', '设置', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1437, 1437, 'dictData.logType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1438, 1438, 'dictData.logType.upload', '上传', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1439, 1439, 'dictData.logType.view', '查看', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1440, 1440, 'dictData.logType.login', '登录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1441, 1441, 'dictData.logType.logout', '登出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1442, 1442, 'dictData.securityLogType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1443, 1443, 'dictData.securityLogType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1444, 1444, 'dictData.securityLogType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1445, 1445, 'dictData.securityLogType.lock', '锁定', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1446, 1446, 'dictData.securityLogType.unlock', '解锁', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1447, 1447, 'dictData.securityLogType.reset', '重置', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1448, 1448, 'dictData.securityLogType.deactivate', '停用', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1427, 1427, 'dictData.logType.download', '下载', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1428, 1428, 'dictData.logType.activation', '激活', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1429, 1429, 'dictData.logType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1430, 1430, 'dictData.logType.other', '其他', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1431, 1431, 'dictData.logType.back', '回退', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1432, 1432, 'dictData.logType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1433, 1433, 'dictData.logType.distribute', '分配', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1434, 1434, 'dictData.logType.export', '导出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1435, 1435, 'dictData.logType.query', '查询', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1436, 1436, 'dictData.logType.setup', '设置', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1437, 1437, 'dictData.logType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1438, 1438, 'dictData.logType.upload', '上传', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1439, 1439, 'dictData.logType.view', '查看', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1440, 1440, 'dictData.logType.login', '登录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1441, 1441, 'dictData.logType.logout', '登出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1442, 1442, 'dictData.securityLogType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1443, 1443, 'dictData.securityLogType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1444, 1444, 'dictData.securityLogType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1445, 1445, 'dictData.securityLogType.lock', '锁定', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1446, 1446, 'dictData.securityLogType.unlock', '解锁', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1447, 1447, 'dictData.securityLogType.reset', '重置', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1448, 1448, 'dictData.securityLogType.deactivate', '停用', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1449, 1449, 'dictData.jobSaveLog.no', '不记录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1450, 1450, 'dictData.jobSaveLog.yes', '记录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1451, 1451, 'dictData.neVersionStatus.upload', '已上传', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -246,9 +246,9 @@ REPLACE INTO `sys_dict_data` VALUES (1505, 1505, 'dictType.sys_yes_no', '系统 REPLACE INTO `sys_dict_data` VALUES (1506, 1506, 'dictType.sys_oper_type', '操作类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1507, 1507, 'dictType.sys_common_status', '系统状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1508, 1508, 'dictType.trace_type', '跟踪类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1509, 1509, 'dictType.operation_log_type', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1509, 1509, 'dictType.operation_log_type', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1510, 1510, 'dictType.alarm_status', '告警日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1511, 1511, 'dictType.security_log_type', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1511, 1511, 'dictType.security_log_type', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1512, 1512, 'dictType.ne_version_status', '网元软件版本状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1513, 1513, 'dictType.i18n_en', '多语言-英文', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1514, 1514, 'dictType.i18n_zh', '多语言-中文', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -261,9 +261,9 @@ REPLACE INTO `sys_dict_data` VALUES (1520, 1520, 'dictType.sys_yes_no_remark', ' REPLACE INTO `sys_dict_data` VALUES (1521, 1521, 'dictType.sys_oper_type_remark', '操作类型列表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1522, 1522, 'dictType.sys_common_status_remark', '登录状态列表', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1523, 1523, 'dictType.trace_type_remark', '跟踪类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1524, 1524, 'dictType.operation_log_type_remark', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1524, 1524, 'dictType.operation_log_type_remark', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1525, 1525, 'dictType.alarm_status_remark', '告警日志状态类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (1526, 1526, 'dictType.security_log_type_remark', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (1526, 1526, 'dictType.security_log_type_remark', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1527, 1527, 'dictType.ne_version_status_remark', '网元软件版本状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1528, 1528, 'dictType.i18n_en_remark', 'Internationalization - English', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1529, 1529, 'dictType.i18n_zh_remark', 'Internationalization - Chinese', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -678,6 +678,24 @@ REPLACE INTO `sys_dict_data` VALUES (2160, 2160, 'table.sys_log_operate', '操 REPLACE INTO `sys_dict_data` VALUES (2161, 2161, 'table.cdr_event_ims', '语音话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2162, 2162, 'table.cdr_event_smf', '数据话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2163, 2163, 'table.cdr_event_smsc', '短信话单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2164, 2164, 'menu.log.exportFile', '导出文件管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2165, 2165, 'menu.perf.kpiCReport', '自定义指标数据', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2166, 2166, 'menu.trace.taskHLR', '跟踪任务 HLR', 'i18n_zh', '', '', '1', 'supervisor', 1726626822538, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2167, 2167, 'dictType.cdr_cause_code', 'CDR 响应原因代码类别类型', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2168, 2168, 'dictData.cdr_cause_code.0', '其他', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2169, 2169, 'dictData.cdr_cause_code.8', '运营者要求禁止', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2170, 2170, 'dictData.cdr_cause_code.10', '呼叫禁止', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2171, 2171, 'dictData.cdr_cause_code.21', '短信传输拒绝', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2172, 2172, 'dictData.cdr_cause_code.22', '内存超限', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2173, 2173, 'dictData.cdr_cause_code.27', '目的地出错', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2174, 2174, 'dictData.cdr_cause_code.28', '用户身份不明', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2175, 2175, 'dictData.cdr_cause_code.29', '功能拒绝错误', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2176, 2176, 'dictData.cdr_cause_code.30', '未知用户', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2177, 2177, 'dictData.cdr_cause_code.38', '网络出错', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2178, 2178, 'dictData.cdr_cause_code.41', '临时错误', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2179, 2179, 'dictData.cdr_cause_code.42', '拥塞', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2180, 2180, 'dictData.cdr_cause_code.47', '资源不可用', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2181, 2181, 'dictData.cdr_cause_code.50', '请求的设施未订阅', 'i18n_zh', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); -- multi-tenancy REPLACE INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); diff --git a/database/upgrade/upg_sys_dict_data2_i18n_en.sql b/database/upgrade/upg_sys_dict_data2_i18n_en.sql index 6bb9a2c8..c90d9861 100644 --- a/database/upgrade/upg_sys_dict_data2_i18n_en.sql +++ b/database/upgrade/upg_sys_dict_data2_i18n_en.sql @@ -126,7 +126,7 @@ REPLACE INTO `sys_dict_data` VALUES (3113, 3113, 'menu.perf.data', 'Performance REPLACE INTO `sys_dict_data` VALUES (3114, 3114, 'menu.perf.report', 'Performance Reports', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3115, 3115, 'menu.perf.threshold', 'Performance Thresholds', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3116, 3116, 'menu.perf.kpi', 'Key Performance Indicators', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3117, 3117, 'menu.perf.customTarget', 'Custom Metrics', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (3117, 3117, 'menu.perf.customTarget', 'Custom Indicator Management', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3118, 3118, 'menu.perf.set', 'Performance General Settings', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3119, 3119, 'menu.mml', 'MML', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3120, 3120, 'menu.mml.ne', 'NE Operation', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -138,7 +138,7 @@ REPLACE INTO `sys_dict_data` VALUES (3125, 3125, 'menu.perf.dataRemark', 'Perfor REPLACE INTO `sys_dict_data` VALUES (3126, 3126, 'menu.perf.reportRemark', 'Performance Report Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); 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 Metrics 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 (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); @@ -189,28 +189,28 @@ REPLACE INTO `sys_dict_data` VALUES (3423, 3423, 'dictData.operType.clear', 'Cle REPLACE INTO `sys_dict_data` VALUES (3424, 3424, 'dictData.trace.interface', 'Interface Tracing', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3425, 3425, 'dictData.trace.device', 'Module Tracing', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3426, 3426, 'dictData.trace.user', 'User Tracing', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3427, 3427, 'dictData.logType.download', 'Download', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3428, 3428, 'dictData.logType.activation', 'Activation', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3429, 3429, 'dictData.logType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3430, 3430, 'dictData.logType.other', 'Other', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3431, 3431, 'dictData.logType.back', 'Rollback', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3432, 3432, 'dictData.logType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3433, 3433, 'dictData.logType.distribute', 'Assign', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3434, 3434, 'dictData.logType.export', 'Export', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3435, 3435, 'dictData.logType.query', 'Query', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3436, 3436, 'dictData.logType.setup', 'Setup', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3437, 3437, 'dictData.logType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3438, 3438, 'dictData.logType.upload', 'Upload', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3439, 3439, 'dictData.logType.view', 'View', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3440, 3440, 'dictData.logType.login', 'Login', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3441, 3441, 'dictData.logType.logout', 'Logout', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3442, 3442, 'dictData.securityLogType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3443, 3443, 'dictData.securityLogType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3444, 3444, 'dictData.securityLogType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3445, 3445, 'dictData.securityLogType.lock', 'Locked', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3446, 3446, 'dictData.securityLogType.unlock', 'Unlock', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3447, 3447, 'dictData.securityLogType.reset', 'Reset', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3448, 3448, 'dictData.securityLogType.deactivate', 'Deactivate', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3427, 3427, 'dictData.logType.download', 'Download', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3428, 3428, 'dictData.logType.activation', 'Activation', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3429, 3429, 'dictData.logType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3430, 3430, 'dictData.logType.other', 'Other', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3431, 3431, 'dictData.logType.back', 'Rollback', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3432, 3432, 'dictData.logType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3433, 3433, 'dictData.logType.distribute', 'Assign', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3434, 3434, 'dictData.logType.export', 'Export', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3435, 3435, 'dictData.logType.query', 'Query', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3436, 3436, 'dictData.logType.setup', 'Setup', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3437, 3437, 'dictData.logType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3438, 3438, 'dictData.logType.upload', 'Upload', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3439, 3439, 'dictData.logType.view', 'View', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3440, 3440, 'dictData.logType.login', 'Login', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3441, 3441, 'dictData.logType.logout', 'Logout', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3442, 3442, 'dictData.securityLogType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3443, 3443, 'dictData.securityLogType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3444, 3444, 'dictData.securityLogType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3445, 3445, 'dictData.securityLogType.lock', 'Locked', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3446, 3446, 'dictData.securityLogType.unlock', 'Unlock', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3447, 3447, 'dictData.securityLogType.reset', 'Reset', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3448, 3448, 'dictData.securityLogType.deactivate', 'Deactivate', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3449, 3449, 'dictData.jobSaveLog.no', 'No Record', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3450, 3450, 'dictData.jobSaveLog.yes', 'Recorded', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3451, 3451, 'dictData.neVersionStatus.upload', 'Uploaded', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -240,9 +240,9 @@ REPLACE INTO `sys_dict_data` VALUES (3505, 3505, 'dictType.sys_yes_no', 'System REPLACE INTO `sys_dict_data` VALUES (3506, 3506, 'dictType.sys_oper_type', 'Operation Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3507, 3507, 'dictType.sys_common_status', 'System Status', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3508, 3508, 'dictType.trace_type', 'Trace Types', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3509, 3509, 'dictType.operation_log_type', 'Operation Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3509, 3509, 'dictType.operation_log_type', 'Operation Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3510, 3510, 'dictType.alarm_status', 'Alarm Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3511, 3511, 'dictType.security_log_type', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3511, 3511, 'dictType.security_log_type', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3512, 3512, 'dictType.ne_version_status', 'Network element software version status', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3513, 3513, 'dictType.i18n_en', 'Multi-language - English', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3514, 3514, 'dictType.i18n_zh', 'Multi-language - Chinese', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -255,9 +255,9 @@ REPLACE INTO `sys_dict_data` VALUES (3520, 3520, 'dictType.sys_yes_no_remark', ' REPLACE INTO `sys_dict_data` VALUES (3521, 3521, 'dictType.sys_oper_type_remark', 'Operation type list', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3522, 3522, 'dictType.sys_common_status_remark', 'Login Status List', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3523, 3523, 'dictType.trace_type_remark', 'Trace Types', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3524, 3524, 'dictType.operation_log_type_remark', 'Operation log type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3524, 3524, 'dictType.operation_log_type_remark', 'Operation log type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3525, 3525, 'dictType.alarm_status_remark', 'Alarm Log Status Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3526, 3526, 'dictType.security_log_type_remark', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +-- REPLACE INTO `sys_dict_data` VALUES (3526, 3526, 'dictType.security_log_type_remark', 'Security Log Type', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3527, 3527, 'dictType.ne_version_status_remark', 'Network element software version status', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3528, 3528, 'dictType.i18n_en_remark', 'Internationalization - English', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3529, 3529, 'dictType.i18n_zh_remark', 'Internationalization - Chinese', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -326,7 +326,7 @@ REPLACE INTO `sys_dict_data` VALUES (3705, 3705, 'job.deleteExpiredAlarmRecordRe REPLACE INTO `sys_dict_data` VALUES (3706, 3706, 'job.deleteExpiredKpiRecord', 'Delete expired KPI records', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3707, 3707, 'job.deleteExpiredKpiRecordRemark', 'KPI record retention for {duration} days', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3708, 3708, 'job.backupEtcFromNE', 'Network Element Configuration Auto Backup Task', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3709, 3709, 'job.backupEtcFromNERemark', 'Automatically backs up the configuration files in the network element\'s etc directory.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (3709, 3709, 'job.backupEtcFromNERemark', 'Automatically backs up the configuration files in the NE etc directory.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3710, 3710, 'job.export.jobID', 'ID', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3711, 3711, 'job.export.jobName', 'Name', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3712, 3712, 'job.export.jobGroupName', 'Group', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -446,7 +446,7 @@ REPLACE INTO `sys_dict_data` VALUES (3933, 3933, 'log.login.export.browser', 'Br REPLACE INTO `sys_dict_data` VALUES (3934, 3934, 'log.login.export.os', 'Operating System', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3935, 3935, 'log.login.export.msg', 'Login Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3936, 3936, 'log.login.export.time', 'Login Time', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -REPLACE INTO `sys_dict_data` VALUES (3937, 3937, 'trace.tcpdump.noData', 'Can\'t find {type} {id} information of the corresponding network element.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (3937, 3937, 'trace.tcpdump.noData', 'Can it find {type} {id} information of the corresponding network element.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3938, 3938, 'register.errUsername', 'The account number cannot start with a number, but can contain upper and lower case letters, numbers, and not less than 5 digits.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3939, 3939, 'register.errPasswd', 'The password must contain at least 6 upper and lower case letters, numbers, and special symbols.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3940, 3940, 'register.errPasswdNotEq', 'User confirms password inconsistency', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -673,7 +673,24 @@ REPLACE INTO `sys_dict_data` VALUES (4160, 4160, 'table.sys_log_operate', 'Opera REPLACE INTO `sys_dict_data` VALUES (4161, 4161, 'table.cdr_event_ims', 'Voice CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4162, 4162, 'table.cdr_event_smf', 'Data CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4163, 4163, 'table.cdr_event_smsc', 'SMS CDR', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); - +REPLACE INTO `sys_dict_data` VALUES (4164, 4164, 'menu.log.exportFile', 'Exported File Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4165, 4165, 'menu.perf.kpiCReport', 'Custom Indicator Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4166, 4166, 'menu.trace.taskHLR', 'Tracking Tasks HLR', 'i18n_en', '', '', '1', 'supervisor', 1726626822538, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4167, 4167, 'dictType.cdr_cause_code', 'CDR Response Reason Code Category Type', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4168, 4168, 'dictData.cdr_cause_code.0', 'Other', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4169, 4169, 'dictData.cdr_cause_code.8', 'OPERATOR_DETERMINED_BARRING', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4170, 4170, 'dictData.cdr_cause_code.10', 'CALL_BARRED', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4171, 4171, 'dictData.cdr_cause_code.21', 'SM Trans Reject', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4172, 4172, 'dictData.cdr_cause_code.22', 'Memory Exceeded', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4173, 4173, 'dictData.cdr_cause_code.27', 'Destination Out Order', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4174, 4174, 'dictData.cdr_cause_code.28', 'Unidentified Subscriber', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4175, 4175, 'dictData.cdr_cause_code.29', 'Facility Reject Error', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4176, 4176, 'dictData.cdr_cause_code.30', 'Unknown Subscriber', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4177, 4177, 'dictData.cdr_cause_code.38', 'Network Out Order', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4178, 4178, 'dictData.cdr_cause_code.41', 'Temp Fail', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4179, 4179, 'dictData.cdr_cause_code.42', 'Congestion', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4180, 4180, 'dictData.cdr_cause_code.47', 'Resources Unavailable Unspec', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4181, 4181, 'dictData.cdr_cause_code.50', 'Requested Facility Not Subscribed', 'i18n_en', '', '', '1', 'supervisor', 1725877564156, '', 0, ''); -- 多租户 REPLACE INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); @@ -717,5 +734,4 @@ REPLACE INTO `sys_dict_data` VALUES (14037, 14000, 'tenant.errHasChildUse', 'Ope REPLACE INTO `sys_dict_data` VALUES (14038, 14000, 'tenant.errHasUserUse', 'Deletion is not allowed, number of users the tenant has been assigned to: {num}', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (14039, 14000, 'tenant.errAssetExists', 'There is a conflict between tenancy asset[{type}:{key}] and a existing asset', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); - SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/upgrade/upg_sys_dict_type.sql b/database/upgrade/upg_sys_dict_type.sql index 82e5ebf8..1f2793b7 100644 --- a/database/upgrade/upg_sys_dict_type.sql +++ b/database/upgrade/upg_sys_dict_type.sql @@ -30,9 +30,9 @@ INSERT IGNORE INTO `sys_dict_type` VALUES (6, 'dictType.sys_yes_no', 'sys_yes_no INSERT IGNORE INTO `sys_dict_type` VALUES (9, 'dictType.sys_oper_type', 'sys_oper_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.sys_oper_type_remark'); INSERT IGNORE INTO `sys_dict_type` VALUES (10, 'dictType.sys_common_status', 'sys_common_status', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.sys_common_status_remark'); INSERT IGNORE INTO `sys_dict_type` VALUES (100, 'dictType.trace_type', 'trace_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.trace_type_remark'); -INSERT IGNORE INTO `sys_dict_type` VALUES (101, 'dictType.operation_log_type', 'operation_log_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.operation_log_type_remark'); +-- INSERT IGNORE INTO `sys_dict_type` VALUES (101, 'dictType.operation_log_type', 'operation_log_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.operation_log_type_remark'); INSERT IGNORE INTO `sys_dict_type` VALUES (102, 'dictType.alarm_status', 'alarm_status', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.alarm_status_remark'); -INSERT IGNORE INTO `sys_dict_type` VALUES (103, 'dictType.security_log_type', 'security_log_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.security_log_type_remark'); +-- INSERT IGNORE INTO `sys_dict_type` VALUES (103, 'dictType.security_log_type', 'security_log_type', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.security_log_type_remark'); INSERT IGNORE INTO `sys_dict_type` VALUES (104, 'dictType.ne_version_status', 'ne_version_status', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.ne_version_status_remark'); INSERT IGNORE INTO `sys_dict_type` VALUES (105, 'dictType.i18n_en', 'i18n_en', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.i18n_en_remark'); INSERT IGNORE INTO `sys_dict_type` VALUES (106, 'dictType.i18n_zh', 'i18n_zh', '1', 'supervisor', 1699350000000, NULL, 0, 'dictType.i18n_zh_remark'); @@ -53,7 +53,7 @@ INSERT IGNORE INTO `sys_dict_type` VALUES (120, 'dictType.ne_host_authMode', 'ne INSERT IGNORE INTO `sys_dict_type` VALUES (121, 'dictType.ne_host_cmd_groupId', 'ne_host_cmd_groupId', '1', 'supervisor', 1702020000000, '', 0, ''); INSERT IGNORE INTO `sys_dict_type` VALUES (122, 'dictType.ne_info_status', 'ne_info_status', '1', 'supervisor', 1702020000000, '', 0, ''); INSERT IGNORE INTO `sys_dict_type` VALUES (123, 'dictType.ne_license_status', 'ne_license_status', '1', 'supervisor', 1702020000000, '', 0, ''); --- INSERT IGNORE INTO `sys_dict_type` VALUES (124, 'dictType.udm_sub_cn_type', 'udm_sub_cn_type', '1', 'supervisor', 1702020000000, '', 0, ''); +INSERT IGNORE INTO `sys_dict_type` VALUES (124, 'dictType.cdr_cause_code', 'cdr_cause_code', '1', 'supervisor', 1725877564156, '', 0, ''); -- 多租户 INSERT IGNORE INTO `sys_dict_type` VALUES (10000, 'dictType.tenancy_type', 'tenancy_type', '1', 'supervisor', 1702020000000, '', 0, ''); diff --git a/database/upgrade/upg_sys_menu.sql b/database/upgrade/upg_sys_menu.sql index 9933464f..8969db30 100644 --- a/database/upgrade/upg_sys_menu.sql +++ b/database/upgrade/upg_sys_menu.sql @@ -123,14 +123,14 @@ REPLACE INTO `sys_menu` VALUES (2092, 'menu.log.alarm', 2089, 40, 'alarm-log', ' 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 (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', '1', '1', 'faultManage/fault-setting/index', 'icon-gonggaodayi', 'supervisor', 1700000000000, NULL, 0, 'menu.fault.setRemark'); +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'); REPLACE INTO `sys_menu` VALUES (2100, 'menu.perf.task', 2099, 1, 'taskManage', 'perfManage/taskManage/index', '1', '1', 'M', '0', '1', 'perfManage:taskManage:index', 'icon-wofaqi', 'supervisor', 1700000000000, 'admin', 1713177036412, 'menu.perf.taskRemark'); REPLACE INTO `sys_menu` VALUES (2101, 'menu.perf.data', 2099, 2, 'perfData', 'perfManage/perfData/index', '1', '1', 'M', '0', '1', 'perfManage:perfData:index', 'icon-soutubiao', 'supervisor', 1700000000000, 'admin', 1713177042915, 'menu.perf.dataRemark'); REPLACE INTO `sys_menu` VALUES (2102, 'menu.perf.report', 2099, 3, 'perfReport', 'perfManage/perfReport/index', '1', '0', 'M', '0', '0', 'perfManage:perfReport:index', 'icon-gonggaodayi', 'supervisor', 1700000000000, NULL, 0, 'menu.perf.reportRemark'); REPLACE INTO `sys_menu` VALUES (2103, 'menu.perf.threshold', 2099, 4, 'perfThreshold', 'perfManage/perfThreshold/index', '1', '0', 'M', '0', '0', 'perfManage:perfThreshold:index', 'icon-zhuanrang', 'supervisor', 1700000000000, 'supervisor', 1715417264697, 'menu.perf.thresholdRemark'); REPLACE INTO `sys_menu` VALUES (2104, 'menu.perf.kpi', 2099, 5, 'goldTarget', 'perfManage/goldTarget/index', '1', '1', 'M', '1', '1', 'perfManage:goldTarget:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.perf.kpiRemark'); -REPLACE INTO `sys_menu` VALUES (2105, 'menu.perf.customTarget', 2099, 6, 'customTarget', 'perfManage/customTarget/index', '1', '1', 'M', '0', '0', 'perfManage:customTarget:index', 'icon-fanhui1', 'supervisor', 1700000000000, 'admin', 1712807948673, 'menu.perf.customTargetRemark'); +REPLACE INTO `sys_menu` VALUES (2105, 'menu.perf.customTarget', 2099, 6, 'customTarget', 'perfManage/customTarget/index', '1', '1', 'M', '1', '1', 'perfManage:customTarget:index', 'icon-fanhui1', 'supervisor', 1700000000000, 'admin', 1712807948673, 'menu.perf.customTargetRemark'); REPLACE INTO `sys_menu` VALUES (2106, 'menu.perf.set', 2099, 7, 'perfSet', 'perfManage/perfSet/index', '1', '0', 'M', '0', '0', 'perfManage:perfSet:index', 'icon-gonggao', 'supervisor', 1700000000000, NULL, 0, 'menu.perf.setRemark'); REPLACE INTO `sys_menu` VALUES (2107, 'menu.mml', 0, 8, 'mmlManage', NULL, '1', '0', 'D', '1', '1', NULL, 'icon-zhizuoliucheng', 'supervisor', 1700000000000, NULL, 0, 'menu.mmlRemark'); REPLACE INTO `sys_menu` VALUES (2108, 'menu.mml.ne', 2107, 1, 'neOperate', 'mmlManage/neOperate/index', '1', '1', 'M', '1', '1', 'mmlManage:neOperate:index', 'icon-huizhiguize', 'supervisor', 1700000000000, NULL, 0, 'menu.mml.neRemark'); @@ -180,6 +180,9 @@ REPLACE INTO `sys_menu` VALUES (2155, 'menu.common.delete', 2154, 1, '#', '', '1 REPLACE INTO `sys_menu` VALUES (2156, 'menu.common.edit', 2154, 2, '#', '', '1', '1', 'B', '1', '1', 'ne:neConfigBackup:edit', '#', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_menu` VALUES (2157, 'menu.dashboard.smscCDR', 2140, 9, 'smscCDR', 'dashboard/smscCDR/index', '1', '0', 'M', '1', '1', 'dashboard:cdr:index', 'icon-paixu', 'supervisor', 1723107637982, 'supervisor', 1723107637982, ''); REPLACE INTO `sys_menu` VALUES (2158, 'menu.trace.pcapFile', 2083, 4, 'pcap/inline/file', 'traceManage/pcap/file', '1', '1', 'M', '0', '1', 'traceManage:pcap:index', '#', 'supervisor', 1724144595914, '', 0, ''); +REPLACE INTO `sys_menu` VALUES (2159, 'menu.log.exportFile', 2089, 100, 'exportFile', 'logManage/exportFile/index', '1', '1', 'M', '1', '1', 'logManage:exportFile:index', 'icon-wenjian', 'supervisor', 1724144595914, '', 0, ''); +REPLACE INTO `sys_menu` VALUES (2160, 'menu.perf.kpiCReport', 2099, 100, 'kpiCReport', 'perfManage/kpiCReport/index', '1', '1', 'M', '1', '1', 'perfManage:kpiCReport:index', 'icon-tubiaoku', 'supervisor', 1724144595914, '', 0, ''); +REPLACE INTO `sys_menu` VALUES (2161, 'menu.trace.taskHLR', 2083, 10, 'taskHLR', 'traceManage/task-hlr/index', '1', '0', 'M', '1', '1', 'traceManage:taskHLR:index', 'icon-gengduo', 'supervisor', 1724144595914, '', 0, ''); -- multi-tenancy diff --git a/database/upgrade/upg_sys_role_menu.sql b/database/upgrade/upg_sys_role_menu.sql index a206d4b8..966e8f0a 100644 --- a/database/upgrade/upg_sys_role_menu.sql +++ b/database/upgrade/upg_sys_role_menu.sql @@ -158,6 +158,8 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2155); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2156); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2157); INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2158); +INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2159); +INSERT IGNORE INTO `sys_role_menu` VALUES (2, 2160); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 1); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 4); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 5); @@ -179,8 +181,6 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2080); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2081); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2082); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2083); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2084); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2085); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2086); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2087); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2088); @@ -191,26 +191,17 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2094); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2097); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2098); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2099); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2100); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2101); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2102); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2103); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2104); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2105); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2106); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2107); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2108); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2109); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2111); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2113); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2118); +INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2114); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2119); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2120); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2123); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2124); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2125); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2126); -INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2127); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2128); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2129); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2130); @@ -222,12 +213,17 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2138); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2140); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2141); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2143); +INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2146); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2147); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2148); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2149); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2152); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2153); INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2154); +INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2155); +INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2156); +INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2157); +INSERT IGNORE INTO `sys_role_menu` VALUES (3, 2160); INSERT IGNORE INTO `sys_role_menu` VALUES (4, 1); INSERT IGNORE INTO `sys_role_menu` VALUES (4, 5); INSERT IGNORE INTO `sys_role_menu` VALUES (4, 112); @@ -278,6 +274,7 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2148); INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2149); INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2152); INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2153); +INSERT IGNORE INTO `sys_role_menu` VALUES (4, 2160); INSERT IGNORE INTO `sys_role_menu` VALUES (5, 1); INSERT IGNORE INTO `sys_role_menu` VALUES (5, 5); INSERT IGNORE INTO `sys_role_menu` VALUES (5, 112); diff --git a/database/upgrade/upg_u_auth_user.sql b/database/upgrade/upg_u_auth_user.sql new file mode 100644 index 00000000..e73125d2 --- /dev/null +++ b/database/upgrade/upg_u_auth_user.sql @@ -0,0 +1,18 @@ +-- +-- Table structure for table `u_auth_user` +-- +DROP TABLE IF EXISTS `u_auth_user`; +CREATE TABLE IF NOT EXISTS `u_auth_user` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', + `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM卡/USIM卡ID', + `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'UDM网元标识', + `amf` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'AMF', + `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '状态', + `ki` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'ki', + `algo_index` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'algoIndex', + `opc` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'OPC', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_neid唯一主键' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='UDM鉴权用户'; + +-- Dump completed on 2024-03-06 17:26:59 diff --git a/database/upgrade/upg_u_sub_user.sql b/database/upgrade/upg_u_sub_user.sql index dcd95f2e..15de581c 100644 --- a/database/upgrade/upg_u_sub_user.sql +++ b/database/upgrade/upg_u_sub_user.sql @@ -1,53 +1,40 @@ -/* - Navicat Premium Data Transfer - - Source Server : omc@192.168.2.211 - Source Server Type : MariaDB - Source Server Version : 100615 (10.6.15-MariaDB-1:10.6.15+maria~ubu1804) - Source Host : 192.168.2.211:33066 - Source Schema : omc_db - - Target Server Type : MariaDB - Target Server Version : 100615 (10.6.15-MariaDB-1:10.6.15+maria~ubu1804) - File Encoding : 65001 - - Date: 19/06/2024 16:59:50 -*/ - SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; --- ---------------------------- --- Table structure for u_sub_user --- ---------------------------- -DROP TABLE IF EXISTS `u_sub_user`; -CREATE TABLE `u_sub_user` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', - `msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '相当手机号', - `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'SIM卡号', - `ambr` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'SubUeAMBRTemp', - `nssai` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'SubSNSSAITemp', - `rat` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'rat', - `arfb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'forbiddenAreasTemp', - `sar` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'serviceAreaRestrictTemp', - `cn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'cnType', - `sm_data` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'smData', - `smf_sel` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'smfSel', - `eps_dat` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Eps', - `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'UDM网元标识-子系统', - `eps_flag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'epsFlag', - `eps_odb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'epsOdb', - `hplmn_odb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'hplmnOdb', - `ard` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Ard', - `epstpl` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Epstpl', - `context_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'ContextId', - `apn_context` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'apnContext', - `static_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'staticIpstatic_ip指给4G UE分配的静态IP,没有可不带此字段名', +-- +-- Table structure for table `u_sub_user` +-- +-- DROP TABLE IF EXISTS `u_sub_user`; +CREATE TABLE IF NOT EXISTS `u_sub_user` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', + `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM卡/USIM卡ID', + `msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户电话号码', + `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'UDM网元标识', + `ambr` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'SubUeAMBRTemp', + `nssai` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'SubSNSSAITemp', + `rat` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'rat VIRTUAL|WLAN|EUTRA|NR', + `arfb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'forbiddenAreasTemp', + `sar` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'serviceAreaRestrictTemp', + `cn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'cnType EPC|5GC', + `sm_data` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'smData', + `smf_sel` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'smfSel', + `eps_dat` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Eps', + `eps_flag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'epsFlag', + `eps_odb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'epsOdb', + `hplmn_odb` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'hplmnOdb', + `ard` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Ard', + `epstpl` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'Epstpl', + `context_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'ContextId', + `apn_context` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'apnContext', + `static_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'staticIpstatic_ip指给4G UE分配的静态IP,没有可不带此字段名', + `cag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'CAG', + `tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'multi-tenancy refer to sys_tenant.tenant_id', PRIMARY KEY (`id`) USING BTREE, - UNIQUE INDEX `imsi_ne`(`imsi`, `ne_id`) USING BTREE COMMENT 'imsi_ne唯一索引' -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM签约用户' ROW_FORMAT = Dynamic; + UNIQUE KEY `imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_ne唯一索引' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='UDM签约用户'; -- multi-tenancy -ALTER TABLE `u_sub_user` ADD COLUMN `tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'multi-tenancy refer to sys_tenant.tenant_id' AFTER `static_ip`; +ALTER TABLE `u_sub_user` ADD COLUMN `cag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'CAG' AFTER `static_ip`; +ALTER TABLE `u_sub_user` ADD COLUMN `tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'multi-tenancy refer to sys_tenant.tenant_id' AFTER `cag`; SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/upgrade/upg_u_user_info.sql b/database/upgrade/upg_u_user_info.sql new file mode 100644 index 00000000..b2bb734c --- /dev/null +++ b/database/upgrade/upg_u_user_info.sql @@ -0,0 +1,15 @@ +-- +-- Table structure for table `u_user_info` +-- + +CREATE TABLE IF NOT EXISTS `u_user_info` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '默认ID', + `imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM卡/USIM卡ID', + `msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户电话号码', + `ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'UDM网元标识', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '备注', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_ne唯一索引' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='UDM用户IMSI扩展信息'; + +-- Dump completed on 2024-09-19 11:26:59 diff --git a/database/upgvue3/upg_sys_dict_data2_i18n_en.sql b/database/upgvue3/upg_sys_dict_data2_i18n_en.sql index f55b7a86..5d5625b5 100644 --- a/database/upgvue3/upg_sys_dict_data2_i18n_en.sql +++ b/database/upgvue3/upg_sys_dict_data2_i18n_en.sql @@ -134,7 +134,7 @@ INSERT IGNORE INTO `sys_dict_data` VALUES (3113, 3113, 'menu.perf.data', 'Perfor INSERT IGNORE INTO `sys_dict_data` VALUES (3114, 3114, 'menu.perf.report', 'Performance Reports', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (3115, 3115, 'menu.perf.threshold', 'Performance Thresholds', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (3116, 3116, 'menu.perf.kpi', 'Key Performance Indicators', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); -INSERT IGNORE INTO `sys_dict_data` VALUES (3117, 3117, 'menu.perf.customTarget', 'Custom Metrics', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT IGNORE INTO `sys_dict_data` VALUES (3117, 3117, 'menu.perf.customTarget', 'Custom Indicator Management', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (3118, 3118, 'menu.perf.set', 'Performance General Settings', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (3119, 3119, 'menu.mml', 'MML', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (3120, 3120, 'menu.mml.ne', 'NE Operation', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -146,7 +146,7 @@ INSERT IGNORE INTO `sys_dict_data` VALUES (3125, 3125, 'menu.perf.dataRemark', ' INSERT IGNORE INTO `sys_dict_data` VALUES (3126, 3126, 'menu.perf.reportRemark', 'Performance Report Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (3127, 3127, 'menu.perf.thresholdRemark', 'Performance Threshold Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT IGNORE 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 IGNORE INTO `sys_dict_data` VALUES (3129, 3129, 'menu.perf.customTargetRemark', 'Custom Metrics Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT IGNORE 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 IGNORE 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 IGNORE INTO `sys_dict_data` VALUES (3131, 3131, 'menu.mmlRemark', 'MML Management Catalog', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT IGNORE INTO `sys_dict_data` VALUES (3132, 3132, 'menu.mml.neRemark', 'Network Element Operations Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); diff --git a/features/cm/omc/controller.go b/features/cm/omc/controller.go new file mode 100644 index 00000000..888f182f --- /dev/null +++ b/features/cm/omc/controller.go @@ -0,0 +1,46 @@ +package cm_omc + +import ( + "fmt" + "net/http" + + "be.ems/lib/services" + "github.com/gin-gonic/gin" +) + +func (o *ConfigOMC) Get(c *gin.Context) { + paramName := c.Param("paramName") + results, err := o.Query(paramName) + if err != nil { + c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + return + } + c.JSON(http.StatusOK, services.DataResp(results)) +} + +func (o *ConfigOMC) Post(c *gin.Context) { + err := fmt.Errorf("method not allowed") + c.JSON(http.StatusMethodNotAllowed, services.ErrResp(err.Error())) +} + +func (o *ConfigOMC) Put(c *gin.Context) { + paramName := c.Param("paramName") + var paramData map[string]any + + if err := c.ShouldBindJSON(¶mData); err != nil { + c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + return + } + + result, err := o.Modify(paramName, paramData) + if err != nil { + c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + return + } + c.JSON(http.StatusOK, services.DataResp(result)) +} + +func (o *ConfigOMC) Delete(c *gin.Context) { + err := fmt.Errorf("method not allowed") + c.JSON(http.StatusMethodNotAllowed, services.ErrResp(err.Error())) +} diff --git a/features/cm/omc/implement.go b/features/cm/omc/implement.go new file mode 100644 index 00000000..6ef2e65b --- /dev/null +++ b/features/cm/omc/implement.go @@ -0,0 +1,69 @@ +package cm_omc + +import ( + "fmt" + + "be.ems/restagent/config" +) + +const ( + PASSWORD_MASK = "********" +) + +func (o *ConfigOMC) Query(paramName string) (any, error) { + var results []any + + switch paramName { + case "alarmEmailForward": + result := config.GetYamlConfig().Alarm.EmailForward + result.Password = PASSWORD_MASK + results = append(results, result) + case "alarmSMSForward": + result := config.GetYamlConfig().Alarm.SMSCForward + result.Password = PASSWORD_MASK + results = append(results, result) + default: + return nil, fmt.Errorf("invalid source parameter") + } + + return results, nil +} + +func (o *ConfigOMC) Add() { + +} + +func (o *ConfigOMC) Modify(paramName string, paramData map[string]any) (any, error) { + var results []any + + switch paramName { + case "alarmEmailForward": + param := &(config.GetYamlConfig().Alarm.EmailForward) + config.UpdateStructFromMap(param, paramData) + result := *param + results = append(results, result) + err := config.WriteOrignalConfig(config.YamlConfigInfo.FilePath, paramName, paramData) + if err != nil { + fmt.Println("failed to write config yaml file:", err) + return results, err + } + case "alarmSMSForward": + param := &(config.GetYamlConfig().Alarm.SMSCForward) + config.UpdateStructFromMap(param, paramData) + result := *param + results = append(results, result) + err := config.WriteOrignalConfig(config.YamlConfigInfo.FilePath, paramName, paramData) + if err != nil { + fmt.Println("failed to write config yaml file:", err) + return results, err + } + default: + return nil, fmt.Errorf("invalid source parameter") + } + + return results, nil +} + +func (o *ConfigOMC) Remove() { + +} diff --git a/features/cm/omc/model.go b/features/cm/omc/model.go new file mode 100644 index 00000000..967c84c6 --- /dev/null +++ b/features/cm/omc/model.go @@ -0,0 +1,26 @@ +package cm_omc + +type ConfigOMC struct{} + +type SystemConfig struct { + ForwardFlag bool `json:"forwardFlag"` +} + +type AlarmEmailForward struct { + Enable bool `json:"enable"` + EmailList string `json:"emailList"` + SMTP string `json:"smtp"` + Port uint16 `json:"port"` + User string `json:"user"` + Password string `json:"password"` + TLSSkipVerify bool `json:"tlsSkipVerify"` +} + +type AlarmSMSForward struct { + Enable bool `json:"enable"` + MobileList string `json:"mobileList"` + SMSCAddr string `json:"smscAddr"` + SystemID string `json:"systemID"` + Password string `json:"password"` + SystemType string `json:"systemType"` +} diff --git a/features/cm/omc/route.go b/features/cm/omc/route.go new file mode 100644 index 00000000..906cb1e7 --- /dev/null +++ b/features/cm/omc/route.go @@ -0,0 +1,30 @@ +package cm_omc + +import ( + "be.ems/src/framework/middleware" + "github.com/gin-gonic/gin" +) + +// Register Routes for file_export +func Register(r *gin.RouterGroup) { + cmOMC := r.Group("/omc") + { + var o *ConfigOMC + cmOMC.GET("/config/:paramName", + middleware.PreAuthorize(nil), + o.Get, + ) + cmOMC.POST("/config/:paramName", + middleware.PreAuthorize(nil), + o.Post, + ) + cmOMC.PUT("/config/:paramName", + middleware.PreAuthorize(nil), + o.Put, + ) + cmOMC.DELETE("/config/:paramName", + middleware.PreAuthorize(nil), + o.Delete, + ) + } +} diff --git a/features/cm/service.go b/features/cm/service.go new file mode 100644 index 00000000..f5d8b692 --- /dev/null +++ b/features/cm/service.go @@ -0,0 +1,17 @@ +package cm + +import ( + cm_omc "be.ems/features/cm/omc" + "be.ems/lib/log" + "github.com/gin-gonic/gin" +) + +func InitSubServiceRoute(r *gin.Engine) { + log.Info("======init PM group gin.Engine") + + cmGroup := r.Group("/cm") + // register sub modules routes + cm_omc.Register(cmGroup) + + // return featuresGroup +} diff --git a/features/features.go b/features/features.go index 70510558..343ff0bb 100644 --- a/features/features.go +++ b/features/features.go @@ -1,6 +1,7 @@ package features import ( + "be.ems/features/cm" "be.ems/features/lm" "be.ems/features/pm" "be.ems/lib/log" @@ -14,6 +15,7 @@ func InitServiceEngine(r *gin.Engine) { // 注册 各个features 模块的路由 pm.InitSubServiceRoute(r) lm.InitSubServiceRoute(r) + cm.InitSubServiceRoute(r) // return featuresGroup } diff --git a/features/fm/alarm.go b/features/fm/alarm.go index a3ff7e94..7bb89ea8 100644 --- a/features/fm/alarm.go +++ b/features/fm/alarm.go @@ -466,10 +466,12 @@ func PostAlarmFromNF(w http.ResponseWriter, r *http.Request) { } session.Commit() } - if config.GetYamlConfig().Alarm.ForwardAlarm { + if config.GetYamlConfig().Alarm.EmailForward.Enable { if err = AlarmEmailForward(&alarmData); err != nil { log.Error("Failed to AlarmEmailForward:", err) } + } + if config.GetYamlConfig().Alarm.SMSCForward.Enable { if err = AlarmSMSForward(&alarmData); err != nil { log.Error("Failed to AlarmSMSForward:", err) } @@ -737,9 +739,10 @@ func GetAlarmFromNF(w http.ResponseWriter, r *http.Request) { } } + evenTime := global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime) alarmData.ObjectUid = alarmData.NeId alarmData.ObjectType = "VNFM" - alarmData.EventTime = global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime) + alarmData.EventTime = evenTime if IsNeedToAckAlarm(valueJson, &alarmData) { SetAlarmAckInfo(valueJson, &alarmData) } @@ -766,8 +769,8 @@ func GetAlarmFromNF(w http.ResponseWriter, r *http.Request) { alarmLog.AlarmId = alarmData.AlarmId alarmLog.AlarmCode = alarmData.AlarmCode alarmLog.AlarmStatus = alarmData.AlarmStatus - alarmLog.EventTime = global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime) - log.Debug("alarmLog:", alarmLog) + alarmLog.EventTime = evenTime + log.Trace("alarmLog:", alarmLog) affected, err = session.Insert(alarmLog) if err != nil && affected <= 0 { log.Error("Failed to insert data:", err) @@ -775,10 +778,12 @@ func GetAlarmFromNF(w http.ResponseWriter, r *http.Request) { continue } session.Commit() - if config.GetYamlConfig().Alarm.ForwardAlarm { + if config.GetYamlConfig().Alarm.EmailForward.Enable { if err = AlarmEmailForward(&alarmData); err != nil { log.Error("Failed to AlarmEmailForward:", err) } + } + if config.GetYamlConfig().Alarm.SMSCForward.Enable { if err = AlarmSMSForward(&alarmData); err != nil { log.Error("Failed to AlarmSMSForward:", err) } diff --git a/features/fm/email.go b/features/fm/email.go index 01cf8a42..aa25d929 100644 --- a/features/fm/email.go +++ b/features/fm/email.go @@ -2,7 +2,6 @@ package fm import ( "crypto/tls" - "errors" "fmt" "strings" @@ -48,25 +47,25 @@ func AlarmEmailForward(alarmData *Alarm) error { // userName := "smtpext@agrandtech.com" // password := "1000smtp@omc!" - host := config.GetYamlConfig().Alarm.Email.Smtp - port := int(config.GetYamlConfig().Alarm.Email.Port) - userName := config.GetYamlConfig().Alarm.Email.User - password := config.GetYamlConfig().Alarm.Email.Password + host := config.GetYamlConfig().Alarm.EmailForward.SMTP + port := int(config.GetYamlConfig().Alarm.EmailForward.Port) + userName := config.GetYamlConfig().Alarm.EmailForward.User + password := config.GetYamlConfig().Alarm.EmailForward.Password m := gomail.NewMessage() m.SetHeader("From", userName) // 发件人 //m.SetHeader("From", "alias"+"<"+"aliastest"+">") // 增加发件人别名 - emails, err := dborm.XormGetAlarmForward("Email") - if err != nil { - log.Error("Failed to XormGetAlarmForward:", err) - return err - } else if emails == nil || len(*emails) == 0 { - err := errors.New("not found forward email list") - log.Error(err) - return err - } - + // emails, err := dborm.XormGetAlarmForward("Email") + // if err != nil { + // log.Error("Failed to XormGetAlarmForward:", err) + // return err + // } else if emails == nil || len(*emails) == 0 { + // err := errors.New("not found forward email list") + // log.Error(err) + // return err + // } + emails := strings.Split(config.GetYamlConfig().Alarm.EmailForward.EmailList, ",") forwardLog := &dborm.AlarmForwardLog{ NeType: alarmData.NeType, NeID: alarmData.NeId, @@ -74,10 +73,10 @@ func AlarmEmailForward(alarmData *Alarm) error { AlarmTitle: alarmData.AlarmTitle, AlarmSeq: alarmData.AlarmSeq, EventTime: alarmData.EventTime, - ToUser: strings.Join(*emails, ","), + ToUser: config.GetYamlConfig().Alarm.EmailForward.EmailList, } - m.SetHeader("To", *emails...) // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接 + m.SetHeader("To", emails...) // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接 //m.SetHeader("To", strings.Join(*emails, " ")) // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接 //m.SetHeader("To", "zhangshuzhong@agrandtech.com", "simonzhangsz@outlook.com") // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接 //m.SetHeader("Cc", "******@qq.com") // 抄送,可以多个 @@ -103,7 +102,7 @@ func AlarmEmailForward(alarmData *Alarm) error { ) // 关闭SSL协议认证 d.TLSConfig = &tls.Config{InsecureSkipVerify: true} - if !config.GetYamlConfig().Alarm.Email.TlsSkipVerify { + if !config.GetYamlConfig().Alarm.EmailForward.TLSSkipVerify { // 打开SSL协议认证 d.TLSConfig = &tls.Config{InsecureSkipVerify: false} } diff --git a/features/fm/smsforward.go b/features/fm/smsforward.go index 06e11347..01f85d33 100644 --- a/features/fm/smsforward.go +++ b/features/fm/smsforward.go @@ -90,36 +90,24 @@ func AlarmForwardBySMS(alarmData *Alarm) (string, error) { case http.StatusOK, http.StatusAccepted, http.StatusNoContent, http.StatusCreated: return userList, nil default: - err := fmt.Errorf("Failed to send SMS: %s(Code=%d)", resp.Status, resp.StatusCode) - log.Error(err) + log.Error(fmt.Errorf("failed to send SMS: %s(Code=%d)", resp.Status, resp.StatusCode)) return userList, err } } +var smsForward = &(config.GetYamlConfig().Alarm.SMSCForward) + func AlarmForwardBySMPP(alarmData *Alarm) (string, error) { log.Info("AlarmForwardBySMPP processing... ") - toUsers, err := dborm.XormGetAlarmForward("SMS") - if err != nil { - log.Error("Failed to XormGetAlarmForward:", err) - return "", err - } else if toUsers == nil { - err := errors.New("not found forward phone number") - log.Error(err) - return "", err - } - userList := strings.Join(*toUsers, ",") - + userList := smsForward.MobileList auth := gosmpp.Auth{ - SMSC: config.GetYamlConfig().Alarm.SMSC.Addr, - SystemID: config.GetYamlConfig().Alarm.SMSC.SystemID, - Password: config.GetYamlConfig().Alarm.SMSC.Password, - SystemType: config.GetYamlConfig().Alarm.SMSC.SystemType, + SMSC: smsForward.SMSCAddr, + SystemID: smsForward.SystemID, + Password: smsForward.Password, + SystemType: smsForward.SystemType, } - // conn, err := gosmpp.NonTLSDialer(auth.SMSC) - // connection := gosmpp.NewConnection(conn) - trans, err := gosmpp.NewSession( gosmpp.TXConnector(gosmpp.NonTLSDialer, auth), gosmpp.Settings{ @@ -149,17 +137,22 @@ func AlarmForwardBySMPP(alarmData *Alarm) (string, error) { _ = trans.Close() }() - // sending SMS(s) - // var results []string - // for _, toUser := range *toUsers { - message := "Alarm Notification: " + alarmData.AlarmTitle + " from " + alarmData.NeType + " " + alarmData.NeId + " at " + alarmData.EventTime - if err = trans.Transceiver().Submit(newSubmitSM(userList, message)); err != nil { - // result := fmt.Sprintf("Failed to submit %s hort message:%s", toUser, err.Error()) - // results = append(results, result) - log.Error("Failed to submit hort message:", err) - return userList, err + message := "Alarm Notification: " + alarmData.AlarmTitle + " from " + alarmData.NeType + "_" + alarmData.NeId + " at " + alarmData.EventTime + for _, user := range strings.Split(userList, ",") { + sm, err := newSubmitSM(user, message) + if err != nil { + log.Errorf("Failed to newSubmitSM %s short message: %v", user, err) + writeLog(alarmData, user, "SMS", err) + continue + } + if err = trans.Transceiver().Submit(sm); err != nil { + log.Errorf("Failed to Submit %s short message: %v", user, err) + writeLog(alarmData, user, "SMS", err) + continue + } + writeLog(alarmData, user, "SMS", nil) } - // } + return userList, nil } @@ -190,61 +183,42 @@ func writeLog(alarmData *Alarm, toUser, forwardBy string, err error) error { return nil } -func handlePDU() func(pdu.PDU) (pdu.PDU, bool) { - return func(p pdu.PDU) (pdu.PDU, bool) { - switch pd := p.(type) { - case *pdu.Unbind: - log.Trace("Unbind Received") - return pd.GetResponse(), true - - case *pdu.UnbindResp: - log.Trace("UnbindResp Received") - - case *pdu.SubmitSMResp: - log.Trace("SubmitSMResp Received") - - case *pdu.GenericNack: - log.Trace("GenericNack Received") - - case *pdu.EnquireLinkResp: - fmt.Println("EnquireLinkResp Received") - - case *pdu.EnquireLink: - log.Trace("EnquireLink Received") - return pd.GetResponse(), false - - case *pdu.DataSM: - log.Trace("DataSM receiver") - return pd.GetResponse(), false - - case *pdu.DeliverSM: - log.Trace("DeliverSM receiver") - return pd.GetResponse(), false - } - return nil, false - } -} - -func newSubmitSM(phoneNumber string, message string) *pdu.SubmitSM { +func newSubmitSM(phoneNumber string, message string) (*pdu.SubmitSM, error) { // build up submitSM srcAddr := pdu.NewAddress() srcAddr.SetTon(5) srcAddr.SetNpi(0) - _ = srcAddr.SetAddress("alarm notification:") - + err := srcAddr.SetAddress(smsForward.ServiceNumber) + if err != nil { + return nil, err + } destAddr := pdu.NewAddress() destAddr.SetTon(1) destAddr.SetNpi(1) - _ = destAddr.SetAddress(phoneNumber) - + err = destAddr.SetAddress(phoneNumber) + if err != nil { + return nil, err + } submitSM := pdu.NewSubmitSM().(*pdu.SubmitSM) submitSM.SourceAddr = srcAddr submitSM.DestAddr = destAddr - _ = submitSM.Message.SetMessageWithEncoding(message, data.UCS2) + dataCoding := data.UCS2 + switch smsForward.DataCoding { + case config.CODING_UCS2: + dataCoding = data.UCS2 + case config.CODING_ASCII: + dataCoding = data.ASCII + case config.CODING_LATIN1: + dataCoding = data.LATIN1 + } + err = submitSM.Message.SetMessageWithEncoding(message, dataCoding) + if err != nil { + return nil, err + } submitSM.ProtocolID = 0 submitSM.RegisteredDelivery = 1 submitSM.ReplaceIfPresentFlag = 0 submitSM.EsmClass = 0 - return submitSM + return submitSM, nil } diff --git a/features/lm/file_export/controller.go b/features/lm/file_export/controller.go index 5fba6abb..d5610fff 100644 --- a/features/lm/file_export/controller.go +++ b/features/lm/file_export/controller.go @@ -38,7 +38,7 @@ func (m *SysJob) GetFileExportTable(c *gin.Context) { err := datasource.DefaultDB().Table(m.TableName()).Where("invoke_target=? and status=1", INVOKE_FILE_EXPORT). Find(&results).Error if err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } language := ctx.AcceptLanguage(c) @@ -46,7 +46,7 @@ func (m *SysJob) GetFileExportTable(c *gin.Context) { for _, job := range results { var params TargetParams if err := json.Unmarshal([]byte(job.TargetParams), ¶ms); err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } TableDisplay := i18n.TKey(language, "table."+params.TableName) @@ -67,14 +67,15 @@ func (m *FileExport) GetFileList(c *gin.Context) { var querys FileExportQuery if err := c.ShouldBindQuery(&querys); err != nil { - c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } files, err := file.GetFileInfo(querys.Path, querys.Suffix) if err != nil { - log.Error(err) - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + log.Error("failed to GetFileInfo:", err) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return } // split files list @@ -98,8 +99,8 @@ func (m *FileExport) Total(c *gin.Context) { fileCount, dirCount, err := file.GetFileAndDirCount(dir) if err != nil { - log.Error(err) - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + log.Error("failed to GetFileAndDirCount:", err) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } total := fileCount + dirCount @@ -113,13 +114,13 @@ func (m *FileExport) DownloadHandler(c *gin.Context) { file, err := os.Open(filePath) if err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } defer file.Close() if _, err := os.Stat(filePath); os.IsNotExist(err) { - c.JSON(http.StatusNotFound, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } @@ -134,7 +135,7 @@ func (m *FileExport) Delete(c *gin.Context) { filePath := filepath.Join(dir, fileName) if err := os.Remove(filePath); err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } c.JSON(http.StatusNoContent, nil) // 204 No Content diff --git a/features/pm/kpi_c_report/controller.go b/features/pm/kpi_c_report/controller.go index 85818b48..1b88013c 100644 --- a/features/pm/kpi_c_report/controller.go +++ b/features/pm/kpi_c_report/controller.go @@ -5,8 +5,8 @@ import ( "net/http" "strings" + "be.ems/lib/dborm" "be.ems/lib/services" - "be.ems/src/framework/datasource" "github.com/gin-gonic/gin" ) @@ -30,7 +30,7 @@ func (k *KpiCReport) Get(c *gin.Context) { return } tableName := TableName() + "_" + strings.ToLower(querys.NeType) - dborm := datasource.DefaultDB().Table(tableName) + dbg := dborm.DefaultDB().Table(tableName) if querys.NeID != "" { conditions = append(conditions, "rm_uid = (select n.rm_uid from ne_info n where n.ne_type=? and n.ne_id=? and n.status=1)") @@ -51,30 +51,29 @@ func (k *KpiCReport) Get(c *gin.Context) { whereSql := "" if len(conditions) > 0 { whereSql += strings.Join(conditions, " and ") - dborm = dborm.Where(whereSql, params...) + dbg = dbg.Where(whereSql, params...) } // page number and size if pageSize := querys.PageSize; pageSize > 0 { - dborm = dborm.Limit(pageSize) + dbg = dbg.Limit(pageSize) if pageNum := querys.PageNum; pageNum > 0 { - dborm = dborm.Offset((pageNum - 1) * pageSize) + dbg = dbg.Offset((pageNum - 1) * pageSize) } } // order by if sortField, sortOrder := querys.SortField, querys.SortOrder; sortField != "" && sortOrder != "" { orderBy := fmt.Sprintf("%s %s", sortField, sortOrder) - dborm = dborm.Order(orderBy) + dbg = dbg.Order(orderBy) } - //err := datasource.DefaultDB().Table(tableName).Where(whereSql, params...).Find(&reports).Error - err := dborm.Find(&reports).Error + //err := dborm.DefaultDB().Table(tableName).Where(whereSql, params...).Find(&reports).Error + err := dbg.Find(&reports).Error if err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } c.JSON(http.StatusOK, services.DataResp(reports)) - //c.JSON(http.StatusOK, reports) } func (k *KpiCReport) GetReport2FE(c *gin.Context) { @@ -84,7 +83,7 @@ func (k *KpiCReport) GetReport2FE(c *gin.Context) { var querys KpiCReportQuery if err := c.ShouldBindQuery(&querys); err != nil { - c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } @@ -93,11 +92,11 @@ func (k *KpiCReport) GetReport2FE(c *gin.Context) { conditions = append(conditions, "ne_type = ?") params = append(params, strings.ToUpper(querys.NeType)) } else { - c.JSON(http.StatusBadRequest, services.ErrResp("Not found required parameter NE type")) + c.JSON(http.StatusOK, services.ErrResp("Not found required parameter NE type")) return } tableName := TableName() + "_" + strings.ToLower(querys.NeType) - dborm := datasource.DefaultDB().Table(tableName) + dbg := dborm.DefaultDB().Table(tableName) if querys.NeID != "" { conditions = append(conditions, "rm_uid = (select n.rm_uid from ne_info n where n.ne_type=? and n.ne_id=? and n.status=1)") @@ -118,26 +117,26 @@ func (k *KpiCReport) GetReport2FE(c *gin.Context) { whereSql := "" if len(conditions) > 0 { whereSql += strings.Join(conditions, " and ") - dborm = dborm.Where(whereSql, params...) + dbg = dbg.Where(whereSql, params...) } // page number and size if pageSize := querys.PageSize; pageSize > 0 { - dborm = dborm.Limit(pageSize) + dbg = dbg.Limit(pageSize) if pageNum := querys.PageNum; pageNum > 0 { - dborm = dborm.Offset((pageNum - 1) * pageSize) + dbg = dbg.Offset((pageNum - 1) * pageSize) } } // order by if sortField, sortOrder := querys.SortField, querys.SortOrder; sortField != "" && sortOrder != "" { orderBy := fmt.Sprintf("%s %s", sortField, sortOrder) - dborm = dborm.Order(orderBy) + dbg = dbg.Order(orderBy) } - //err := datasource.DefaultDB().Table(tableName).Where(whereSql, params...).Find(&reports).Error - err := dborm.Find(&results).Error + //err := dborm.DefaultDB().Table(tableName).Where(whereSql, params...).Find(&reports).Error + err := dbg.Find(&results).Error if err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } @@ -150,10 +149,9 @@ func (k *KpiCReport) GetReport2FE(c *gin.Context) { "neName": *r.NeName, "rmUID": *r.RmUID, "startIndex": r.Index, - "timeGroup": r.Date[:10] + " " + *r.StartTime, + "timeGroup": r.Date[:10] + " " + *r.EndTime, "createdAt": r.CreatedAt, "granularity": r.Granularity, - "tenantID": r.TenantID, } for _, k := range r.KpiValues { @@ -171,7 +169,7 @@ func (k *KpiCReport) GetTotalList(c *gin.Context) { var querys KpiCReportQuery if err := c.ShouldBindQuery(&querys); err != nil { - c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } @@ -180,11 +178,11 @@ func (k *KpiCReport) GetTotalList(c *gin.Context) { conditions = append(conditions, "ne_type = ?") params = append(params, strings.ToUpper(querys.NeType)) } else { - c.JSON(http.StatusBadRequest, services.ErrResp("Not found NE type")) + c.JSON(http.StatusOK, services.ErrResp("Not found NE type")) return } tableName := TableName() + "_" + strings.ToLower(querys.NeType) - dborm := datasource.DefaultDB().Table(tableName) + dbg := dborm.DefaultDB().Table(tableName) if querys.StartTime != "" { conditions = append(conditions, "created_at >= ?") @@ -198,40 +196,39 @@ func (k *KpiCReport) GetTotalList(c *gin.Context) { whereSql := "" if len(conditions) > 0 { whereSql += strings.Join(conditions, " and ") - dborm = dborm.Where(whereSql, params...) + dbg = dbg.Where(whereSql, params...) } // get total number var total int64 = 0 - err := dborm.Count(&total).Error + err := dbg.Count(&total).Error if err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } // page number and size if pageSize := querys.PageSize; pageSize > 0 { - dborm = dborm.Limit(pageSize) + dbg = dbg.Limit(pageSize) if pageNum := querys.PageNum; pageNum > 0 { - dborm = dborm.Offset((pageNum - 1) * pageSize) + dbg = dbg.Offset((pageNum - 1) * pageSize) } } // order by if sortField, sortOrder := querys.SortField, querys.SortOrder; sortField != "" && sortOrder != "" { orderBy := fmt.Sprintf("%s %s", sortField, sortOrder) - dborm = dborm.Order(orderBy) + dbg = dbg.Order(orderBy) } - //err := datasource.DefaultDB().Table(tableName).Where(whereSql, params...).Find(&reports).Error - err = dborm.Find(&reports).Error + //err := dborm.DefaultDB().Table(tableName).Where(whereSql, params...).Find(&reports).Error + err = dbg.Find(&reports).Error if err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } c.JSON(http.StatusOK, services.TotalDataResp(reports, total)) - //c.JSON(http.StatusOK, reports) } func (k *KpiCReport) Total(c *gin.Context) { @@ -240,7 +237,7 @@ func (k *KpiCReport) Total(c *gin.Context) { var querys KpiCReportQuery if err := c.ShouldBindQuery(&querys); err != nil { - c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } @@ -249,11 +246,11 @@ func (k *KpiCReport) Total(c *gin.Context) { conditions = append(conditions, "ne_type = ?") params = append(params, strings.ToUpper(querys.NeType)) } else { - c.JSON(http.StatusBadRequest, services.ErrResp("Not found NE type")) + c.JSON(http.StatusOK, services.ErrResp("Not found NE type")) return } tableName := TableName() + "_" + strings.ToLower(querys.NeType) - dborm := datasource.DefaultDB().Table(tableName) + dbg := dborm.DefaultDB().Table(tableName) if querys.StartTime != "" { conditions = append(conditions, "created_at >= ?") @@ -267,12 +264,12 @@ func (k *KpiCReport) Total(c *gin.Context) { whereSql := "" if len(conditions) > 0 { whereSql += strings.Join(conditions, " and ") - dborm = dborm.Where(whereSql, params...) + dbg = dbg.Where(whereSql, params...) } var total int64 = 0 - err := dborm.Count(&total).Error + err := dbg.Count(&total).Error if err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } @@ -283,11 +280,11 @@ func (k *KpiCReport) Post(c *gin.Context) { var report KpiCReport if err := c.ShouldBindJSON(&report); err != nil { - c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } - if err := datasource.DefaultDB().Create(&report).Error; err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + if err := dborm.DefaultDB().Create(&report).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } c.JSON(http.StatusCreated, services.DataResp(report)) @@ -297,24 +294,24 @@ func (k *KpiCReport) Put(c *gin.Context) { var report KpiCReport id := c.Param("id") - if err := datasource.DefaultDB().First(&report, id).Error; err != nil { - c.JSON(http.StatusNotFound, services.ErrResp("KPI report not found")) + if err := dborm.DefaultDB().First(&report, id).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp("custom indicator report not found")) return } if err := c.ShouldBindJSON(&report); err != nil { - c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } - datasource.DefaultDB().Save(&report) + dborm.DefaultDB().Save(&report) c.JSON(http.StatusOK, services.DataResp(report)) } func (k *KpiCReport) Delete(c *gin.Context) { id := c.Param("id") - if err := datasource.DefaultDB().Delete(&KpiCReport{}, id).Error; err != nil { - c.JSON(http.StatusNotFound, services.ErrResp("KPI report not found")) + if err := dborm.DefaultDB().Delete(&KpiCReport{}, id).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp("custom indicator report not found")) return } @@ -323,7 +320,7 @@ func (k *KpiCReport) Delete(c *gin.Context) { func InsertKpiCReport(neType string, report KpiCReport) { tableName := TableName() + "_" + strings.ToLower(neType) - if err := datasource.DefaultDB().Table(tableName).Create(&report).Error; err != nil { + if err := dborm.DefaultDB().Table(tableName).Create(&report).Error; err != nil { return } } diff --git a/features/pm/kpi_c_title/controller.go b/features/pm/kpi_c_title/controller.go index 1c509470..aa2912ce 100644 --- a/features/pm/kpi_c_title/controller.go +++ b/features/pm/kpi_c_title/controller.go @@ -5,8 +5,8 @@ import ( "net/http" "strings" + "be.ems/lib/dborm" "be.ems/lib/services" - "be.ems/src/framework/datasource" "github.com/gin-gonic/gin" ) @@ -17,11 +17,11 @@ func (k *KpiCTitle) GetToalList(c *gin.Context) { var querys KpiCTitleQuery if err := c.ShouldBindQuery(&querys); err != nil { - c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } - dborm := datasource.DefaultDB().Table(k.TableName()) + dbg := dborm.DefaultDB().Table(k.TableName()) // construct condition to get if neType := querys.NeType; neType != "" { conditions = append(conditions, "ne_type = ?") @@ -34,31 +34,31 @@ func (k *KpiCTitle) GetToalList(c *gin.Context) { whereSql := "" if len(conditions) > 0 { whereSql += strings.Join(conditions, " and ") - dborm = dborm.Where(whereSql, params...) + dbg = dbg.Where(whereSql, params...) } // Get total number var total int64 = 0 - if err := dborm.Count(&total).Error; err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + if err := dbg.Count(&total).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } // page number and size if pageSize := querys.PageSize; pageSize > 0 { - dborm = dborm.Limit(pageSize) + dbg = dbg.Limit(pageSize) if pageNum := querys.PageNum; pageNum > 0 { - dborm = dborm.Offset((pageNum - 1) * pageSize) + dbg = dbg.Offset((pageNum - 1) * pageSize) } } // order by if sortField, sortOrder := querys.SortField, querys.SortOrder; sortField != "" && sortOrder != "" { orderBy := fmt.Sprintf("%s %s", sortField, sortOrder) - dborm = dborm.Order(orderBy) + dbg = dbg.Order(orderBy) } - if err := dborm.Find(&titles).Error; err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + if err := dbg.Find(&titles).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } @@ -84,8 +84,8 @@ func (k *KpiCTitle) Get(c *gin.Context) { if len(conditions) > 0 { whereSql += strings.Join(conditions, " and ") } - if err := datasource.DefaultDB().Where(whereSql, params...).Find(&titles).Error; err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + if err := dborm.DefaultDB().Where(whereSql, params...).Find(&titles).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } @@ -111,8 +111,8 @@ func (k *KpiCTitle) Total(c *gin.Context) { whereSql += strings.Join(conditions, " and ") } var total int64 = 0 - if err := datasource.DefaultDB().Table(k.TableName()).Where(whereSql, params...).Count(&total).Error; err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + if err := dborm.DefaultDB().Table(k.TableName()).Where(whereSql, params...).Count(&total).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } @@ -123,14 +123,37 @@ func (k *KpiCTitle) Post(c *gin.Context) { var title KpiCTitle if err := c.ShouldBindJSON(&title); err != nil { - c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } - if err := datasource.DefaultDB().Create(&title).Error; err != nil { - c.JSON(http.StatusInternalServerError, services.ErrResp(err.Error())) + result := dborm.DefaultDB().Where("ne_type=? and (kpi_id=? or title=?)", title.NeType, title.KpiID, title.Title).First(&title) + if result.RowsAffected > 0 { + c.JSON(http.StatusOK, services.ErrResp("custom indicator already exist")) return } - + if err := dborm.DefaultDB().Create(&title).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + kpiCReportTable := "kpi_c_report_" + strings.ToLower(*title.NeType) + if !dborm.DefaultDB().Migrator().HasTable(kpiCReportTable) { + // clone table "kpi_c_report" to "kpi_c_report_{neType}" + sql := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s AS SELECT * FROM %s WHERE 1=0", kpiCReportTable, "kpi_c_report") + if _, err := dborm.ExecSQL(sql, nil); err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + sql = fmt.Sprintf("ALTER TABLE %s MODIFY COLUMN `id` int(11) NOT NULL AUTO_INCREMENT FIRST,ADD PRIMARY KEY IF NOT EXISTS (`id`)", kpiCReportTable) + if _, err := dborm.ExecSQL(sql, nil); err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + sql = fmt.Sprintf("ALTER TABLE %s ADD INDEX IF NOT EXISTS `idx_timestamp`(`created_at`) USING BTREE, ADD INDEX IF NOT EXISTS `idx_uid_datetime`(`rm_uid`, `date`, `start_time`) USING BTREE", kpiCReportTable) + if _, err := dborm.ExecSQL(sql, nil); err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + } c.JSON(http.StatusCreated, services.DataResp(title)) } @@ -138,16 +161,16 @@ func (k *KpiCTitle) Put(c *gin.Context) { var title KpiCTitle id := c.Param("id") - if err := datasource.DefaultDB().First(&title, id).Error; err != nil { - c.JSON(http.StatusNotFound, services.ErrResp("KPIC Title not found")) + if err := dborm.DefaultDB().First(&title, id).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp("custom indicator not found")) return } if err := c.ShouldBindJSON(&title); err != nil { - c.JSON(http.StatusBadRequest, services.ErrResp(err.Error())) + c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } - datasource.DefaultDB().Save(&title) + dborm.DefaultDB().Save(&title) c.JSON(http.StatusOK, services.DataResp(title)) } @@ -155,8 +178,8 @@ func (k *KpiCTitle) Put(c *gin.Context) { func (k *KpiCTitle) Delete(c *gin.Context) { id := c.Param("id") - if err := datasource.DefaultDB().Delete(&KpiCTitle{}, id).Error; err != nil { - c.JSON(http.StatusNotFound, services.ErrResp("KPIC Title not found")) + if err := dborm.DefaultDB().Delete(&KpiCTitle{}, id).Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp("custom indicator not found")) return } @@ -166,7 +189,7 @@ func (k *KpiCTitle) Delete(c *gin.Context) { func GetActiveKPICList(neType string) []KpiCTitle { k := new([]KpiCTitle) - err := datasource.DefaultDB().Where("`ne_type` = ? and `status` = 'Active'", neType).Find(&k).Error + err := dborm.DefaultDB().Where("`ne_type` = ? and `status` = 'Active'", neType).Find(&k).Error if err != nil { return nil } diff --git a/features/pm/kpi_c_title/model.go b/features/pm/kpi_c_title/model.go index 1bfbfcbc..77bb9423 100644 --- a/features/pm/kpi_c_title/model.go +++ b/features/pm/kpi_c_title/model.go @@ -8,7 +8,7 @@ type KpiCTitle struct { KpiID *string `gorm:"column:kpi_id;default:NULL," json:"kpiId,omitempty"` Title *string `gorm:"column:title;default:NULL," json:"title,omitempty"` Expression *string `gorm:"column:expression;default:NULL," json:"expression,omitempty"` - Status *string `gorm:"column:status" json:"status,omitempty"` + Status string `gorm:"column:status;default:'Active'" json:"status"` Unit *string `gorm:"column:unit" json:"unit,omitempty"` Description *string `gorm:"column:description;default:NULL," json:"description,omitempty"` CreatedBy *string `gorm:"column:created_by;default:NULL," json:"createdBy,omitempty"` diff --git a/features/pm/performance.go b/features/pm/performance.go index 258c19d7..a183d8a4 100644 --- a/features/pm/performance.go +++ b/features/pm/performance.go @@ -334,6 +334,7 @@ func PostKPIReportFromNF(w http.ResponseWriter, r *http.Request) { // 推送自定义KPI到ws订阅组 wsService.NewWSSendImpl.ByGroupID(fmt.Sprintf("%s%s_%s", wsService.GROUP_KPI_C, neInfo.NeType, neInfo.NeId), kpiCEvent) if neInfo.NeType == "UPF" { + wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_KPI_UPF+neInfo.NeId, kpiEvent) // 推送标识为:12_RMUID, exp: 12_4400HXUPF001 wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_KPI_UPF+kpiReport.Task.NE.RmUID, kpiEvent) } diff --git a/go.mod b/go.mod index 9c79cdba..0f2568e5 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.21 require ( github.com/dlclark/regexp2 v1.11.4 + github.com/dustin/go-humanize v1.0.0 github.com/gin-gonic/gin v1.10.0 github.com/go-resty/resty/v2 v2.14.0 github.com/go-sql-driver/mysql v1.8.1 @@ -24,6 +25,7 @@ require ( github.com/redis/go-redis/v9 v9.6.1 github.com/robfig/cron/v3 v3.0.1 github.com/shirou/gopsutil/v4 v4.24.7 + github.com/slayercat/GoSNMPServer v0.5.2 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/xuri/excelize/v2 v2.8.1 @@ -34,13 +36,15 @@ require ( golang.org/x/text v0.17.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/yaml.v3 v3.0.1 - gorm.io/datatypes v1.2.1 gorm.io/driver/mysql v1.5.7 gorm.io/gorm v1.25.11 xorm.io/xorm v1.3.9 ) require ( + github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect + github.com/shirou/gopsutil/v3 v3.23.11 // indirect + github.com/sirupsen/logrus v1.4.2 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic v1.12.1 // indirect diff --git a/go.sum b/go.sum index 486522c2..052a8f2d 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,7 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= @@ -21,6 +22,7 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -69,12 +71,9 @@ github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= -github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= -github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -88,28 +87,24 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gosnmp/gosnmp v1.36.2-0.20231009064202-d306ed5aa998/go.mod h1:O938QjIS4vpSag1UTcnnBq9MfNmimuOGtvQsT1NbErc= github.com/gosnmp/gosnmp v1.38.0 h1:I5ZOMR8kb0DXAFg/88ACurnuwGwYkXWq3eLpJPHMEYc= github.com/gosnmp/gosnmp v1.38.0/go.mod h1:FE+PEZvKrFz9afP9ii1W3cprXuVZ17ypCcyyfYuu5LY= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= -github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= -github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= -github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= -github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU= github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= @@ -130,6 +125,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -148,6 +145,7 @@ github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5j github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0= github.com/linxGnu/gosmpp v0.3.0 h1:LL+eY+zc9Ei/YY0po9A6L6SHf8nPyGvqsLddttr/y/4= github.com/linxGnu/gosmpp v0.3.0/go.mod h1:Ba6SULQql3IbF2A5Mtj3DqMKoFbx1pEz/8xyiOh8ZOs= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae h1:dIZY4ULFcto4tAFlj1FYZl8ztUZ13bdq+PLY+NOfbyI= github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -162,8 +160,6 @@ github.com/metaleap/go-util v0.0.0-20180330192724-a09253046f73 h1:4vKVhAdype/dej github.com/metaleap/go-util v0.0.0-20180330192724-a09253046f73/go.mod h1:l71/5fppWP5A6nqhcxz6wQAYok6pr/vM2+KHIy50/LY= github.com/metaleap/go-xsd v0.0.0-20180330193350-61f7638f502f h1:eeJGcYszuvOpmuJxeq57LaOO8mJurfjpOHJJMfQSD0s= github.com/metaleap/go-xsd v0.0.0-20180330193350-61f7638f502f/go.mod h1:WK3zEKtwVd/v+NM3lh1ZE6MdDfHsdOFFOD5Ezi4Hutg= -github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= -github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -207,6 +203,7 @@ github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Q github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus-community/pro-bing v0.4.1 h1:aMaJwyifHZO0y+h8+icUz0xbToHbia0wdmzdVZ+Kl3w= @@ -217,6 +214,7 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= @@ -232,16 +230,24 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/shirou/gopsutil/v3 v3.23.11 h1:i3jP9NjCPUz7FiZKxlMnODZkdSIp2gnzfrvsu9CuWEQ= +github.com/shirou/gopsutil/v3 v3.23.11/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= github.com/shirou/gopsutil/v4 v4.24.7 h1:V9UGTK4gQ8HvcnPKf6Zt3XHyQq/peaekfxpJ2HSocJk= github.com/shirou/gopsutil/v4 v4.24.7/go.mod h1:0uW/073rP7FYLOkvxolUQM5rMOLTNmRXnFKafpb71rw= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/slayercat/GoSNMPServer v0.5.2 h1:IK2d3kz6JoiYHbAZT5H7hrQQRzAD7rxF0iJZxWrV7Ns= +github.com/slayercat/GoSNMPServer v0.5.2/go.mod h1:6taMSIwudR+7pKRO6dz2U+xoNccZds8eiMVlEN66fXY= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= @@ -253,9 +259,11 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -272,14 +280,17 @@ github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFd github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg= github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY= github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= github.com/xuri/excelize/v2 v2.8.1 h1:pZLMEwK8ep+CLIUWpWmvW8IWE/yxqG0I1xcN6cVMGuQ= @@ -289,7 +300,9 @@ github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9 github.com/xuri/xgen v0.0.0-20240722131518-d0691b701898 h1:qqSByV3qojIVp1XbrFgD3nO38w1m6aePzmknorZQmRc= github.com/xuri/xgen v0.0.0-20240722131518-d0691b701898/go.mod h1:tBkmlRf8JH62H5fAW+BPFj0LNZWRmKglWTLFfpXhhbg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -312,7 +325,10 @@ golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeId golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk= golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ= golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -327,6 +343,7 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -342,6 +359,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= @@ -352,6 +370,7 @@ golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -361,6 +380,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -368,7 +389,10 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -402,7 +426,9 @@ golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= @@ -443,16 +469,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/datatypes v1.2.1 h1:r+g0bk4LPCW2v4+Ls7aeNgGme7JYdNDQ2VtvlNUfBh0= -gorm.io/datatypes v1.2.1/go.mod h1:hYK6OTb/1x+m96PgoZZq10UXJ6RvEBb9kRDQ2yyhzGs= gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= -gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U= -gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A= -gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU= -gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI= -gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0= -gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= diff --git a/lib/dborm/dbgorm.go b/lib/dborm/dbgorm.go new file mode 100644 index 00000000..30ff7c62 --- /dev/null +++ b/lib/dborm/dbgorm.go @@ -0,0 +1,167 @@ +package dborm + +import ( + "database/sql" + "fmt" + "log" + "os" + "regexp" + "time" + + "gorm.io/driver/mysql" + "gorm.io/gorm" + "gorm.io/gorm/logger" +) + +// 数据库连接实例 +var dbgEngine *gorm.DB + +// 载入连接日志配置 +func loadLogger() logger.Interface { + newLogger := logger.New( + log.New(os.Stdout, "[GORM] ", log.LstdFlags), // 将日志输出到控制台 + logger.Config{ + SlowThreshold: time.Second, // Slow SQL 阈值 + LogLevel: logger.Info, // 日志级别 Silent不输出任何日志 + ParameterizedQueries: false, // 参数化查询SQL 用实际值带入?的执行语句 + Colorful: false, // 彩色日志输出 + }, + ) + return newLogger +} + +// 连接数据库实例 +func InitGormConnect(dbType, dbUser, dbPassword, dbHost, dbPort, dbName, dbParam, dbLogging any) error { + var dialector gorm.Dialector + switch dbType { + case "mysql": + dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s", + dbUser, + dbPassword, + dbHost, + dbPort, + dbName, + dbParam, + ) + dialector = mysql.Open(dsn) + default: + err := fmt.Errorf("invalid type: %s", dbType) + return err + } + opts := &gorm.Config{} + // 是否需要日志输出 + if dbLogging.(bool) { + opts.Logger = loadLogger() + } + // 创建连接 + db, err := gorm.Open(dialector, opts) + if err != nil { + log.Fatalf("failed to open: %s", err) + return err + } + // 获取底层 SQL 数据库连接 + sqlDB, err := db.DB() + if err != nil { + log.Fatalf("failed to connect DB pool: %v", err) + return err + } + // 测试数据库连接 + err = sqlDB.Ping() + if err != nil { + log.Fatalf("failed to ping database: %v", err) + return err + } + dbgEngine = db + return nil +} + +// 关闭数据库实例 +func Close() { + sqlDB, err := dbgEngine.DB() + if err != nil { + log.Fatalf("failed to connect pool: %s", err) + } + if err := sqlDB.Close(); err != nil { + log.Fatalf("failed to close: %s", err) + } +} + +// default gorm DB +func DefaultDB() *gorm.DB { + return dbgEngine +} + +// get sql DB +func GCoreDB() (*sql.DB, error) { + return dbgEngine.DB() +} + +// RawSQL 原生查询语句 +func RawSQL(sql string, parameters []any) ([]map[string]any, error) { + // 数据源 + db := DefaultDB() + + // 使用正则表达式替换连续的空白字符为单个空格 + fmtSql := regexp.MustCompile(`\s+`).ReplaceAllString(sql, " ") + + // logger.Infof("sql=> %v", fmtSql) + // logger.Infof("parameters=> %v", parameters) + + // 查询结果 + var rows []map[string]any + res := db.Raw(fmtSql, parameters...).Scan(&rows) + if res.Error != nil { + return nil, res.Error + } + return rows, nil +} + +// ExecSQL 原生执行语句 +func ExecSQL(sql string, parameters []any) (int64, error) { + // 数据源 + db := DefaultDB() + + // 使用正则表达式替换连续的空白字符为单个空格 + fmtSql := regexp.MustCompile(`\s+`).ReplaceAllString(sql, " ") + // 执行结果 + res := db.Exec(fmtSql, parameters...) + if res.Error != nil { + return 0, res.Error + } + return res.RowsAffected, nil +} + +func CloneTable(srcTable, dstTable string) error { + // 获取表 A 的结构信息 + var columns []gorm.ColumnType + dbMigrator := dbgEngine.Migrator() + columns, err := dbMigrator.ColumnTypes(srcTable) + if err != nil { + return fmt.Errorf("failed to ColumnTypes, %v", err) + } + + // 创建表 destination table + err = dbMigrator.CreateTable(dstTable) + if err != nil { + return fmt.Errorf("failed to CreateTable, %v", err) + } + // 复制表 src 的字段到表 dst + for _, column := range columns { + err = dbMigrator.AddColumn(dstTable, column.Name()) + if err != nil { + return fmt.Errorf("failed to AddColumn, %v", err) + } + } + + // 复制表 src 的主键和索引到表 dst + err = dbMigrator.CreateConstraint(dstTable, "PRIMARY") + if err != nil { + return fmt.Errorf("failed to AddColumn, %v", err) + } + + err = dbMigrator.CreateConstraint(dstTable, "INDEX") + if err != nil { + return fmt.Errorf("failed to AddColumn, %v", err) + } + return nil +} diff --git a/lib/dborm/dborm.go b/lib/dborm/dborm.go index 8bf8f918..22eb4496 100644 --- a/lib/dborm/dborm.go +++ b/lib/dborm/dborm.go @@ -16,6 +16,7 @@ import ( _ "github.com/go-sql-driver/mysql" "xorm.io/xorm" + "xorm.io/xorm/core" ) const ( @@ -124,6 +125,14 @@ func XormConnectDatabase(dbType, dbUser, dbPassword, dbHost, dbPort, dbName stri return xEngine, nil } +func XCoreDB() *core.DB { + return xEngine.DB() +} + +func XEngDB() *xorm.Engine { + return xEngine +} + func ConstructInsertSQL(tableName string, insertData interface{}) (string, []string) { log.Debug("ConstructInsertSQL processing... ") log.Debug("Request insertData:", insertData) diff --git a/lib/file/file_linux.go b/lib/file/file_linux.go index 9e459ef5..e4e37256 100644 --- a/lib/file/file_linux.go +++ b/lib/file/file_linux.go @@ -3,6 +3,86 @@ package file +import ( + "fmt" + "os" + "os/user" + "path/filepath" + "strings" + "syscall" + + "github.com/dustin/go-humanize" +) + +type FileInfo struct { + FileType string `json:"fileType"` // 文件类型 + FileMode string `json:"fileMode"` // 文件的权限 + LinkCount int64 `json:"linkCount"` // 硬链接数目 + Owner string `json:"owner"` // 所属用户 + Group string `json:"group"` // 所属组 + Size string `json:"size"` // 文件的大小 + ModifiedTime int64 `json:"modifiedTime"` // 最后修改时间,单位为秒 + FileName string `json:"fileName"` // 文件的名称 +} + +func GetFileInfo(dir, suffix string) ([]FileInfo, error) { + var files []FileInfo + + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if path == dir { + return nil // 跳过当前目录 + } + + fileType := "file" + if info.IsDir() { + fileType = "directory" + } else if info.Mode()&os.ModeSymlink != 0 { + fileType = "symlink" + } + + // check if match suffix + if (suffix != "" && filepath.Ext(path) == suffix) || suffix == "" { + stat, ok := info.Sys().(*syscall.Stat_t) + if !ok { + return fmt.Errorf("not a syscall.Stat_t") + } + userInfo, err := user.LookupId(fmt.Sprint(stat.Uid)) + if err != nil { + return err + } + groupInfo, err := user.LookupGroupId(fmt.Sprint(stat.Gid)) + if err != nil { + return err + } + humanReadableSize := humanize.Bytes(uint64(info.Size())) + fileInfo := FileInfo{ + FileType: fileType, + FileMode: info.Mode().String(), + LinkCount: int64(info.Sys().(*syscall.Stat_t).Nlink), + Owner: userInfo.Username, + Group: groupInfo.Name, + Size: strings.ToUpper(humanReadableSize), + ModifiedTime: info.ModTime().Unix(), + FileName: info.Name(), + } + files = append(files, fileInfo) + } + return nil + }) + if err != nil { + return nil, err + } + return files, nil +} +//go:build linux +// +build linux + +package file + import ( "fmt" "os" diff --git a/lib/file/file_windows.go b/lib/file/file_windows.go index 5371d44e..fbcf9b3c 100644 --- a/lib/file/file_windows.go +++ b/lib/file/file_windows.go @@ -44,8 +44,8 @@ func GetFileInfo(dir, suffix string) ([]FileInfo, error) { FileType: fileType, FileMode: info.Mode().String(), LinkCount: 0, - Owner: "N/A", - Group: "N/A", + Owner: "-", + Group: "-", Size: info.Size(), ModifiedTime: info.ModTime().Unix(), FileName: info.Name(), diff --git a/lib/mmlp/parse.go b/lib/mmlp/parse.go index 94a5692b..e24230e8 100644 --- a/lib/mmlp/parse.go +++ b/lib/mmlp/parse.go @@ -46,6 +46,7 @@ type MmlVar struct { Authorization string `josn:"authorization"` HttpUri string `json:"httpUri"` UserAgent string `json:"userAgent"` + TagNE string `json:"tagNE"` } // func init() { diff --git a/lib/services/response.go b/lib/services/response.go index 93f24425..0c5ce1ac 100644 --- a/lib/services/response.go +++ b/lib/services/response.go @@ -6,7 +6,7 @@ const ( ) func ErrResp(msg string) map[string]any { - return map[string]any{"code": CODE_FAIL, "message": msg} + return map[string]any{"code": CODE_FAIL, "msg": msg} } func DataResp(data any) map[string]any { @@ -14,7 +14,7 @@ func DataResp(data any) map[string]any { } func SuccMessageResp() map[string]any { - return map[string]any{"code": CODE_SUCC, "message": "success"} + return map[string]any{"code": CODE_SUCC, "msg": "success"} } func TotalResp(total int64) map[string]any { diff --git a/makefile b/makefile index 3db6ffa7..0ef01ac4 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,7 @@ ProjectL = omc ProjectU = OMC PROJECT = $(ProjectL) -VERSION = 2.2408.1 +VERSION = 2.2409.3 RelDate = `date +%Y%m%d` Release = $(RelDate) RelVer = $(VERSION)-$(RelDate) diff --git a/misc/omcsvc.sh b/misc/omcsvc.sh index 947c0f3b..ad242725 100644 --- a/misc/omcsvc.sh +++ b/misc/omcsvc.sh @@ -20,7 +20,7 @@ case "$1" in ;; stop) for procName in $ProcList;do - echo "Stoping $procName process ..." + echo "Stopping $procName process ..." systemctl stop $procName done ;; diff --git a/misc/setomc.sh b/misc/setomc.sh index e246f77e..d4c2b7fc 100644 --- a/misc/setomc.sh +++ b/misc/setomc.sh @@ -54,19 +54,19 @@ case "${M_ARG}" in ${OMCBinDir}/importdb.sh ${M_ARG} if [ "${C_ARG_LOWER}" != "" ]; then - CustomizedDir=${OMCStaticDir}/${C_ARG_LOWER}.d - if [ ! -d "${CustomizedDir}" ]; then - echo "Not found ${C_ARG_UPPER} customized directory, nothing to be done" - exit 1 - fi + CustomizedDir=${OMCStaticDir}/${C_ARG_LOWER}.d + if [ ! -d "${CustomizedDir}" ]; then + echo "Not found ${C_ARG_UPPER} customized directory, nothing to be done" + exit 1 + fi echo -n "Setting ${C_ARG_UPPER} customized OMC ..." - for SQL in ${CustomizedDir}/db/*.sql; do - mysql -u${USER} -p${PASSWORD} -P ${PORT} --protocol tcp -D ${DBNAME} < ${SQL}; - done - cp -rf ${CustomizedDir}/logo/* ${OMCStaticDir}/logo - cp -rf ${CustomizedDir}/doc/* ${OMCStaticDir}/helpDoc - #perl -0777 -i -pe 's/omcuser/bluearcus/g' ${OMCRootDir}/etc/default/restconf.yaml - #perl -0777 -i -pe 's/omcuser/bluearcus/g' ${OMCBinDir}/nehosts + for SQL in ${CustomizedDir}/db/*.sql; do + mysql -u${USER} -p${PASSWORD} -P ${PORT} --protocol tcp -D ${DBNAME} < ${SQL}; + done + cp -rf ${CustomizedDir}/logo/* ${OMCStaticDir}/logo + cp -rf ${CustomizedDir}/doc/* ${OMCStaticDir}/helpDoc + #perl -0777 -i -pe 's/omcuser/bluearcus/g' ${OMCRootDir}/etc/default/restconf.yaml + #perl -0777 -i -pe 's/omcuser/bluearcus/g' ${OMCBinDir}/nehosts if [ $? = 0 ]; then echo "done" fi @@ -77,17 +77,17 @@ case "${M_ARG}" in ;; skip) if [ "${C_ARG_LOWER}" != "" ]; then - CustomizedDir=${OMCStaticDir}/${C_ARG_LOWER}.d - if [ ! -d "${CustomizedDir}" ]; then - echo "Not found ${C_ARG_UPPER} customized directory, nothing to be done" - exit 1 - fi + CustomizedDir=${OMCStaticDir}/${C_ARG_LOWER}.d + if [ ! -d "${CustomizedDir}" ]; then + echo "Not found ${C_ARG_UPPER} customized directory, nothing to be done" + exit 1 + fi echo -n "Setting ${C_ARG_UPPER} customized OMC ..." - for SQL in ${CustomizedDir}/db/*.sql; do - mysql -u${USER} -p${PASSWORD} -P ${PORT} --protocol tcp -D ${DBNAME} < ${SQL}; - done - cp -rf ${CustomizedDir}/logo/* ${OMCStaticDir}/logo - cp -rf ${CustomizedDir}/doc/* ${OMCStaticDir}/helpDoc + for SQL in ${CustomizedDir}/db/*.sql; do + mysql -u${USER} -p${PASSWORD} -P ${PORT} --protocol tcp -D ${DBNAME} < ${SQL}; + done + cp -rf ${CustomizedDir}/logo/* ${OMCStaticDir}/logo + cp -rf ${CustomizedDir}/doc/* ${OMCStaticDir}/helpDoc if [ $? = 0 ]; then echo "done" fi diff --git a/mkpkg.sh b/mkpkg.sh index a7c96c3c..310beeb1 100644 --- a/mkpkg.sh +++ b/mkpkg.sh @@ -2,7 +2,7 @@ ProcList="restagent crontask sshsvc captrace data2html" ProjectL=omc -VERSION=2.2408.1 +VERSION=2.2409.3 RelDate=`date +%Y%m%d` Release=${RelDate} RelVer=${VERSION}-${RelDate} diff --git a/restagent/config/config.go b/restagent/config/config.go index 59585c83..aad08afd 100644 --- a/restagent/config/config.go +++ b/restagent/config/config.go @@ -1,14 +1,18 @@ package config import ( + "bufio" "fmt" "os" + "reflect" "strings" "be.ems/lib/global" "be.ems/lib/log" "gopkg.in/yaml.v3" + //"github.com/go-yaml-comment/yaml" + //"github.com/goccy/go-yaml" ) // Yaml struct of config @@ -146,30 +150,47 @@ type DbConfig struct { Backup string `yaml:"backup"` } +//type codingType int + +const ( + // Short message data coding type + CODING_UCS2 int = iota + CODING_ASCII + CODING_LATIN1 + CODING_NODEF +) + type AlarmConfig struct { - SplitEventAlarm bool `yaml:"splitEventAlarm"` - ForwardAlarm bool `yaml:"forwardAlarm"` - SMProxy string `yaml:"smProxy"` - Email struct { - Smtp string `yaml:"smtp"` - Port uint16 `yaml:"port"` - User string `yaml:"user"` - Password string `yaml:"password"` - TlsSkipVerify bool `yaml:"tlsSkipVerify"` - } `yaml:"email"` + SplitEventAlarm bool `yaml:"splitEventAlarm"` + //ForwardAlarm bool `yaml:"forwardAlarm"` + + EmailForward struct { + Enable bool `yaml:"enable" json:"enable"` + EmailList string `yaml:"emailList" json:"emailList"` + SMTP string `yaml:"smtp" json:"smtp"` + Port uint16 `yaml:"port" json:"port"` + User string `yaml:"user" json:"user"` + Password string `yaml:"password" json:"password"` + TLSSkipVerify bool `yaml:"tlsSkipVerify" json:"tlsSkipVerify"` + } `yaml:"alarmEmailForward"` + SMSCForward struct { + Enable bool `yaml:"enable" json:"enable"` + MobileList string `yaml:"mobileList" json:"mobileList"` + SMSCAddr string `yaml:"smscAddr" json:"smscAddr"` + SystemID string `yaml:"systemID" json:"systemID"` + Password string `yaml:"password" json:"password"` + SystemType string `yaml:"systemType" json:"systemType"` + DataCoding int `yaml:"dataCoding" json:"dataCoding"` + ServiceNumber string `yaml:"serviceNumber" json:"serviceNumber"` + } `yaml:"alarmSMSForward"` SMS struct { ApiURL string `yaml:"apiURL"` AccessKeyID string `yaml:"AccessKeyID"` AccessKeySecret string `yaml:"accessKeySecret"` SignName string `yaml:"signName"` TemplateCode string `yaml:"templateCode"` - } `yaml:"sms"` - SMSC struct { - Addr string `yaml:"addr"` - SystemID string `yaml:"systemID"` - Password string `yaml:"password"` - SystemType string `yaml:"systemType"` - } `yaml:"smsc"` + } `yaml:"smsForward"` + SMProxy string `yaml:"smProxy"` } type MMLParam struct { @@ -218,6 +239,16 @@ type TestDataMap struct { var yamlConfig YamlConfig = NewYamlConfig() +type YamlConfigFile struct { + FilePath string `json:"filePath"` + ConfigLines YamlConfig `json:"configLines"` + OrignalLines []string `json:"orignalLines"` +} + +var YamlConfigInfo YamlConfigFile = YamlConfigFile{ + ConfigLines: NewYamlConfig(), +} + // set default value for yaml config func NewYamlConfig() YamlConfig { return YamlConfig{ @@ -237,6 +268,8 @@ func NewYamlConfig() YamlConfig { } func ReadConfig(configFile string) { + YamlConfigInfo.FilePath = configFile + yamlFile, err := os.ReadFile(configFile) if err != nil { fmt.Println("Read yaml config file error:", err) @@ -244,25 +277,97 @@ func ReadConfig(configFile string) { } // fmt.Println("yamlfile:", string(yamlFile)) - err = yaml.Unmarshal(yamlFile, &yamlConfig) + err = yaml.Unmarshal(yamlFile, &YamlConfigInfo.ConfigLines) if err != nil { fmt.Println("Unmarshal error:", err) os.Exit(3) } + yamlConfig = YamlConfigInfo.ConfigLines + + ReadOriginalConfig(configFile) } -func WriteYamlConfig(newConfigData YamlConfig, configFile string) { +func ReadOriginalConfig(configFile string) { + // 读取原始YAML文件 + inputFile, err := os.Open(configFile) + if err != nil { + fmt.Println("failed to open:", err) + os.Exit(3) + } + defer inputFile.Close() + + scanner := bufio.NewScanner(inputFile) + for scanner.Scan() { + YamlConfigInfo.OrignalLines = append(YamlConfigInfo.OrignalLines, scanner.Text()) + } + + if err := scanner.Err(); err != nil { + fmt.Println("failed to scanner:", err) + os.Exit(3) + } +} + +func WriteOrignalConfig(configFile string, paramName string, paramData map[string]any) error { + lines := YamlConfigInfo.OrignalLines + for i, line := range lines { + if strings.Contains(line, paramName) { + for k, v := range paramData { + // find the first line nearby the paramName + for j := i + 1; j < len(lines); j++ { + if strings.Contains(lines[j], k+":") { + index := strings.Index(lines[j], k) + // Determine the type of v + switch v := v.(type) { + case string: + lines[j] = lines[j][:index] + fmt.Sprintf("%s: \"%s\"", k, v) + // case int: + // lines[j] = lines[j][:index] + fmt.Sprintf("%s: %d", k, v) + // case float64: + // lines[j] = lines[j][:index] + fmt.Sprintf("%s: %f", k, v) + case bool: + lines[j] = lines[j][:index] + fmt.Sprintf("%s: %t", k, v) + default: + lines[j] = lines[j][:index] + fmt.Sprintf("%s: %v", k, v) + } + break + } + } + } + break + } + } + + // write back to yaml file + outputFile, err := os.Create(configFile) + if err != nil { + fmt.Println(err) + return err + } + defer outputFile.Close() + + writer := bufio.NewWriter(outputFile) + for _, line := range YamlConfigInfo.OrignalLines { + writer.WriteString(line + "\n") + } + writer.Flush() + return nil +} + +func WriteYamlConfig(newConfigData YamlConfig, configFile string) error { // 将配置转换回YAML数据 newYamlData, err := yaml.Marshal(&newConfigData) if err != nil { log.Errorf("Failed to marshal YAML: %v", err) + return err } // 将新的YAML数据写入文件 err = os.WriteFile(configFile, newYamlData, 0644) if err != nil { log.Errorf("Failed to write YAML file: %v", err) + return err } + return nil } var mapYaml map[string]interface{} @@ -284,8 +389,28 @@ func ReadParamConfig(fileName string) *map[string]interface{} { return &mapYaml } +func UpdateStructFromMap(s any, updates map[string]any) { + v := reflect.ValueOf(s).Elem() + t := v.Type() + + for key, value := range updates { + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if field.Tag.Get("json") == key { + structField := v.FieldByName(field.Name) + if structField.IsValid() && structField.CanSet() { + if structField.Type() == reflect.TypeOf(value) { + structField.Set(reflect.ValueOf(value)) + } + } + break + } + } + } +} + func GetYamlConfig() *YamlConfig { - return &yamlConfig + return &YamlConfigInfo.ConfigLines } func GetAuthFromConfig() interface{} { diff --git a/restagent/etc/restconf.yaml b/restagent/etc/restconf.yaml index 7a707643..daddd30d 100644 --- a/restagent/etc/restconf.yaml +++ b/restagent/etc/restconf.yaml @@ -38,29 +38,29 @@ webServer: database: type: mysql user: root - password: 1000omc@kp! - host: 127.0.0.1 + password: "1000omc@kp!" + host: "127.0.0.1" port: 33066 name: tenants_db connParam: charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&interpolateParams=True backup: d:/local.git/be.ems/restagent/database -# Redis 缓存数据,数据源声明全小写 +# Redis data cache redis: dataSource: - # OMC系统使用库 + # OMC system db default: port: 6379 # Redis port host: "127.0.0.1" # Redis host password: "helloearth" db: 10 # Redis db_num - # UDM网元用户库 + # UDM sub/auth db udmuser: port: 6379 # Redis port host: "127.0.0.1" password: "helloearth" db: 0 # Redis db_num - # 多个数据源时可以用这个指定默认的数据源 + # used to specify the default data source for multiple data resourece defaultDataSourceName: "default" # sleep: time delay for after write buffer (millisecond) @@ -77,6 +77,12 @@ mml: password: admin mmlHome: ./mmlhome +# Tracking configuration +trace: + enabled: true + host: "172.16.5.100" # Fill in the specific IP address + port: 33033 + # NE config ne: user: omcuser @@ -123,29 +129,35 @@ omc: # Alarm module setting # Forward interface: +# TLS Skip verify: true/false # email/sms # smProxy: sms(Short Message Service)/smsc(SMS Centre) +# dataCoding: 0:UCS2, 1:ASCII, 2:LATIN1 alarm: - forwardAlarm: false - email: - smtp: mail.agrandtech.com + alarmEmailForward: + enable: true + emailList: + smtp: mail.smtp.com port: 25 - user: smtpext@agrandtech.com + user: smtpext@smtp.com password: "1000smtp@omc!" - # TLS skip verify: true/false tlsSkipVerify: true - smProxy: smsc + alarmSMSForward: + enable: true + mobileList: + smscAddr: "192.168.13.114:2775" + systemID: "omc" + password: "omc123" + systemType: "UTRAN" + dataCoding: 0 + serviceNumber: "OMC" sms: apiURL: http://smsc.xxx.com/ accessKeyID: xxxx accessKeySecret: xxxx signName: xxx SMSC templateCode: 1000 - smsc: - addr: "192.168.13.114:2775" - systemID: "omc" - password: "omc123" - systemType: "UTRAN" + smProxy: smsc #User authorized information # crypt: mysql/md5/bcrypt diff --git a/restagent/makefile b/restagent/makefile index 0b966149..10016cd3 100644 --- a/restagent/makefile +++ b/restagent/makefile @@ -1,7 +1,7 @@ # Makefile for rest agent project PROJECT = OMC -VERSION = 2.2408.1 +VERSION = 2.2409.3 PLATFORM = amd64 ARMPLATFORM = aarch64 BUILDDIR = ../../build diff --git a/restagent/restagent.go b/restagent/restagent.go index 723b37f4..9dd6abcc 100644 --- a/restagent/restagent.go +++ b/restagent/restagent.go @@ -213,6 +213,12 @@ func main() { fmt.Println("dborm.initDbClient err:", err) os.Exit(4) } + err = dborm.InitGormConnect(conf.Database.Type, conf.Database.User, conf.Database.Password, + conf.Database.Host, conf.Database.Port, conf.Database.Name, conf.Database.ConnParam, true) + if err != nil { + fmt.Println("dborm.InitGormConnect err:", err) + os.Exit(4) + } err = fm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password, conf.Database.Host, conf.Database.Port, conf.Database.Name, conf.Database.ConnParam) if err != nil { diff --git a/src/framework/config/config/config.default.yaml b/src/framework/config/config/config.default.yaml index 630aa427..1344060d 100644 --- a/src/framework/config/config/config.default.yaml +++ b/src/framework/config/config/config.default.yaml @@ -1,7 +1,7 @@ # 项目信息 framework: name: "OMC" - version: "2.2408.1" + version: "2.2409.3" # 应用服务配置 server: diff --git a/src/framework/socket/tcp_client.go b/src/framework/socket/tcp_client.go new file mode 100644 index 00000000..fb8899b5 --- /dev/null +++ b/src/framework/socket/tcp_client.go @@ -0,0 +1,96 @@ +package socket + +import ( + "bytes" + "fmt" + "net" + "strings" + "time" +) + +// ConnTCP 连接TCP客户端 +type ConnTCP struct { + Addr string `json:"addr"` // 主机地址 + Port int64 `json:"port"` // 端口 + + DialTimeOut time.Duration `json:"dialTimeOut"` // 连接超时断开 + + Client *net.Conn `json:"client"` + LastResult string `json:"lastResult"` // 记最后一次发送消息的结果 +} + +// New 创建TCP客户端 +func (c *ConnTCP) New() (*ConnTCP, error) { + // IPV6地址协议 + proto := "tcp" + if strings.Contains(c.Addr, ":") { + proto = "tcp6" + c.Addr = fmt.Sprintf("[%s]", c.Addr) + } + address := fmt.Sprintf("%s:%d", c.Addr, c.Port) + + // 默认等待5s + if c.DialTimeOut == 0 { + c.DialTimeOut = 5 * time.Second + } + + // 连接到服务端 + client, err := net.DialTimeout(proto, address, c.DialTimeOut) + if err != nil { + return nil, err + } + + c.Client = &client + return c, nil +} + +// Close 关闭当前TCP客户端 +func (c *ConnTCP) Close() { + if c.Client != nil { + (*c.Client).Close() + } +} + +// Send 发送消息 +func (c *ConnTCP) Send(msg []byte, timer time.Duration) (string, error) { + if c.Client == nil { + return "", fmt.Errorf("tcp client not connected") + } + conn := *c.Client + + // 写入信息 + if len(msg) > 0 { + if _, err := conn.Write(msg); err != nil { + return "", err + } + } + + var buf bytes.Buffer + defer buf.Reset() + + tmp := make([]byte, 1024) + for { + select { + case <-time.After(timer): + c.LastResult = buf.String() + return c.LastResult, fmt.Errorf("timeout") + default: + // 读取命令消息 + n, err := conn.Read(tmp) + if n == 0 || err != nil { + tmp = nil + break + } + + tmpStr := string(tmp[:n]) + buf.WriteString(tmpStr) + + // 是否有终止符 + if strings.HasSuffix(tmpStr, ">") || strings.HasSuffix(tmpStr, "> ") || strings.HasSuffix(tmpStr, "# ") { + tmp = nil + c.LastResult = buf.String() + return c.LastResult, nil + } + } + } +} diff --git a/src/framework/socket/tcp_server.go b/src/framework/socket/tcp_server.go new file mode 100644 index 00000000..52a9b960 --- /dev/null +++ b/src/framework/socket/tcp_server.go @@ -0,0 +1,83 @@ +package socket + +import ( + "fmt" + "net" + "strings" + + "be.ems/src/framework/logger" +) + +// SocketTCP TCP服务端 +type SocketTCP struct { + Addr string `json:"addr"` // 主机地址 + Port int64 `json:"port"` // 端口 + Listen *net.Listener `json:"listen"` + StopChan chan struct{} `json:"stop"` // 停止信号 +} + +// New 创建TCP服务端 +func (s *SocketTCP) New() (*SocketTCP, error) { + // IPV6地址协议 + proto := "tcp" + if strings.Contains(s.Addr, ":") { + proto = "tcp6" + s.Addr = fmt.Sprintf("[%s]", s.Addr) + } + address := fmt.Sprintf("%s:%d", s.Addr, s.Port) + + ln, err := net.Listen(proto, address) + if err != nil { + return nil, err + } + + s.Listen = &ln + s.StopChan = make(chan struct{}, 1) + return s, nil +} + +// Close 关闭当前TCP服务端 +func (s *SocketTCP) Close() { + if s.Listen != nil { + s.StopChan <- struct{}{} + (*s.Listen).Close() + } +} + +// Resolve 处理消息 +func (s *SocketTCP) Resolve(bufferSize int, callback func([]byte, int)) error { + if s.Listen == nil { + return fmt.Errorf("tcp service not created") + } + + ln := *s.Listen + buffer := make([]byte, bufferSize) + + for { + select { + case <-s.StopChan: + return fmt.Errorf("udp service stop") + default: + conn, err := ln.Accept() + if err != nil { + logger.Errorf("Error accepting connection: %v ", err) + continue + } + defer conn.Close() + + // 读取数据 + n, err := conn.Read(buffer) + if err != nil { + fmt.Println("Error reading from TCP connection:", err) + continue + } + + callback(buffer, n) + + // 发送响应 + if _, err = conn.Write([]byte("tcp>")); err != nil { + fmt.Println("Error sending response:", err) + } + } + } +} diff --git a/src/framework/socket/udp_client.go b/src/framework/socket/udp_client.go new file mode 100644 index 00000000..ecaa4864 --- /dev/null +++ b/src/framework/socket/udp_client.go @@ -0,0 +1,96 @@ +package socket + +import ( + "bytes" + "fmt" + "net" + "strings" + "time" +) + +// ConnUDP 连接UDP客户端 +type ConnUDP struct { + Addr string `json:"addr"` // 主机地址 + Port int64 `json:"port"` // 端口 + + DialTimeOut time.Duration `json:"dialTimeOut"` // 连接超时断开 + + Client *net.Conn `json:"client"` + LastResult string `json:"lastResult"` // 记最后一次发送消息的结果 +} + +// New 创建UDP客户端 +func (c *ConnUDP) New() (*ConnUDP, error) { + // IPV6地址协议 + proto := "udp" + if strings.Contains(c.Addr, ":") { + proto = "udp6" + c.Addr = fmt.Sprintf("[%s]", c.Addr) + } + address := fmt.Sprintf("%s:%d", c.Addr, c.Port) + + // 默认等待5s + if c.DialTimeOut == 0 { + c.DialTimeOut = 5 * time.Second + } + + // 连接到服务端 + client, err := net.DialTimeout(proto, address, c.DialTimeOut) + if err != nil { + return nil, err + } + + c.Client = &client + return c, nil +} + +// Close 关闭当前UDP客户端 +func (c *ConnUDP) Close() { + if c.Client != nil { + (*c.Client).Close() + } +} + +// Send 发送消息 +func (c *ConnUDP) Send(msg []byte, ms int) (string, error) { + if c.Client == nil { + return "", fmt.Errorf("udp client not connected") + } + conn := *c.Client + + // 写入信息 + if len(msg) > 0 { + if _, err := conn.Write(msg); err != nil { + return "", err + } + } + + var buf bytes.Buffer + defer buf.Reset() + + tmp := make([]byte, 1024) + for { + select { + case <-time.After(time.Duration(time.Duration(ms).Milliseconds())): + c.LastResult = buf.String() + return c.LastResult, fmt.Errorf("timeout") + default: + // 读取命令消息 + n, err := conn.Read(tmp) + if n == 0 || err != nil { + tmp = nil + break + } + + tmpStr := string(tmp[:n]) + buf.WriteString(tmpStr) + + // 是否有终止符 + if strings.HasSuffix(tmpStr, ">") || strings.HasSuffix(tmpStr, "> ") || strings.HasSuffix(tmpStr, "# ") { + tmp = nil + c.LastResult = buf.String() + return c.LastResult, nil + } + } + } +} diff --git a/src/framework/socket/udp_server.go b/src/framework/socket/udp_server.go new file mode 100644 index 00000000..d54b957a --- /dev/null +++ b/src/framework/socket/udp_server.go @@ -0,0 +1,80 @@ +package socket + +import ( + "fmt" + "net" + "strings" +) + +// SocketUDP UDP服务端 +type SocketUDP struct { + Addr string `json:"addr"` // 主机地址 + Port int64 `json:"port"` // 端口 + Conn *net.UDPConn `json:"conn"` + StopChan chan struct{} `json:"stop"` // 停止信号 +} + +// New 创建UDP服务端 +func (s *SocketUDP) New() (*SocketUDP, error) { + // IPV6地址协议 + proto := "udp" + if strings.Contains(s.Addr, ":") { + proto = "udp6" + s.Addr = fmt.Sprintf("[%s]", s.Addr) + } + address := fmt.Sprintf("%s:%d", s.Addr, s.Port) + + // 解析 UDP 地址 + udpAddr, err := net.ResolveUDPAddr(proto, address) + if err != nil { + return nil, err + } + + // 监听 UDP 地址 + conn, err := net.ListenUDP("udp", udpAddr) + if err != nil { + return nil, err + } + + s.Conn = conn + s.StopChan = make(chan struct{}, 1) + return s, nil +} + +// CloseService 关闭当前UDP服务端 +func (s *SocketUDP) Close() { + if s.Conn != nil { + s.StopChan <- struct{}{} + (*s.Conn).Close() + } +} + +// Resolve 处理消息 +func (s *SocketUDP) Resolve(bufferSize int, callback func([]byte, int)) error { + if s.Conn == nil { + return fmt.Errorf("udp service not created") + } + + buffer := make([]byte, bufferSize) + + for { + select { + case <-s.StopChan: + return fmt.Errorf("udp service stop") + default: + // 读取数据 + n, addr, err := s.Conn.ReadFromUDP(buffer) + if err != nil { + fmt.Println("Error reading from UDP connection:", err) + continue + } + + callback(buffer, n) + + // 发送响应 + if _, err = s.Conn.WriteToUDP([]byte("udp>"), addr); err != nil { + fmt.Println("Error sending response:", err) + } + } + } +} diff --git a/src/framework/utils/telnet/parse.go b/src/framework/telnet/parse.go similarity index 100% rename from src/framework/utils/telnet/parse.go rename to src/framework/telnet/parse.go diff --git a/src/framework/utils/telnet/telnet.go b/src/framework/telnet/telnet.go similarity index 89% rename from src/framework/utils/telnet/telnet.go rename to src/framework/telnet/telnet.go index 33579e94..8b2c2ec4 100644 --- a/src/framework/utils/telnet/telnet.go +++ b/src/framework/telnet/telnet.go @@ -50,11 +50,6 @@ func (c *ConnTelnet) NewClient() (*ConnTelnet, error) { // fmt.Fprintln(client, c.User) // fmt.Fprintln(client, c.Password) - // 调整窗口大小 (120 列 x 128 行) - // 需要确保接收方理解并正确处理发送窗口大小设置命令 - client.Write([]byte{255, 251, 31}) - client.Write([]byte{255, 250, 31, byte(120 >> 8), byte(120 & 0xFF), byte(128 >> 8), byte(128 & 0xFF), 255, 240}) - c.Client = &client // 排空连接登录的信息 @@ -116,6 +111,6 @@ func (c *ConnTelnet) NewClientSession(cols, rows int) (*TelnetClientSession, err s := &TelnetClientSession{ Client: *c.Client, } - s.WindowChange(cols, rows) + // s.WindowChange(cols, rows) return s, nil } diff --git a/src/framework/utils/telnet/telnet_session.go b/src/framework/telnet/telnet_session.go similarity index 97% rename from src/framework/utils/telnet/telnet_session.go rename to src/framework/telnet/telnet_session.go index 4d0cc59f..33994a56 100644 --- a/src/framework/utils/telnet/telnet_session.go +++ b/src/framework/telnet/telnet_session.go @@ -47,11 +47,11 @@ func (s *TelnetClientSession) Read() []byte { buf := make([]byte, 1024) // 设置读取超时时间为100毫秒 s.Client.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) - _, err := s.Client.Read(buf) + n, err := s.Client.Read(buf) if err != nil { return []byte{} } - return buf + return buf[:n] } // CombinedOutput 发送命令带结果返回 diff --git a/src/framework/utils/fetch/fetch.go b/src/framework/utils/fetch/fetch.go index 008b557a..be7cc07c 100644 --- a/src/framework/utils/fetch/fetch.go +++ b/src/framework/utils/fetch/fetch.go @@ -87,7 +87,7 @@ func Post(url string, data url.Values, headers map[string]string) ([]byte, error // PostJSON 发送 POST 请求,并将请求体序列化为 JSON 格式 func PostJSON(url string, data any, headers map[string]string) ([]byte, error) { client := &http.Client{ - Timeout: 3 * time.Second, // 超时时间 + Timeout: 10 * time.Second, // 超时时间 } jsonData, err := json.Marshal(data) @@ -180,7 +180,7 @@ func PostUploadFile(url string, params map[string]string, file *os.File) ([]byte // PutJSON 发送 PUT 请求,并将请求体序列化为 JSON 格式 func PutJSON(url string, data any, headers map[string]string) ([]byte, error) { client := &http.Client{ - Timeout: 3 * time.Second, // 超时时间 + Timeout: 10 * time.Second, // 超时时间 } jsonData, err := json.Marshal(data) diff --git a/src/framework/utils/parse/parse.go b/src/framework/utils/parse/parse.go index 67fb8317..a51e313f 100644 --- a/src/framework/utils/parse/parse.go +++ b/src/framework/utils/parse/parse.go @@ -17,46 +17,53 @@ import ( ) // Number 解析数值型 -func Number(str any) int64 { - switch str := str.(type) { +func Number(value any) int64 { + switch v := value.(type) { case string: - if str == "" { + if v == "" { return 0 } - num, err := strconv.ParseInt(str, 10, 64) + num, err := strconv.ParseInt(v, 10, 64) if err != nil { return 0 } return num - case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: - return reflect.ValueOf(str).Int() + case int, int8, int16, int32, int64: + return reflect.ValueOf(v).Int() + case uint, uint8, uint16, uint32, uint64: + return int64(reflect.ValueOf(v).Uint()) case float32, float64: - return int64(reflect.ValueOf(str).Float()) + return int64(reflect.ValueOf(v).Float()) + case bool: + if v { + return 1 + } + return 0 default: return 0 } } // Boolean 解析布尔型 -func Boolean(str any) bool { - switch str := str.(type) { +func Boolean(value any) bool { + switch v := value.(type) { case string: - if str == "" || str == "false" || str == "0" { + b, err := strconv.ParseBool(v) + if err != nil { return false } - // 尝试将字符串解析为数字 - if num, err := strconv.ParseFloat(str, 64); err == nil { - return num != 0 - } - return true - case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: - num := reflect.ValueOf(str).Int() + return b + case int, int8, int16, int32, int64: + num := reflect.ValueOf(v).Int() + return num != 0 + case uint, uint8, uint16, uint32, uint64: + num := int64(reflect.ValueOf(v).Uint()) return num != 0 case float32, float64: - num := reflect.ValueOf(str).Float() + num := reflect.ValueOf(v).Float() return num != 0 case bool: - return str + return v default: return false } diff --git a/src/modules/crontask/processor/exportTable/exportTable.go b/src/modules/crontask/processor/exportTable/exportTable.go index 8411f7ce..e0f8a986 100644 --- a/src/modules/crontask/processor/exportTable/exportTable.go +++ b/src/modules/crontask/processor/exportTable/exportTable.go @@ -8,7 +8,7 @@ import ( "os" "time" - "be.ems/lib/core/datasource" + "be.ems/lib/dborm" "be.ems/lib/log" "be.ems/src/framework/cron" ) @@ -103,7 +103,7 @@ func (s *BarProcessor) Execute(data any) (any, error) { } func (s *BarProcessor) exportData(query, filePath string) (int64, error) { - rows, err := datasource.DefaultDB().DB().Query(query) + rows, err := dborm.XCoreDB().Query(query) if err != nil { return 0, err } diff --git a/src/modules/monitor/controller/sys_cache.go b/src/modules/monitor/controller/sys_cache.go index 4c544efd..4baa442b 100644 --- a/src/modules/monitor/controller/sys_cache.go +++ b/src/modules/monitor/controller/sys_cache.go @@ -141,10 +141,8 @@ func (s *SysCacheController) ClearCacheKey(c *gin.Context) { func (s *SysCacheController) ClearCacheSafe(c *gin.Context) { language := ctx.AcceptLanguage(c) caches := []model.SysCache{ - model.NewSysCacheNames(i18n.TKey(language, "cache.name.user"), cachekey.LOGIN_TOKEN_KEY), model.NewSysCacheNames(i18n.TKey(language, "cache.name.sys_config"), cachekey.SYS_CONFIG_KEY), model.NewSysCacheNames(i18n.TKey(language, "cache.name.sys_dict"), cachekey.SYS_DICT_KEY), - model.NewSysCacheNames(i18n.TKey(language, "cache.name.captcha_codes"), cachekey.CAPTCHA_CODE_KEY), model.NewSysCacheNames(i18n.TKey(language, "cache.name.repeat_submit"), cachekey.REPEAT_SUBMIT_KEY), model.NewSysCacheNames(i18n.TKey(language, "cache.name.rate_limit"), cachekey.RATE_LIMIT_KEY), model.NewSysCacheNames(i18n.TKey(language, "cache.name.pwd_err_cnt"), cachekey.PWD_ERR_CNT_KEY), diff --git a/src/modules/monitor/service/system_info.impl.go b/src/modules/monitor/service/system_info.impl.go index a071a792..43feba5c 100644 --- a/src/modules/monitor/service/system_info.impl.go +++ b/src/modules/monitor/service/system_info.impl.go @@ -152,11 +152,11 @@ func (s *SystemInfoImpl) NetworkInfo() map[string]string { func (s *SystemInfoImpl) DiskInfo() []map[string]string { disks := make([]map[string]string, 0) ctx := context.Background() - ctx, cancel := context.WithTimeout(ctx, 1*time.Second) + ctx, cancel := context.WithTimeout(ctx, 2*time.Second) defer cancel() partitions, err := disk.PartitionsWithContext(ctx, false) - if err != context.DeadlineExceeded { + if err != nil && err != context.DeadlineExceeded { return disks } diff --git a/src/modules/network_data/controller/smf.go b/src/modules/network_data/controller/smf.go index 640fac58..e0aaf0df 100644 --- a/src/modules/network_data/controller/smf.go +++ b/src/modules/network_data/controller/smf.go @@ -15,6 +15,7 @@ import ( "be.ems/src/framework/vo/result" "be.ems/src/modules/network_data/model" neDataService "be.ems/src/modules/network_data/service" + neFetchlink "be.ems/src/modules/network_element/fetch_link" neService "be.ems/src/modules/network_element/service" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" @@ -22,8 +23,9 @@ import ( // 实例化控制层 SMFController 结构体 var NewSMFController = &SMFController{ - neInfoService: neService.NewNeInfoImpl, - cdrEventService: neDataService.NewCDREventSMFImpl, + neInfoService: neService.NewNeInfoImpl, + cdrEventService: neDataService.NewCDREventSMFImpl, + udmUserInfoService: *neDataService.NewUDMUserInfo, } // 网元SMF @@ -34,6 +36,8 @@ type SMFController struct { neInfoService neService.INeInfo // CDR会话事件服务 cdrEventService neDataService.ICDREventSMF + // UDM用户信息服务 + udmUserInfoService neDataService.UDMUserInfo } // CDR会话列表 @@ -263,3 +267,63 @@ PDU IPv6 Addres Swith Prefix: %s`, User_Identifier, SSC_Mode, RAT_Type, DNN_ID, c.FileAttachment(saveFilePath, fileName) } + +// 在线订阅用户列表信息 +// +// GET /subscribers +func (s *SMFController) SubUserList(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var query struct { + NeId string `form:"neId" binding:"required"` + IMSI string `form:"imsi"` + MSISDN string `form:"msisdn"` + Upstate string `form:"upstate"` + PageNum string `form:"pageNum"` + } + if err := c.ShouldBindQuery(&query); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询网元信息 rmUID + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("SMF", query.NeId) + if neInfo.NeId != query.NeId || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + // 网元直连 + data, err := neFetchlink.SMFSubInfo(neInfo, map[string]string{ + "imsi": query.IMSI, + "msisdn": query.MSISDN, + "upstate": query.Upstate, + "pageNum": query.PageNum, + }) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + + // 对数据进行处理,去掉前缀,并加入imsi拓展信息 + rows := data["rows"].([]any) + arr := &rows + for i := range *arr { + item := (*arr)[i].(map[string]any) + if v, ok := item["imsi"]; ok && v != nil { + imsiStr := v.(string) + imsiStr = strings.TrimPrefix(imsiStr, "imsi-") + item["imsi"] = imsiStr + // 查UDM拓展信息 + info := s.udmUserInfoService.SelectByIMSIAndNeID(imsiStr, "") + item["remark"] = info.Remark + } + if v, ok := item["msisdn"]; ok && v != nil { + item["msisdn"] = strings.TrimPrefix(v.(string), "msisdn-") + } + } + + c.JSON(200, result.Ok(map[string]any{ + "total": data["total"], + "rows": data["rows"], + })) +} diff --git a/src/modules/network_data/controller/udm_auth.go b/src/modules/network_data/controller/udm_auth.go index 525f5a6a..c893129c 100644 --- a/src/modules/network_data/controller/udm_auth.go +++ b/src/modules/network_data/controller/udm_auth.go @@ -8,10 +8,10 @@ import ( "be.ems/src/framework/constants/uploadsubpath" "be.ems/src/framework/i18n" + "be.ems/src/framework/telnet" "be.ems/src/framework/utils/ctx" "be.ems/src/framework/utils/file" "be.ems/src/framework/utils/parse" - "be.ems/src/framework/utils/telnet" "be.ems/src/framework/vo/result" "be.ems/src/modules/network_data/model" neDataService "be.ems/src/modules/network_data/service" @@ -23,7 +23,7 @@ import ( // 实例化控制层 UDMAuthController 结构体 var NewUDMAuth = &UDMAuthController{ - udmAuthService: neDataService.NewUDMAuthImpl, + udmAuthService: neDataService.NewUDMAuthUser, neInfoService: neService.NewNeInfoImpl, } @@ -32,7 +32,7 @@ var NewUDMAuth = &UDMAuthController{ // PATH /udm/auth type UDMAuthController struct { // UDM鉴权信息服务 - udmAuthService neDataService.IUDMAuth + udmAuthService *neDataService.UDMAuthUser // 网元信息服务 neInfoService neService.INeInfo } @@ -103,26 +103,9 @@ func (s *UDMAuthController) Info(c *gin.Context) { } neId = "" - u := model.UDMAuth{ - IMSI: imsi, - Amf: data["amf"], - Status: "1", - Ki: data["ki"], - AlgoIndex: data["algo"], - Opc: data["opc"], - NeId: neId, - } - - // 查询imsi存在赋予id用于更新 - list := s.udmAuthService.SelectList(u) - if len(list) > 0 { - item := list[0] - if item.ID != "" { - u.ID = item.ID - } - } - go s.udmAuthService.Insert(neId, u) - + // 解析返回的数据 + u := s.udmAuthService.ParseInfo(imsi, neId, data) + s.udmAuthService.Insert(neId, u) c.JSON(200, result.OkData(u)) } @@ -137,7 +120,7 @@ func (s *UDMAuthController) Add(c *gin.Context) { return } - var body model.UDMAuth + var body model.UDMAuthUser err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.IMSI == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -169,7 +152,7 @@ func (s *UDMAuthController) Add(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmAuthService.Insert(neId, body) + s.udmAuthService.Insert(neId, body) } c.JSON(200, result.OkData(data)) } @@ -186,7 +169,7 @@ func (s *UDMAuthController) Adds(c *gin.Context) { return } - var body model.UDMAuth + var body model.UDMAuthUser err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.IMSI == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -234,7 +217,7 @@ func (s *UDMAuthController) Edit(c *gin.Context) { return } - var body model.UDMAuth + var body model.UDMAuthUser err := c.ShouldBindBodyWith(&body, binding.JSON) if err != nil || body.IMSI == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -279,7 +262,7 @@ func (s *UDMAuthController) Edit(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmAuthService.Insert(neId, body) + s.udmAuthService.Insert(neId, body) } c.JSON(200, result.OkData(data)) } @@ -330,7 +313,7 @@ func (s *UDMAuthController) Remove(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmAuthService.Delete(neId, imsi) + s.udmAuthService.Delete(imsi, neId) } resultData[imsi] = data } @@ -402,7 +385,7 @@ func (s *UDMAuthController) Export(c *gin.Context) { } neId := "" - list := s.udmAuthService.SelectList(model.UDMAuth{NeId: neId}) + list := s.udmAuthService.SelectList(model.UDMAuthUser{NeId: neId}) // 文件名 fileName := fmt.Sprintf("udm_auth_user_export_%s_%d.%s", neId, time.Now().UnixMilli(), body.Type) filePath := fmt.Sprintf("%s/%s", file.ParseUploadFileDir(uploadsubpath.EXPORT), fileName) diff --git a/src/modules/network_data/controller/udm_sub.go b/src/modules/network_data/controller/udm_sub.go index 99c0d2b4..3578c89e 100644 --- a/src/modules/network_data/controller/udm_sub.go +++ b/src/modules/network_data/controller/udm_sub.go @@ -3,16 +3,15 @@ package controller import ( "fmt" "path/filepath" - "strconv" "strings" "time" "be.ems/src/framework/constants/uploadsubpath" "be.ems/src/framework/i18n" + "be.ems/src/framework/telnet" "be.ems/src/framework/utils/ctx" "be.ems/src/framework/utils/file" "be.ems/src/framework/utils/parse" - "be.ems/src/framework/utils/telnet" "be.ems/src/framework/vo/result" "be.ems/src/modules/network_data/model" neDataService "be.ems/src/modules/network_data/service" @@ -23,7 +22,7 @@ import ( // 实例化控制层 UDMSubController 结构体 var NewUDMSub = &UDMSubController{ - udmSubService: neDataService.NewUDMSubImpl, + udmSubService: neDataService.NewUDMSub, neInfoService: neService.NewNeInfoImpl, } @@ -32,7 +31,7 @@ var NewUDMSub = &UDMSubController{ // PATH /udm/sub type UDMSubController struct { // UDM签约信息服务 - udmSubService neDataService.IUDMSub + udmSubService *neDataService.UDMSubUser // 网元信息服务 neInfoService neService.INeInfo } @@ -103,53 +102,10 @@ func (s *UDMSubController) Info(c *gin.Context) { return } - // 解析返回的数据 - cnType, _ := strconv.ParseInt(data["CNType"][:4], 0, 64) - rat, _ := strconv.ParseInt(data["RAT"][:4], 0, 64) - msisdn := data["MSISDN"] - imsMsisdnLen := strings.Index(msisdn, ",") - if imsMsisdnLen != -1 { - msisdn = msisdn[:imsMsisdnLen] - } neId = "" - u := model.UDMSub{ - IMSI: imsi, - Msisdn: msisdn, - Ambr: data["AMBR"], - Arfb: data["AreaForbidden"], - Cn: fmt.Sprint(cnType), - SmData: data["SM-Data(snssai+dnn[1..n])"], - Sar: data["ServiceAreaRestriction"], - Nssai: data["NSSAI"], - SmfSel: data["Smf-Selection"], - Rat: fmt.Sprint(rat), - NeId: neId, - } - // 1,64,24,65,def_eps,1,2,010200000000,- - if v, ok := data["EPS-Data"]; ok { - u.EpsDat = v - arr := strings.Split(v, ",") - u.EpsFlag = arr[0] - u.EpsOdb = arr[1] - u.HplmnOdb = arr[2] - u.Ard = arr[3] - u.Epstpl = arr[4] - u.ContextId = arr[5] - u.ApnContext = arr[7] - // [6] 是不要的,导入和导出不用 - u.StaticIp = arr[8] - } - - // 查询imsi存在赋予id用于更新 - list := s.udmSubService.SelectList(u) - if len(list) > 0 { - item := list[0] - if item.ID != "" { - u.ID = item.ID - } - } - go s.udmSubService.Insert(neId, u) - + // 解析返回的数据 + u := s.udmSubService.ParseInfo(imsi, neId, data) + s.udmSubService.Insert(neId, u) c.JSON(200, result.OkData(u)) } @@ -164,9 +120,9 @@ func (s *UDMSubController) Add(c *gin.Context) { return } - var body model.UDMSub + var body model.UDMSubUser err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || body.IMSI == "" { + if err != nil || len(body.IMSI) < 15 { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -186,8 +142,8 @@ func (s *UDMSubController) Add(c *gin.Context) { defer telnetClient.Close() // 发送MML - cmd := fmt.Sprintf("add udmuser:imsi=%s,msisdn=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s", - body.IMSI, body.Msisdn, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext) + cmd := fmt.Sprintf("add udmuser:imsi=%s,msisdn=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s,cag=%s", + body.IMSI, body.MSISDN, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext, body.Cag) // static_ip指给4G UE分配的静态IP,没有可不带此字段名,批量添加IP会自动递增 if body.StaticIp != "" { cmd += fmt.Sprintf(",static_ip=%s", body.StaticIp) @@ -201,7 +157,8 @@ func (s *UDMSubController) Add(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.Insert(neId, body) + body.NeId = neId + s.udmSubService.Insert(neId, body) } c.JSON(200, result.OkData(data)) } @@ -218,9 +175,9 @@ func (s *UDMSubController) Adds(c *gin.Context) { return } - var body model.UDMSub + var body model.UDMSubUser err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || body.IMSI == "" { + if err != nil || len(body.IMSI) < 15 { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -240,8 +197,8 @@ func (s *UDMSubController) Adds(c *gin.Context) { defer telnetClient.Close() // 发送MML - cmd := fmt.Sprintf("baa udmuser:start_imsi=%s,start_msisdn=%s,sub_num=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s", - body.IMSI, body.Msisdn, num, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext) + cmd := fmt.Sprintf("baa udmuser:start_imsi=%s,start_msisdn=%s,sub_num=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s,cag=%s", + body.IMSI, body.MSISDN, num, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext, body.Cag) // static_ip指给4G UE分配的静态IP,没有可不带此字段名,批量添加IP会自动递增 if body.StaticIp != "" { cmd += fmt.Sprintf(",static_ip=%s", body.StaticIp) @@ -255,7 +212,7 @@ func (s *UDMSubController) Adds(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.LoadData(neId, body.IMSI, num) + go s.udmSubService.LoadData(neId, body.IMSI, num, body.Remark) } c.JSON(200, result.OkData(data)) } @@ -271,9 +228,9 @@ func (s *UDMSubController) Edit(c *gin.Context) { return } - var body model.UDMSub + var body model.UDMSubUser err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || body.IMSI == "" { + if err != nil || len(body.IMSI) < 15 { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -295,8 +252,8 @@ func (s *UDMSubController) Edit(c *gin.Context) { // 发送MML cmd := fmt.Sprintf("mod udmuser:imsi=%s", body.IMSI) // 修改的参数名称 - if body.Msisdn != "" { - cmd += fmt.Sprintf(",msisdn=%s", body.Msisdn) + if body.MSISDN != "" { + cmd += fmt.Sprintf(",msisdn=%s", body.MSISDN) } if body.Ambr != "" { cmd += fmt.Sprintf(",ambr=%s", body.Ambr) @@ -346,6 +303,9 @@ func (s *UDMSubController) Edit(c *gin.Context) { if body.ApnContext != "" { cmd += fmt.Sprintf(",apn_context=%s", body.ApnContext) } + if body.Cag != "" { + cmd += fmt.Sprintf(",cag=%s", body.Cag) + } if body.StaticIp != "" { cmd += fmt.Sprintf(",static_ip=%s", body.StaticIp) } @@ -358,7 +318,8 @@ func (s *UDMSubController) Edit(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.Insert(neId, body) + body.NeId = neId + s.udmSubService.Insert(neId, body) } c.JSON(200, result.OkData(data)) } @@ -370,7 +331,7 @@ func (s *UDMSubController) Remove(c *gin.Context) { language := ctx.AcceptLanguage(c) neId := c.Param("neId") imsi := c.Param("imsi") - if neId == "" || imsi == "" { + if neId == "" || len(imsi) < 15 { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -409,7 +370,7 @@ func (s *UDMSubController) Remove(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.Delete(neId, imsi) + s.udmSubService.Delete(neId, imsi) } resultData[imsi] = data } @@ -425,7 +386,7 @@ func (s *UDMSubController) Removes(c *gin.Context) { neId := c.Param("neId") imsi := c.Param("imsi") num := c.Param("num") - if neId == "" || imsi == "" || num == "" { + if neId == "" || len(imsi) < 15 || num == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -455,7 +416,8 @@ func (s *UDMSubController) Removes(c *gin.Context) { // 命令ok时 if strings.Contains(data, "ok") { neId = "" - go s.udmSubService.LoadData(neId, imsi, num) + go s.udmSubService.LoadData(neId, imsi, num, "-(Deleted)-") + } c.JSON(200, result.OkData(data)) } @@ -481,7 +443,7 @@ func (s *UDMSubController) Export(c *gin.Context) { } neId := "" - list := s.udmSubService.SelectList(model.UDMSub{NeId: neId}) + list := s.udmSubService.SelectList(model.UDMSubUser{NeId: neId}) // 文件名 fileName := fmt.Sprintf("udm_sub_user_export_%s_%d.%s", neId, time.Now().UnixMilli(), body.Type) filePath := fmt.Sprintf("%s/%s", file.ParseUploadFileDir(uploadsubpath.EXPORT), fileName) @@ -492,7 +454,7 @@ func (s *UDMSubController) Export(c *gin.Context) { data = append(data, []string{"imsi", "msisdn", "ambr", "nssai", "arfb", "sar", "rat", "cn", "smf_sel", "sm_dat", "eps_dat"}) for _, v := range list { epsDat := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s", v.EpsFlag, v.EpsOdb, v.HplmnOdb, v.Ard, v.Epstpl, v.ContextId, v.ApnContext, v.StaticIp) - data = append(data, []string{v.IMSI, v.Msisdn, v.Ambr, v.Nssai, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, epsDat}) + data = append(data, []string{v.IMSI, v.MSISDN, v.Ambr, v.Nssai, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, epsDat}) } // 输出到文件 err = file.WriterFileCSV(data, filePath) @@ -507,7 +469,7 @@ func (s *UDMSubController) Export(c *gin.Context) { data := [][]string{} for _, v := range list { epsDat := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s", v.EpsFlag, v.EpsOdb, v.HplmnOdb, v.Ard, v.Epstpl, v.ContextId, v.ApnContext, v.StaticIp) - data = append(data, []string{v.IMSI, v.Msisdn, v.Ambr, v.Nssai, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, epsDat}) + data = append(data, []string{v.IMSI, v.MSISDN, v.Ambr, v.Nssai, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, epsDat}) } // 输出到文件 err = file.WriterFileTXT(data, ",", filePath) diff --git a/src/modules/network_data/controller/upf.go b/src/modules/network_data/controller/upf.go index aa3ef337..366fc15d 100644 --- a/src/modules/network_data/controller/upf.go +++ b/src/modules/network_data/controller/upf.go @@ -32,9 +32,8 @@ type UPFController struct { func (s *UPFController) TotalFlow(c *gin.Context) { language := ctx.AcceptLanguage(c) var querys struct { - NeType string `json:"neType" form:"neType" binding:"required"` - NeID string `form:"neId" binding:"required"` - Day int `form:"day" binding:"required"` + NeID string `form:"neId" binding:"required"` + Day int `form:"day" binding:"required"` } if err := c.ShouldBindQuery(&querys); querys.Day < 0 || err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -42,7 +41,7 @@ func (s *UPFController) TotalFlow(c *gin.Context) { } // 查询网元获取IP - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UPF", querys.NeID) if neInfo.NeId != querys.NeID || neInfo.IP == "" { c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return diff --git a/src/modules/network_data/model/udm_auth.go b/src/modules/network_data/model/udm_auth.go index 6f7c1d17..57ee012b 100644 --- a/src/modules/network_data/model/udm_auth.go +++ b/src/modules/network_data/model/udm_auth.go @@ -1,17 +1,18 @@ package model -// UDMAuth UDM鉴权用户对象 u_auth_user -type UDMAuth struct { +// UDMAuthUser UDM鉴权用户 u_auth_user +type UDMAuthUser struct { ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 默认ID - IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡号 - Amf string `json:"amf" gorm:"column:amf"` // ANF - Status string `json:"status" gorm:"column:status"` // 状态 默认给1 - Ki string `json:"ki" gorm:"column:ki"` // ki - AlgoIndex string `json:"algoIndex" gorm:"column:algo_index"` // AlgoIndex - Opc string `json:"opc" gorm:"column:opc"` // opc - NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统 + IMSI string `json:"imsi" gorm:"imsi"` // SIM卡/USIM卡ID + NeId string `json:"neId" gorm:"ne_id"` // UDM网元标识 + Amf string `json:"amf" gorm:"amf"` // AMF + Status string `json:"status" gorm:"status"` // 状态 + Ki string `json:"ki" gorm:"ki"` // ki + AlgoIndex string `json:"algoIndex" gorm:"algo_index"` // algoIndex + Opc string `json:"opc" gorm:"opc"` // OPC } -func (UDMAuth) TableName() string { +// TableName 表名称 +func (*UDMAuthUser) TableName() string { return "u_auth_user" } diff --git a/src/modules/network_data/model/udm_sub.go b/src/modules/network_data/model/udm_sub.go index e3d05c4c..bc80ccae 100644 --- a/src/modules/network_data/model/udm_sub.go +++ b/src/modules/network_data/model/udm_sub.go @@ -1,36 +1,39 @@ package model -// UDMSub UDM签约用户对象 u_sub_user -type UDMSub struct { - ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` - Msisdn string `json:"msisdn" gorm:"column:msisdn"` // 相当手机号 - IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡号 - Ambr string `json:"ambr" gorm:"column:ambr"` - Nssai string `json:"nssai" gorm:"column:nssai"` - Rat string `json:"rat" gorm:"column:rat"` - Arfb string `json:"arfb" gorm:"column:arfb"` - Sar string `json:"sar" gorm:"column:sar"` - Cn string `json:"cn" gorm:"column:cn"` - SmData string `json:"smData" gorm:"column:sm_data"` - SmfSel string `json:"smfSel" gorm:"column:smf_sel"` - EpsDat string `json:"epsDat" gorm:"column:eps_dat"` - NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统 +// UDMSubUser UDM签约用户 u_sub_user +type UDMSubUser struct { + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键 + IMSI string `json:"imsi" gorm:"imsi"` // SIM卡/USIM卡ID + MSISDN string `json:"msisdn" gorm:"msisdn"` // 用户电话号码 + NeId string `json:"neId" gorm:"ne_id"` // UDM网元标识 + Ambr string `json:"ambr" gorm:"ambr"` // SubUeAMBRTemp + Nssai string `json:"nssai" gorm:"nssai"` // SubSNSSAITemp + Rat string `json:"rat" gorm:"rat"` // rat VIRTUAL|WLAN|EUTRA|NR + Arfb string `json:"arfb" gorm:"arfb"` // forbiddenAreasTemp + Sar string `json:"sar" gorm:"sar"` // serviceAreaRestrictTemp + Cn string `json:"cn" gorm:"cn"` // cnType EPC|5GC + SmData string `json:"smData" gorm:"sm_data"` // smData + SmfSel string `json:"smfSel" gorm:"smf_sel"` // smfSel + EpsDat string `json:"epsDat" gorm:"eps_dat"` // Eps + EpsFlag string `json:"epsFlag" gorm:"eps_flag"` // epsFlag + EpsOdb string `json:"epsOdb" gorm:"eps_odb"` // epsOdb + HplmnOdb string `json:"hplmnOdb" gorm:"hplmn_odb"` // hplmnOdb + Ard string `json:"ard" gorm:"ard"` // Ard + Epstpl string `json:"epstpl" gorm:"epstpl"` // Epstpl + ContextId string `json:"contextId" gorm:"context_id"` // ContextId + ApnContext string `json:"apnContext" gorm:"apn_context"` // apnContext + StaticIp string `json:"staticIp" gorm:"static_ip"` // staticIpstatic_ip指给4G UE分配的静态IP,没有可不带此字段名 + Cag string `json:"cag" gorm:"cag"` // CAG - EpsFlag string `json:"epsFlag" gorm:"column:eps_flag"` - EpsOdb string `json:"epsOdb" gorm:"column:eps_odb"` - HplmnOdb string `json:"hplmnOdb" gorm:"column:hplmn_odb"` - Ard string `json:"ard" gorm:"column:ard"` - Epstpl string `json:"epstpl" gorm:"column:epstpl"` - ContextId string `json:"contextId" gorm:"column:context_id"` - ApnContext string `json:"apnContext" gorm:"column:apn_context"` - StaticIp string `json:"staticIp" gorm:"column:static_ip"` TenantID string `json:"tenantID" gorm:"column:tenant_id"` TenantName string `json:"tenantName" gorm:"-"` // ====== 非数据库字段属性 ====== + Remark string `json:"remark,omitempty" gorm:"-"` // 备注 } -func (UDMSub) TableName() string { +// TableName 表名称 +func (*UDMSubUser) TableName() string { return "u_sub_user" } diff --git a/src/modules/network_data/model/udm_user_info.go b/src/modules/network_data/model/udm_user_info.go new file mode 100644 index 00000000..470a9abc --- /dev/null +++ b/src/modules/network_data/model/udm_user_info.go @@ -0,0 +1,15 @@ +package model + +// UDMUserInfo UDM用户IMSI扩展信息 u_user_info +type UDMUserInfo struct { + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 默认ID + IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID + MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码 + NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统 + Remark string `json:"remark" gorm:"remark"` // 备注 +} + +// TableName 表名称 +func (*UDMUserInfo) TableName() string { + return "u_user_info" +} diff --git a/src/modules/network_data/network_data.go b/src/modules/network_data/network_data.go index 69b513d8..e60cdd9f 100644 --- a/src/modules/network_data/network_data.go +++ b/src/modules/network_data/network_data.go @@ -97,6 +97,10 @@ func Setup(router *gin.Engine) { collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smfCDR", collectlogs.BUSINESS_TYPE_EXPORT)), controller.NewSMFController.CDRExport, ) + smfGroup.GET("/subscribers", + middleware.PreAuthorize(nil), + controller.NewSMFController.SubUserList, + ) } // 网元AMF diff --git a/src/modules/network_data/repository/udm_auth.go b/src/modules/network_data/repository/udm_auth.go index 90a3bea8..25f46684 100644 --- a/src/modules/network_data/repository/udm_auth.go +++ b/src/modules/network_data/repository/udm_auth.go @@ -1,26 +1,206 @@ package repository import ( + "fmt" + "strings" + + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" "be.ems/src/modules/network_data/model" ) -// UDM鉴权信息 数据层接口 -type IUDMAuth interface { - // ClearAndInsert 清空ne_id后新增实体 - ClearAndInsert(neId string, uArr []model.UDMAuth) int64 +// 实例化数据层 UDMAuthUser 结构体 +var NewUDMAuthUser = &UDMAuthUser{ + selectSql: `select id, imsi, ne_id, amf, status, ki, algo_index, opc from u_auth_user`, - // SelectPage 根据条件分页查询 - SelectPage(query map[string]any) map[string]any - - // SelectList 根据实体查询 - SelectList(u model.UDMAuth) []model.UDMAuth - - // Insert 批量添加 - Inserts(uArr []model.UDMAuth) int64 - - // Delete 删除实体 - Delete(neId, imsi string) int64 - - // DeletePrefixByIMSI 删除前缀匹配的实体 - DeletePrefixByIMSI(neId, imsi string) int64 + resultMap: map[string]string{ + "id": "ID", + "imsi": "IMSI", + "ne_id": "NeId", + "amf": "Amf", + "status": "Status", + "ki": "Ki", + "algo_index": "AlgoIndex", + "opc": "Opc", + }, +} + +// UDMAuthUser UDM鉴权信息表 数据层处理 +type UDMAuthUser struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *UDMAuthUser) convertResultRows(rows []map[string]any) []model.UDMAuthUser { + arr := make([]model.UDMAuthUser, 0) + for _, row := range rows { + item := model.UDMAuthUser{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + repo.SetFieldValue(&item, keyMapper, value) + } + } + arr = append(arr, item) + } + return arr +} + +// ClearAndInsert 清空ne_id后新增实体 +func (r *UDMAuthUser) ClearAndInsert(neId string, uArr []model.UDMAuthUser) int64 { + // 不指定neID时,用 TRUNCATE 清空表快 + _, err := datasource.ExecDB("", "TRUNCATE TABLE u_auth_user", nil) + if err != nil { + logger.Errorf("TRUNCATE err => %v", err) + } + return r.Inserts(uArr) +} + +// SelectPage 根据条件分页查询 +func (r *UDMAuthUser) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["imsi"]; ok && v != "" { + conditions = append(conditions, "imsi like concat(concat('%', ?), '%')") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["neId"]; ok && v != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, v) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.UDMAuthUser{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from u_auth_user" + 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(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 排序 + orderSql := "" + if v, ok := query["sortField"]; ok && v != "" { + sortSql := v.(string) + if o, ok := query["sortOrder"]; ok && o != nil && v != "" { + if o == "desc" { + sortSql += " desc " + } else { + sortSql += " asc " + } + } + orderSql = fmt.Sprintf(" order by %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 +} + +// SelectList 根据实体查询 +func (r *UDMAuthUser) SelectList(u model.UDMAuthUser) []model.UDMAuthUser { + // 查询条件拼接 + var conditions []string + var params []any + if u.IMSI != "" { + conditions = append(conditions, "imsi = ?") + params = append(params, u.IMSI) + } + if u.NeId != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, u.NeId) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by imsi asc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIMSIAndNeID 通过imsi和ne_id查询 +func (r *UDMAuthUser) SelectByIMSIAndNeID(imsi, neId string) model.UDMAuthUser { + querySql := r.selectSql + " where imsi = ? and ne_id = ?" + results, err := datasource.RawDB("", querySql, []any{imsi, neId}) + if err != nil { + logger.Errorf("query err => %v", err) + return model.UDMAuthUser{} + } + // 转换实体 + rows := r.convertResultRows(results) + if len(rows) > 0 { + return rows[0] + } + return model.UDMAuthUser{} +} + +// Insert 批量添加 +func (r *UDMAuthUser) Inserts(uArr []model.UDMAuthUser) int64 { + tx := datasource.DefaultDB().CreateInBatches(uArr, 3000) + if err := tx.Error; err != nil { + logger.Errorf("CreateInBatches err => %v", err) + } + return tx.RowsAffected +} + +// Delete 删除实体 +func (r *UDMAuthUser) Delete(imsi, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMAuthUser{}) + if err := tx.Error; err != nil { + logger.Errorf("Delete err => %v", err) + } + return tx.RowsAffected +} + +// DeletePrefixByIMSI 删除前缀匹配的实体 +func (r *UDMAuthUser) DeletePrefixByIMSI(neId, imsi string) int64 { + tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsi, neId).Delete(&model.UDMAuthUser{}) + if err := tx.Error; err != nil { + logger.Errorf("DeletePrefixByIMSI err => %v", err) + } + return tx.RowsAffected } diff --git a/src/modules/network_data/repository/udm_sub.go b/src/modules/network_data/repository/udm_sub.go index db8db0f8..635dc62d 100644 --- a/src/modules/network_data/repository/udm_sub.go +++ b/src/modules/network_data/repository/udm_sub.go @@ -1,26 +1,288 @@ package repository import ( + "fmt" + "strings" + + dborm "be.ems/lib/core/datasource" + "be.ems/lib/log" + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" "be.ems/src/modules/network_data/model" ) -// UDM签约信息 数据层接口 -type IUDMSub interface { - // ClearAndInsert 清空ne_id后新增实体 - ClearAndInsert(neId string, uArr []model.UDMSub) int64 +// 实例化数据层 UDMSubUser 结构体 +var NewUDMSub = &UDMSubUser{ + selectSql: `select + s.id, s.msisdn, s.imsi, s.ambr, s.nssai, s.rat, s.arfb, s.sar, s.cn, s.sm_data, s.smf_sel, s.eps_dat, + s.ne_id, s.eps_flag, s.eps_odb, s.hplmn_odb, s.ard, s.epstpl, s.context_id, s.apn_context, s.static_ip, + s.cag, + t.tenant_id, t.tenant_name + from u_sub_user s + left join sys_tenant t on t.tenant_id = s.tenant_id`, - // SelectPage 根据条件分页查询 - SelectPage(query map[string]any) map[string]any + resultMap: map[string]string{ + "id": "ID", + "imsi": "IMSI", + "msisdn": "MSISDN", + "ne_id": "NeId", + "ambr": "Ambr", + "nssai": "Nssai", + "rat": "Rat", + "arfb": "Arfb", + "sar": "Sar", + "cn": "Cn", + "sm_data": "SmData", + "smf_sel": "SmfSel", + "eps_dat": "EpsDat", + "eps_flag": "EpsFlag", + "eps_odb": "EpsOdb", + "hplmn_odb": "HplmnOdb", + "ard": "Ard", + "epstpl": "Epstpl", + "context_id": "ContextId", + "apn_context": "ApnContext", + "static_ip": "StaticIp", + "cag": "Cag", - // SelectList 根据实体查询 - SelectList(u model.UDMSub) []model.UDMSub - - // Insert 批量添加 - Inserts(uArr []model.UDMSub) int64 - - // Delete 删除实体 - Delete(neId, imsi string) int64 - - // DeletePrefixByIMSI 删除前缀匹配的实体 - DeletePrefixByIMSI(neId, imsi string) int64 + "tenant_id": "TenantID", + "tenant_name": "TenantName", // Tenant name for multi-tenancy + }, +} + +// UDMSubUser UDM签约信息表 数据层处理 +type UDMSubUser struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *UDMSubUser) convertResultRows(rows []map[string]any) []model.UDMSubUser { + arr := make([]model.UDMSubUser, 0) + for _, row := range rows { + item := model.UDMSubUser{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + repo.SetFieldValue(&item, keyMapper, value) + } + } + arr = append(arr, item) + } + return arr +} + +// ClearAndInsert 清空ne_id后新增实体 +func (r *UDMSubUser) ClearAndInsert(neID string, u []model.UDMSubUser) int64 { + // 不指定neID时,用 TRUNCATE 清空表快 + _, err := datasource.ExecDB("", "TRUNCATE TABLE u_sub_user", nil) + if err != nil { + logger.Errorf("TRUNCATE err => %v", err) + } + + return r.Inserts(u) +} + +// SelectPage 根据条件分页查询字典类型 +func (r *UDMSubUser) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["msisdn"]; ok && v != "" { + conditions = append(conditions, "msisdn like concat(concat('%', ?), '%')") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["imsi"]; ok && v != "" { + //conditions = append(conditions, "imsi like concat(concat('%', ?), '%')") + //params = append(params, strings.Trim(v.(string), " ")) + conditions = append(conditions, "imsi like ?") + params = append(params, v) + } + if v, ok := query["neId"]; ok && v != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, v) + } + // for multi-tenancy solution + if v, ok := query["tenantName"]; ok && v != "" { + var tenantID []string + err := dborm.DefaultDB().Table("sys_tenant"). + Where("tenant_name=?", v).Cols("tenant_id").Distinct().Find(&tenantID) + if err != nil { + log.Errorf("Find tenant_id from sys_user err => %v", err) + } + log.Tracef("userName=%v, tenantID=%v", v, tenantID) + if len(tenantID) > 0 { + conditions = append(conditions, "s.tenant_id = ?") + params = append(params, tenantID[0]) + } + } else if v, ok := query["userName"]; ok && v != "" { + var tenantID string + _, err := dborm.DefaultDB().Table("sys_user"). + Where("user_name=?", v).Cols("tenant_id").Distinct().Get(&tenantID) + if err != nil { + log.Errorf("Find tenant_id from sys_user err => %v", err) + } + log.Tracef("userName=%v, tenantID=%v", v, tenantID) + if tenantID != "" { + conditions = append(conditions, "s.tenant_id = ?") + params = append(params, tenantID) + } + // if len(tenantID) > 0 { + // conditions = append(conditions, "s.tenant_id = ?") + // params = append(params, tenantID[0]) + // } + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.UDMSubUser{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from u_sub_user s" + 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(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 排序 + orderSql := "" + if v, ok := query["sortField"]; ok && v != "" { + sortSql := v.(string) + if o, ok := query["sortOrder"]; ok && o != nil && v != "" { + if o == "desc" { + sortSql += " desc " + } else { + sortSql += " asc " + } + } + orderSql = fmt.Sprintf(" order by %s ", sortSql) + } + + // 查询数据 + querySql := r.selectSql + whereSql + orderSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + return result + } + + // 转换实体 + result["rows"] = r.convertResultRows(results) + return result +} + +// SelectList 根据实体查询 +func (r *UDMSubUser) SelectList(u model.UDMSubUser) []model.UDMSubUser { + // 查询条件拼接 + var conditions []string + var params []any + if u.IMSI != "" { + conditions = append(conditions, "imsi = ?") + params = append(params, u.IMSI) + } + if u.NeId != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, u.NeId) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by imsi asc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIMSIAndNeID 通过imsi和ne_id查询 +func (r *UDMSubUser) SelectByIMSIAndNeID(imsi, neId string) model.UDMSubUser { + querySql := r.selectSql + " where imsi = ? and ne_id = ?" + results, err := datasource.RawDB("", querySql, []any{imsi, neId}) + if err != nil { + logger.Errorf("query err => %v", err) + return model.UDMSubUser{} + } + // 转换实体 + rows := r.convertResultRows(results) + if len(rows) > 0 { + return rows[0] + } + return model.UDMSubUser{} +} + +// Insert 批量添加 +func (r *UDMSubUser) Inserts(uArr []model.UDMSubUser) int64 { + // multi-tenancy + r.SetTenantID(&uArr) + + tx := datasource.DefaultDB().CreateInBatches(uArr, 2000) + if err := tx.Error; err != nil { + logger.Errorf("CreateInBatches err => %v", err) + } + return tx.RowsAffected +} + +// Delete 删除实体 +func (r *UDMSubUser) Delete(imsi, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMSubUser{}) + if err := tx.Error; err != nil { + logger.Errorf("Delete err => %v", err) + } + return tx.RowsAffected +} + +// DeletePrefixByIMSI 删除前缀匹配的实体 +func (r *UDMSubUser) DeletePrefixByIMSI(imsiPrefix, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsiPrefix, neId).Delete(&model.UDMSubUser{}) + if err := tx.Error; err != nil { + logger.Errorf("DeletePrefixByIMSI err => %v", err) + } + return tx.RowsAffected +} + +func (r *UDMSubUser) SetTenantID(subArr *[]model.UDMSubUser) { + for s := 0; s < len(*subArr); s++ { + var tenantID []string + err := dborm.DefaultDB().Table("sys_tenant"). + Where("status='1' and tenancy_type='IMSI' and ? like tenancy_key", (*subArr)[s].IMSI). + Cols("parent_id").Distinct().Find(&tenantID) + if err != nil { + logger.Errorf("Find tenant_id err => %v", err) + continue + } + if len(tenantID) > 0 { + (*subArr)[s].TenantID = tenantID[0] + } + } } diff --git a/src/modules/network_data/repository/udm_sub.impl.go b/src/modules/network_data/repository/udm_sub.impl.go deleted file mode 100644 index e953240a..00000000 --- a/src/modules/network_data/repository/udm_sub.impl.go +++ /dev/null @@ -1,268 +0,0 @@ -package repository - -import ( - "fmt" - "strings" - - dborm "be.ems/lib/core/datasource" - "be.ems/lib/log" - "be.ems/src/framework/datasource" - "be.ems/src/framework/logger" - "be.ems/src/framework/utils/parse" - "be.ems/src/framework/utils/repo" - "be.ems/src/modules/network_data/model" -) - -// 实例化数据层 UDMSubImpl 结构体 -var NewUDMSubImpl = &UDMSubImpl{ - selectSql: `select - s.id, s.msisdn, s.imsi, s.ambr, s.nssai, s.rat, s.arfb, s.sar, s.cn, s.sm_data, s.smf_sel, s.eps_dat, - s.ne_id, s.eps_flag, s.eps_odb, s.hplmn_odb, s.ard, s.epstpl, s.context_id, s.apn_context, s.static_ip, - t.tenant_id, t.tenant_name - from u_sub_user s - left join sys_tenant t on t.tenant_id = s.tenant_id`, - - resultMap: map[string]string{ - "id": "ID", - "msisdn": "Msisdn", - "imsi": "IMSI", - "ambr": "Ambr", - "nssai": "Nssai", - "rat": "Rat", - "arfb": "Arfb", - "sar": "Sar", - "cn": "Cn", - "sm_data": "SmData", - "smf_sel": "SmfSel", - "eps_dat": "EpsDat", - "ne_id": "NeId", - "eps_flag": "EpsFlag", - "eps_odb": "EpsOdb", - "hplmn_odb": "HplmnOdb", - "ard": "Ard", - "epstpl": "Epstpl", - "context_id": "ContextId", - "apn_context": "ApnContext", - "static_ip": "StaticIp", - "tenant_id": "TenantID", - "tenant_name": "TenantName", // Tenant name for multi-tenancy - }, -} - -// UDMSubImpl UDM签约信息表 数据层处理 -type UDMSubImpl struct { - // 查询视图对象SQL - selectSql string - // 结果字段与实体映射 - resultMap map[string]string -} - -// convertResultRows 将结果记录转实体结果组 -func (r *UDMSubImpl) convertResultRows(rows []map[string]any) []model.UDMSub { - arr := make([]model.UDMSub, 0) - for _, row := range rows { - item := model.UDMSub{} - for key, value := range row { - if keyMapper, ok := r.resultMap[key]; ok { - repo.SetFieldValue(&item, keyMapper, value) - } - } - arr = append(arr, item) - } - return arr -} - -// ClearAndInsert 清空ne_id后新增实体 -func (r *UDMSubImpl) ClearAndInsert(neID string, u []model.UDMSub) int64 { - // 不指定neID时,用 TRUNCATE 清空表快 - _, err := datasource.ExecDB("", "TRUNCATE TABLE u_sub_user", nil) - if err != nil { - logger.Errorf("TRUNCATE err => %v", err) - } - return r.Inserts(u) -} - -// SelectPage 根据条件分页查询字典类型 -func (r *UDMSubImpl) SelectPage(query map[string]any) map[string]any { - // 查询条件拼接 - var conditions []string - var params []any - if v, ok := query["msisdn"]; ok && v != "" { - conditions = append(conditions, "msisdn like concat(concat('%', ?), '%')") - params = append(params, strings.Trim(v.(string), " ")) - } - if v, ok := query["imsi"]; ok && v != "" { - //conditions = append(conditions, "imsi like concat(concat('%', ?), '%')") - //params = append(params, strings.Trim(v.(string), " ")) - conditions = append(conditions, "imsi like ?") - params = append(params, v) - } - if v, ok := query["neId"]; ok && v != "" { - conditions = append(conditions, "ne_id = ?") - params = append(params, v) - } - // for multi-tenancy solution - if v, ok := query["tenantName"]; ok && v != "" { - var tenantID []string - err := dborm.DefaultDB().Table("sys_tenant"). - Where("tenant_name=?", v).Cols("tenant_id").Distinct().Find(&tenantID) - if err != nil { - log.Errorf("Find tenant_id from sys_user err => %v", err) - } - log.Tracef("userName=%v, tenantID=%v", v, tenantID) - if len(tenantID) > 0 { - conditions = append(conditions, "s.tenant_id = ?") - params = append(params, tenantID[0]) - } - } else if v, ok := query["userName"]; ok && v != "" { - var tenantID string - _, err := dborm.DefaultDB().Table("sys_user"). - Where("user_name=?", v).Cols("tenant_id").Distinct().Get(&tenantID) - if err != nil { - log.Errorf("Find tenant_id from sys_user err => %v", err) - } - log.Tracef("userName=%v, tenantID=%v", v, tenantID) - if tenantID != "" { - conditions = append(conditions, "s.tenant_id = ?") - params = append(params, tenantID) - } - // if len(tenantID) > 0 { - // conditions = append(conditions, "s.tenant_id = ?") - // params = append(params, tenantID[0]) - // } - } - - // 构建查询条件语句 - whereSql := "" - if len(conditions) > 0 { - whereSql += " where " + strings.Join(conditions, " and ") - } - - result := map[string]any{ - "total": 0, - "rows": []model.UDMSub{}, - } - - // 查询数量 长度为0直接返回 - totalSql := "select count(1) as 'total' from u_sub_user s" - 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(query["pageNum"], query["pageSize"]) - pageSql := " limit ?,? " - params = append(params, pageNum*pageSize) - params = append(params, pageSize) - - // 排序 - orderSql := "" - if v, ok := query["sortField"]; ok && v != "" { - sortSql := v.(string) - if o, ok := query["sortOrder"]; ok && o != nil && v != "" { - if o == "desc" { - sortSql += " desc " - } else { - sortSql += " asc " - } - } - orderSql = fmt.Sprintf(" order by %s ", sortSql) - } - - // 查询数据 - querySql := r.selectSql + whereSql + orderSql + pageSql - results, err := datasource.RawDB("", querySql, params) - if err != nil { - logger.Errorf("query err => %v", err) - return result - } - - // 转换实体 - result["rows"] = r.convertResultRows(results) - return result -} - -// SelectList 根据实体查询 -func (r *UDMSubImpl) SelectList(u model.UDMSub) []model.UDMSub { - // 查询条件拼接 - var conditions []string - var params []any - if u.IMSI != "" { - conditions = append(conditions, "imsi = ?") - params = append(params, u.IMSI) - } - if u.NeId != "" { - conditions = append(conditions, "ne_id = ?") - params = append(params, u.NeId) - } - - // 构建查询条件语句 - whereSql := "" - if len(conditions) > 0 { - whereSql += " where " + strings.Join(conditions, " and ") - } - - // 查询数据 - querySql := r.selectSql + whereSql + " order by imsi asc " - results, err := datasource.RawDB("", querySql, params) - if err != nil { - logger.Errorf("query err => %v", err) - } - - // 转换实体 - return r.convertResultRows(results) -} - -// Insert 批量添加 -func (r *UDMSubImpl) Inserts(uArr []model.UDMSub) int64 { - // multi-tenancy - r.SetTenantID(&uArr) - - tx := datasource.DefaultDB().CreateInBatches(uArr, 2000) - if err := tx.Error; err != nil { - logger.Errorf("CreateInBatches err => %v", err) - } - return tx.RowsAffected -} - -// Delete 删除实体 -func (r *UDMSubImpl) Delete(neId, imsi string) int64 { - tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMSub{}) - if err := tx.Error; err != nil { - logger.Errorf("Delete err => %v", err) - } - return tx.RowsAffected -} - -// DeletePrefixByIMSI 删除前缀匹配的实体 -func (r *UDMSubImpl) DeletePrefixByIMSI(neId, imsi string) int64 { - tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsi, neId).Delete(&model.UDMSub{}) - if err := tx.Error; err != nil { - logger.Errorf("DeletePrefixByIMSI err => %v", err) - } - return tx.RowsAffected -} - -func (r *UDMSubImpl) SetTenantID(subArr *[]model.UDMSub) { - for s := 0; s < len(*subArr); s++ { - var tenantID []string - err := dborm.DefaultDB().Table("sys_tenant"). - Where("status='1' and tenancy_type='IMSI' and ? like tenancy_key", (*subArr)[s].IMSI). - Cols("parent_id").Distinct().Find(&tenantID) - if err != nil { - logger.Errorf("Find tenant_id err => %v", err) - continue - } - if len(tenantID) > 0 { - (*subArr)[s].TenantID = tenantID[0] - } - } -} diff --git a/src/modules/network_data/repository/udm_auth.impl.go b/src/modules/network_data/repository/udm_user_info.go similarity index 71% rename from src/modules/network_data/repository/udm_auth.impl.go rename to src/modules/network_data/repository/udm_user_info.go index 5fee2f0d..c7aead43 100644 --- a/src/modules/network_data/repository/udm_auth.impl.go +++ b/src/modules/network_data/repository/udm_user_info.go @@ -11,24 +11,21 @@ import ( "be.ems/src/modules/network_data/model" ) -// 实例化数据层 UDMAuthImpl 结构体 -var NewUDMAuthImpl = &UDMAuthImpl{ - selectSql: `select id, imsi, amf, status, ki, algo_index, opc, ne_id from u_auth_user`, +// 实例化数据层 UDMUserInfo 结构体 +var NewUDMUserInfo = &UDMUserInfo{ + selectSql: `select id, imsi, msisdn, ne_id, remark from u_user_info`, resultMap: map[string]string{ - "id": "ID", - "imsi": "IMSI", - "amf": "Amf", - "status": "Status", - "ki": "Ki", - "algo_index": "AlgoIndex", - "opc": "Opc", - "ne_id": "NeId", + "id": "ID", + "imsi": "IMSI", + "msisdn": "MSISDN", + "ne_id": "NeId", + "remark": "Remark", }, } -// UDMAuthImpl UDM鉴权信息表 数据层处理 -type UDMAuthImpl struct { +// UDMUserInfo UDM鉴权信息表 数据层处理 +type UDMUserInfo struct { // 查询视图对象SQL selectSql string // 结果字段与实体映射 @@ -36,10 +33,10 @@ type UDMAuthImpl struct { } // convertResultRows 将结果记录转实体结果组 -func (r *UDMAuthImpl) convertResultRows(rows []map[string]any) []model.UDMAuth { - arr := make([]model.UDMAuth, 0) +func (r *UDMUserInfo) convertResultRows(rows []map[string]any) []model.UDMUserInfo { + arr := make([]model.UDMUserInfo, 0) for _, row := range rows { - item := model.UDMAuth{} + item := model.UDMUserInfo{} for key, value := range row { if keyMapper, ok := r.resultMap[key]; ok { repo.SetFieldValue(&item, keyMapper, value) @@ -50,18 +47,8 @@ func (r *UDMAuthImpl) convertResultRows(rows []map[string]any) []model.UDMAuth { return arr } -// ClearAndInsert 清空ne_id后新增实体 -func (r *UDMAuthImpl) ClearAndInsert(neId string, uArr []model.UDMAuth) int64 { - // 不指定neID时,用 TRUNCATE 清空表快 - _, err := datasource.ExecDB("", "TRUNCATE TABLE u_auth_user", nil) - if err != nil { - logger.Errorf("TRUNCATE err => %v", err) - } - return r.Inserts(uArr) -} - // SelectPage 根据条件分页查询 -func (r *UDMAuthImpl) SelectPage(query map[string]any) map[string]any { +func (r *UDMUserInfo) SelectPage(query map[string]any) map[string]any { // 查询条件拼接 var conditions []string var params []any @@ -82,11 +69,11 @@ func (r *UDMAuthImpl) SelectPage(query map[string]any) map[string]any { result := map[string]any{ "total": 0, - "rows": []model.UDMAuth{}, + "rows": []model.UDMUserInfo{}, } // 查询数量 长度为0直接返回 - totalSql := "select count(1) as 'total' from u_auth_user" + totalSql := "select count(1) as 'total' from u_user_info" totalRows, err := datasource.RawDB("", totalSql+whereSql, params) if err != nil { logger.Errorf("total err => %v", err) @@ -132,7 +119,7 @@ func (r *UDMAuthImpl) SelectPage(query map[string]any) map[string]any { } // SelectList 根据实体查询 -func (r *UDMAuthImpl) SelectList(u model.UDMAuth) []model.UDMAuth { +func (r *UDMUserInfo) SelectList(u model.UDMUserInfo) []model.UDMUserInfo { // 查询条件拼接 var conditions []string var params []any @@ -162,8 +149,24 @@ func (r *UDMAuthImpl) SelectList(u model.UDMAuth) []model.UDMAuth { return r.convertResultRows(results) } +// SelectByIMSIAndNeID 通过imsi和ne_id查询 +func (r *UDMUserInfo) SelectByIMSIAndNeID(imsi, neId string) model.UDMUserInfo { + querySql := r.selectSql + " where imsi = ? and ne_id = ?" + results, err := datasource.RawDB("", querySql, []any{imsi, neId}) + if err != nil { + logger.Errorf("query err => %v", err) + return model.UDMUserInfo{} + } + // 转换实体 + rows := r.convertResultRows(results) + if len(rows) > 0 { + return rows[0] + } + return model.UDMUserInfo{} +} + // Insert 批量添加 -func (r *UDMAuthImpl) Inserts(uArr []model.UDMAuth) int64 { +func (r *UDMUserInfo) Inserts(uArr []model.UDMUserInfo) int64 { tx := datasource.DefaultDB().CreateInBatches(uArr, 3000) if err := tx.Error; err != nil { logger.Errorf("CreateInBatches err => %v", err) @@ -172,8 +175,8 @@ func (r *UDMAuthImpl) Inserts(uArr []model.UDMAuth) int64 { } // Delete 删除实体 -func (r *UDMAuthImpl) Delete(neId, imsi string) int64 { - tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMAuth{}) +func (r *UDMUserInfo) Delete(imsi, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&model.UDMUserInfo{}) if err := tx.Error; err != nil { logger.Errorf("Delete err => %v", err) } @@ -181,8 +184,8 @@ func (r *UDMAuthImpl) Delete(neId, imsi string) int64 { } // DeletePrefixByIMSI 删除前缀匹配的实体 -func (r *UDMAuthImpl) DeletePrefixByIMSI(neId, imsi string) int64 { - tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsi, neId).Delete(&model.UDMAuth{}) +func (r *UDMUserInfo) DeletePrefixByIMSI(imsiPrefix, neId string) int64 { + tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsiPrefix, neId).Delete(&model.UDMUserInfo{}) if err := tx.Error; err != nil { logger.Errorf("DeletePrefixByIMSI err => %v", err) } diff --git a/src/modules/network_data/service/udm_auth.go b/src/modules/network_data/service/udm_auth.go index 6e2b14e1..8e35bdd8 100644 --- a/src/modules/network_data/service/udm_auth.go +++ b/src/modules/network_data/service/udm_auth.go @@ -1,28 +1,172 @@ package service -import "be.ems/src/modules/network_data/model" +import ( + "fmt" + "strconv" + "strings" -// UDM鉴权信息 服务层接口 -type IUDMAuth interface { - // ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 - ResetData(neId string) int64 + "be.ems/src/framework/redis" + "be.ems/src/modules/network_data/model" + "be.ems/src/modules/network_data/repository" +) - // SelectPage 分页查询数据库 - SelectPage(query map[string]any) map[string]any - - // SelectList 查询数据库 - SelectList(u model.UDMAuth) []model.UDMAuth - - // Insert 从数据中读取后删除imsi再存入数据库 - // imsi长度15,ki长度32,opc长度0或者32 - Insert(neId string, u model.UDMAuth) int64 - - // InsertData 导入文件数据 dataType目前两种:txt/csv - InsertData(neId, dataType string, data any) int64 - - // Delete 删除单个不重新加载 - Delete(neID, imsi string) int64 - - // LoadData 删除范围后重新加载 num表示imsi后几位 - LoadData(neID, imsi, num string) int64 +// 实例化服务层 UDMAuthUser 结构体 +var NewUDMAuthUser = &UDMAuthUser{ + udmAuthRepository: repository.NewUDMAuthUser, +} + +// UDM鉴权信息 服务层处理 +type UDMAuthUser struct { + // UDM鉴权信息数据信息 + udmAuthRepository *repository.UDMAuthUser +} + +// dataByRedis UDM鉴权用户 db:0 中 ausf:* +func (r *UDMAuthUser) dataByRedis(imsi, neId string) []model.UDMAuthUser { + arr := []model.UDMAuthUser{} + key := fmt.Sprintf("ausf:%s", imsi) + ausfArr, err := redis.GetKeys("udmuser", key) + if err != nil { + return arr + } + for _, key := range ausfArr { + m, err := redis.GetHash("udmuser", key) + if err != nil { + continue + } + + // 跳过-号数据 ausf:360000100000130 + imsi := key[5:] + if strings.Contains(imsi, "-") { + continue + } + + amf := "" + if v, ok := m["amf"]; ok { + amf = strings.Replace(v, "\r\n", "", 1) + } + a := model.UDMAuthUser{ + IMSI: imsi, + Amf: amf, + Status: "1", // 默认给1 + Ki: m["ki"], + AlgoIndex: m["algo"], + Opc: m["opc"], + NeId: neId, + } + arr = append(arr, a) + } + return arr +} + +// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 +func (r *UDMAuthUser) ResetData(neId string) int64 { + authArr := r.dataByRedis("*", neId) + // 数据清空后添加 + go r.udmAuthRepository.ClearAndInsert(neId, authArr) + return int64(len(authArr)) +} + +// ParseInfo 解析单个用户imsi鉴权信息 data从命令MML得到的结果 +func (r *UDMAuthUser) ParseInfo(imsi, neId string, data map[string]string) model.UDMAuthUser { + u := model.UDMAuthUser{ + IMSI: imsi, + NeId: neId, + Amf: data["amf"], + Status: "1", + Ki: data["ki"], + AlgoIndex: data["algo"], + Opc: data["opc"], + } + + // 补充用户ID用于更新 + auth := r.udmAuthRepository.SelectByIMSIAndNeID(imsi, neId) + if auth.IMSI == imsi { + u.ID = auth.ID + } + return u +} + +// SelectPage 分页查询数据库 +func (r *UDMAuthUser) SelectPage(query map[string]any) map[string]any { + return r.udmAuthRepository.SelectPage(query) +} + +// SelectList 查询数据库 +func (r *UDMAuthUser) SelectList(u model.UDMAuthUser) []model.UDMAuthUser { + return r.udmAuthRepository.SelectList(u) +} + +// Insert 从数据中读取后删除imsi再存入数据库 +// imsi长度15,ki长度32,opc长度0或者32 +func (r *UDMAuthUser) Insert(neId string, u model.UDMAuthUser) int64 { + uArr := r.dataByRedis(u.IMSI, neId) + if len(uArr) > 0 { + r.udmAuthRepository.Delete(u.IMSI, neId) + return r.udmAuthRepository.Inserts(uArr) + } + return 0 +} + +// InsertData 导入文件数据 dataType目前两种:txt/csv +func (r *UDMAuthUser) InsertData(neId, dataType string, data any) int64 { + // imsi截取前缀,重新获取部分数据 + prefixes := make(map[string]struct{}) + + if dataType == "csv" { + for _, v := range data.([]map[string]string) { + imsi := v["imsi"] + if len(imsi) < 6 { + continue + } + prefix := imsi[:len(imsi)-4] + prefixes[prefix] = struct{}{} + } + } + if dataType == "txt" { + for _, v := range data.([][]string) { + imsi := v[0] + if len(imsi) < 6 { + continue + } + prefix := imsi[:len(imsi)-4] + prefixes[prefix] = struct{}{} + } + } + + // 根据前缀重新加载插入 + var num int64 = 0 + for prefix := range prefixes { + // 直接删除前缀的记录 + r.udmAuthRepository.DeletePrefixByIMSI(neId, prefix) + // keys ausf:4600001000004* + arr := r.dataByRedis(prefix+"*", neId) + if len(arr) > 0 { + num += r.udmAuthRepository.Inserts(arr) + } + } + return num +} + +// Delete 删除单个不重新加载 +func (r *UDMAuthUser) Delete(imsi, neId string) int64 { + return r.udmAuthRepository.Delete(imsi, neId) +} + +// LoadData 重新加载从imsi开始num的数据 +func (r *UDMAuthUser) LoadData(neId, imsi, num string) { + startIMSI, _ := strconv.ParseInt(imsi, 10, 64) + subNum, _ := strconv.ParseInt(num, 10, 64) + var i int64 + for i = 0; i < subNum; i++ { + keyIMSI := fmt.Sprintf("%015d", startIMSI+i) + // 删除原数据 + r.udmAuthRepository.Delete(keyIMSI, neId) + // 加载数据 + arr := r.dataByRedis(keyIMSI, neId) + if len(arr) < 1 { + continue + } + r.udmAuthRepository.Inserts(arr) + } } diff --git a/src/modules/network_data/service/udm_auth.impl.go b/src/modules/network_data/service/udm_auth.impl.go deleted file mode 100644 index d7998a10..00000000 --- a/src/modules/network_data/service/udm_auth.impl.go +++ /dev/null @@ -1,146 +0,0 @@ -package service - -import ( - "fmt" - "strings" - - "be.ems/src/framework/redis" - "be.ems/src/modules/network_data/model" - "be.ems/src/modules/network_data/repository" -) - -// 实例化服务层 UDMAuthImpl 结构体 -var NewUDMAuthImpl = &UDMAuthImpl{ - udmAuthRepository: repository.NewUDMAuthImpl, -} - -// UDM鉴权信息 服务层处理 -type UDMAuthImpl struct { - // UDM鉴权信息数据信息 - udmAuthRepository repository.IUDMAuth -} - -// dataByRedis UDM鉴权用户 db:0 中 ausf:* -func (r *UDMAuthImpl) dataByRedis(imsi, neId string) []model.UDMAuth { - arr := []model.UDMAuth{} - key := fmt.Sprintf("ausf:%s", imsi) - ausfArr, err := redis.GetKeys("udmuser", key) - if err != nil { - return arr - } - for _, key := range ausfArr { - m, err := redis.GetHash("udmuser", key) - if err != nil { - continue - } - - // 跳过-号数据 - imsi := key[5:] - if strings.Contains(imsi, "-") { - continue - } - - amf := "" - if v, ok := m["amf"]; ok { - amf = strings.Replace(v, "\r\n", "", 1) - } - a := model.UDMAuth{ - IMSI: imsi, - Amf: amf, - Status: "1", // 默认给1 - Ki: m["ki"], - AlgoIndex: m["algo"], - Opc: m["opc"], - NeId: neId, - } - arr = append(arr, a) - } - return arr -} - -// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 -func (r *UDMAuthImpl) ResetData(neId string) int64 { - authArr := r.dataByRedis("*", neId) - // 数据清空后添加 - go r.udmAuthRepository.ClearAndInsert(neId, authArr) - return int64(len(authArr)) -} - -// SelectPage 分页查询数据库 -func (r *UDMAuthImpl) SelectPage(query map[string]any) map[string]any { - return r.udmAuthRepository.SelectPage(query) -} - -// SelectList 查询数据库 -func (r *UDMAuthImpl) SelectList(u model.UDMAuth) []model.UDMAuth { - return r.udmAuthRepository.SelectList(u) -} - -// Insert 从数据中读取后删除imsi再存入数据库 -// imsi长度15,ki长度32,opc长度0或者32 -func (r *UDMAuthImpl) Insert(neId string, u model.UDMAuth) int64 { - uArr := r.dataByRedis(u.IMSI, neId) - if len(uArr) > 0 { - r.udmAuthRepository.Delete(neId, u.IMSI) - return r.udmAuthRepository.Inserts(uArr) - } - return 0 -} - -// InsertData 导入文件数据 dataType目前两种:txt/csv -func (r *UDMAuthImpl) InsertData(neId, dataType string, data any) int64 { - // imsi截取前缀,重新获取部分数据 - prefixes := make(map[string]struct{}) - - if dataType == "csv" { - for _, v := range data.([]map[string]string) { - imsi := v["imsi"] - if len(imsi) < 6 { - continue - } - prefix := imsi[:len(imsi)-4] - prefixes[prefix] = struct{}{} - } - } - if dataType == "txt" { - for _, v := range data.([][]string) { - imsi := v[0] - if len(imsi) < 6 { - continue - } - prefix := imsi[:len(imsi)-4] - prefixes[prefix] = struct{}{} - } - } - - // 根据前缀重新加载插入 - var num int64 = 0 - for prefix := range prefixes { - // 直接删除前缀的记录 - r.udmAuthRepository.DeletePrefixByIMSI(neId, prefix) - // keys ausf:4600001000004* - authArr := r.dataByRedis(prefix+"*", neId) - if len(authArr) > 0 { - num += r.udmAuthRepository.Inserts(authArr) - } - } - return num -} - -// Delete 删除单个不重新加载 -func (r *UDMAuthImpl) Delete(neId, imsi string) int64 { - return r.udmAuthRepository.Delete(neId, imsi) -} - -// LoadData 删除范围后重新加载 num表示imsi后几位 -func (r *UDMAuthImpl) LoadData(neId, imsi, num string) int64 { - prefix := imsi[:len(imsi)-len(num)-1] - // 直接删除前缀的记录 - delNum := r.udmAuthRepository.DeletePrefixByIMSI(neId, prefix) - // keys ausf:4600001000004* - authArr := r.dataByRedis(prefix+"*", neId) - if len(authArr) > 0 { - return r.udmAuthRepository.Inserts(authArr) - } - return delNum -} diff --git a/src/modules/network_data/service/udm_sub.go b/src/modules/network_data/service/udm_sub.go index cb03afe7..8aebea35 100644 --- a/src/modules/network_data/service/udm_sub.go +++ b/src/modules/network_data/service/udm_sub.go @@ -1,28 +1,254 @@ package service -import "be.ems/src/modules/network_data/model" +import ( + "fmt" + "strconv" + "strings" -// UDM签约用户信息 服务层接口 -type IUDMSub interface { - // ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 - ResetData(neId string) int64 + "be.ems/src/framework/redis" + "be.ems/src/modules/network_data/model" + "be.ems/src/modules/network_data/repository" +) - // SelectPage 分页查询数据库 - SelectPage(query map[string]any) map[string]any - - // SelectList 查询数据库 - SelectList(u model.UDMSub) []model.UDMSub - - // Insert 从数据中读取后删除imsi再存入数据库 - // imsi长度15,ki长度32,opc长度0或者32 - Insert(neId string, u model.UDMSub) int64 - - // InsertData 导入文件数据 dataType目前两种:txt/csv - InsertData(neId, dataType string, data any) int64 - - // Delete 删除单个不重新加载 - Delete(neId, imsi string) int64 - - // LoadData 删除范围后重新加载 num表示imsi后几位 - LoadData(neId, imsi, num string) int64 +// 实例化服务层 UDMSubUser 结构体 +var NewUDMSub = &UDMSubUser{ + udmSubRepository: repository.NewUDMSub, + udmUserInfoRepository: repository.NewUDMUserInfo, +} + +// UDM签约信息 服务层处理 +type UDMSubUser struct { + // UDM签约信息数据信息 + udmSubRepository *repository.UDMSubUser + // UDM用户IMSI信息数据信息 + udmUserInfoRepository *repository.UDMUserInfo +} + +// dataByRedis UDM签约用户 db:0 中 udm-sd:* +func (r *UDMSubUser) dataByRedis(imsi, neId string) []model.UDMSubUser { + arr := []model.UDMSubUser{} + key := fmt.Sprintf("udm-sd:%s", imsi) + udmsdArr, err := redis.GetKeys("udmuser", key) + if err != nil { + return arr + } + for _, key := range udmsdArr { + m, err := redis.GetHash("udmuser", key) + if err != nil { + continue + } + + a := model.UDMSubUser{ + IMSI: key[7:], // udm-sd:360000100000130 + MSISDN: m["gpsi"], // 8612300000130 + NeId: neId, + SmfSel: m["smf-sel"], // def_snssai + SmData: m["sm-dat"], // 1-000001&cmnet&ims&3gnet + Cag: m["cag"], // def_cag + } + + // def_ambr,def_nssai,0,def_arfb,def_sar,3,1,12000,1,1000,0,1,- + if v, ok := m["am-dat"]; ok { + arr := strings.Split(v, ",") + a.Ambr = arr[0] + a.Nssai = arr[1] + a.Rat = arr[2] + a.Arfb = arr[3] + a.Sar = arr[4] + a.Cn = arr[5] + } + // 1,64,24,65,def_eps,1,2,010200000000,- + if v, ok := m["eps-dat"]; ok { + arr := strings.Split(v, ",") + // 跳过非常规数据 + if len(arr) > 9 { + continue + } + a.EpsDat = v + a.EpsFlag = arr[0] + a.EpsOdb = arr[1] + a.HplmnOdb = arr[2] + a.Ard = arr[3] + a.Epstpl = arr[4] + a.ContextId = arr[5] + a.ApnContext = arr[7] + // [6] 是不要的,导入和导出不用 + a.StaticIp = arr[8] + } + + arr = append(arr, a) + } + return arr +} + +// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 +func (r *UDMSubUser) ResetData(neId string) int64 { + subArr := r.dataByRedis("*", neId) + // 数据清空后添加 + go r.udmSubRepository.ClearAndInsert(neId, subArr) + return int64(len(subArr)) +} + +// ParseInfo 解析单个用户imsi签约信息 data从命令MML得到的结果 +func (r *UDMSubUser) ParseInfo(imsi, neId string, data map[string]string) model.UDMSubUser { + cnType, _ := strconv.ParseInt(data["CNType"][:4], 0, 64) + rat, _ := strconv.ParseInt(data["RAT"][:4], 0, 64) + msisdn := data["MSISDN"] + if imsMsisdnLen := strings.Index(msisdn, ","); imsMsisdnLen != -1 { + msisdn = msisdn[:imsMsisdnLen] + } + + u := model.UDMSubUser{ + IMSI: imsi, + MSISDN: msisdn, + NeId: neId, + Ambr: data["AMBR"], + Arfb: data["AreaForbidden"], + Cn: fmt.Sprint(cnType), + SmData: data["SM-Data(snssai+dnn[1..n])"], + Sar: data["ServiceAreaRestriction"], + Nssai: data["NSSAI"], + SmfSel: data["Smf-Selection"], + Cag: data["cag"], + Rat: fmt.Sprint(rat), + } + // 1,64,24,65,def_eps,1,2,010200000000,- + if v, ok := data["EPS-Data"]; ok { + u.EpsDat = v + arr := strings.Split(v, ",") + u.EpsFlag = arr[0] + u.EpsOdb = arr[1] + u.HplmnOdb = arr[2] + u.Ard = arr[3] + u.Epstpl = arr[4] + u.ContextId = arr[5] + u.ApnContext = arr[7] + // [6] 是不要的,导入和导出不用 + u.StaticIp = arr[8] + } + + // 补充用户ID用于更新 + sub := r.udmSubRepository.SelectByIMSIAndNeID(imsi, neId) + if sub.IMSI == imsi { + u.ID = sub.ID + } + // 补充用户拓展信息 + info := r.udmUserInfoRepository.SelectByIMSIAndNeID(imsi, neId) + if info.IMSI == imsi { + u.Remark = info.Remark + } + return u +} + +// SelectPage 分页查询数据库 +func (r *UDMSubUser) SelectPage(query map[string]any) map[string]any { + return r.udmSubRepository.SelectPage(query) +} + +// SelectList 查询数据库 +func (r *UDMSubUser) SelectList(u model.UDMSubUser) []model.UDMSubUser { + return r.udmSubRepository.SelectList(u) +} + +// Insert 从数据中读取后删除imsi再存入数据库 +// imsi长度15,ki长度32,opc长度0或者32 +func (r *UDMSubUser) Insert(neId string, u model.UDMSubUser) int64 { + uArr := r.dataByRedis(u.IMSI, neId) + if len(uArr) > 0 { + r.udmSubRepository.Delete(u.IMSI, neId) + // 新增到拓展信息 + if u.Remark != "" { + r.udmUserInfoRepository.Delete(u.IMSI, neId) + r.udmUserInfoRepository.Inserts([]model.UDMUserInfo{{ + IMSI: u.IMSI, + MSISDN: u.MSISDN, + NeId: u.NeId, + Remark: u.Remark, + }}) + } + return r.udmSubRepository.Inserts(uArr) + } + return 0 +} + +// InsertData 导入文件数据 dataType目前两种:txt/csv +func (r *UDMSubUser) InsertData(neId, dataType string, data any) int64 { + // imsi截取前缀,重新获取部分数据 + prefixes := make(map[string]struct{}) + + if dataType == "csv" { + for _, v := range data.([]map[string]string) { + imsi := v["imsi"] + if len(imsi) < 6 { + continue + } + prefix := imsi[:len(imsi)-4] + prefixes[prefix] = struct{}{} + } + } + if dataType == "txt" { + for _, v := range data.([][]string) { + imsi := v[0] + if len(imsi) < 6 { + continue + } + prefix := imsi[:len(imsi)-4] + prefixes[prefix] = struct{}{} + } + } + + // 根据前缀重新加载插入 + var num int64 = 0 + for prefix := range prefixes { + // keys udm-sd:4600001000004* + arr := r.dataByRedis(prefix+"*", neId) + if len(arr) > 0 { + r.udmSubRepository.DeletePrefixByIMSI(prefix, neId) + num += r.udmSubRepository.Inserts(arr) + } + } + return num +} + +// Delete 删除单个不重新加载 +func (r *UDMSubUser) Delete(neId, imsi string) int64 { + // 删除拓展信息 + r.udmUserInfoRepository.Delete(imsi, neId) + return r.udmSubRepository.Delete(imsi, neId) +} + +// LoadData 重新加载从imsi开始num的数据 +// remark不为空,则新增到拓展信息,删除标记为-(Deleted)- +func (r *UDMSubUser) LoadData(neId, imsi, num, remark string) { + startIMSI, _ := strconv.ParseInt(imsi, 10, 64) + subNum, _ := strconv.ParseInt(num, 10, 64) + var i int64 + for i = 0; i < subNum; i++ { + keyIMSI := fmt.Sprintf("%015d", startIMSI+i) + // 删除原数据 + r.udmSubRepository.Delete(keyIMSI, neId) + if remark == "-(Deleted)-" { + r.udmUserInfoRepository.Delete(keyIMSI, neId) + } + // 加载数据 + arr := r.dataByRedis(keyIMSI, neId) + if len(arr) < 1 { + continue + } + r.udmSubRepository.Inserts(arr) + // 拓展信息 + if remark != "" { + uarr := make([]model.UDMUserInfo, 0, len(arr)) + for _, v := range arr { + uarr = append(uarr, model.UDMUserInfo{ + IMSI: v.IMSI, + MSISDN: v.MSISDN, + NeId: v.NeId, + Remark: remark, + }) + } + r.udmUserInfoRepository.Delete(keyIMSI, neId) + r.udmUserInfoRepository.Inserts(uarr) + } + } } diff --git a/src/modules/network_data/service/udm_sub.impl.go b/src/modules/network_data/service/udm_sub.impl.go deleted file mode 100644 index 768e48a8..00000000 --- a/src/modules/network_data/service/udm_sub.impl.go +++ /dev/null @@ -1,164 +0,0 @@ -package service - -import ( - "fmt" - "strings" - - "be.ems/src/framework/redis" - "be.ems/src/modules/network_data/model" - "be.ems/src/modules/network_data/repository" -) - -// 实例化服务层 UDMSubImpl 结构体 -var NewUDMSubImpl = &UDMSubImpl{ - udmSubRepository: repository.NewUDMSubImpl, -} - -// UDM签约信息 服务层处理 -type UDMSubImpl struct { - // UDM签约信息数据信息 - udmSubRepository repository.IUDMSub -} - -// dataByRedis UDM签约用户 db:0 中 udm-sd:* -func (r *UDMSubImpl) dataByRedis(imsi, neId string) []model.UDMSub { - arr := []model.UDMSub{} - key := fmt.Sprintf("udm-sd:%s", imsi) - udmsdArr, err := redis.GetKeys("udmuser", key) - if err != nil { - return arr - } - for _, key := range udmsdArr { - m, err := redis.GetHash("udmuser", key) - if err != nil { - continue - } - - a := model.UDMSub{ - IMSI: key[7:], - Msisdn: m["gpsi"], // 46003550072 - SmfSel: m["smf-sel"], - SmData: m["sm-dat"], // 1-000001&cmnet&ims&3gnet - NeId: neId, - } - - // def_ambr,def_nssai,0,def_arfb,def_sar,3,1,12000,1,1000,0,1,- - if v, ok := m["am-dat"]; ok { - arr := strings.Split(v, ",") - a.Ambr = arr[0] - a.Nssai = arr[1] - a.Rat = arr[2] - a.Arfb = arr[3] - a.Sar = arr[4] - a.Cn = arr[5] - } - // 1,64,24,65,def_eps,1,2,010200000000,- - if v, ok := m["eps-dat"]; ok { - arr := strings.Split(v, ",") - // 跳过非常规数据 - if len(arr) > 9 { - continue - } - a.EpsDat = v - a.EpsFlag = arr[0] - a.EpsOdb = arr[1] - a.HplmnOdb = arr[2] - a.Ard = arr[3] - a.Epstpl = arr[4] - a.ContextId = arr[5] - a.ApnContext = arr[7] - // [6] 是不要的,导入和导出不用 - a.StaticIp = arr[8] - } - - arr = append(arr, a) - } - return arr -} - -// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据 -func (r *UDMSubImpl) ResetData(neId string) int64 { - subArr := r.dataByRedis("*", neId) - // 数据清空后添加 - go r.udmSubRepository.ClearAndInsert(neId, subArr) - return int64(len(subArr)) -} - -// SelectPage 分页查询数据库 -func (r *UDMSubImpl) SelectPage(query map[string]any) map[string]any { - return r.udmSubRepository.SelectPage(query) -} - -// SelectList 查询数据库 -func (r *UDMSubImpl) SelectList(u model.UDMSub) []model.UDMSub { - return r.udmSubRepository.SelectList(u) -} - -// Insert 从数据中读取后删除imsi再存入数据库 -// imsi长度15,ki长度32,opc长度0或者32 -func (r *UDMSubImpl) Insert(neId string, u model.UDMSub) int64 { - uArr := r.dataByRedis(u.IMSI, neId) - if len(uArr) > 0 { - r.udmSubRepository.Delete(neId, u.IMSI) - return r.udmSubRepository.Inserts(uArr) - } - return 0 -} - -// InsertData 导入文件数据 dataType目前两种:txt/csv -func (r *UDMSubImpl) InsertData(neId, dataType string, data any) int64 { - // imsi截取前缀,重新获取部分数据 - prefixes := make(map[string]struct{}) - - if dataType == "csv" { - for _, v := range data.([]map[string]string) { - imsi := v["imsi"] - if len(imsi) < 6 { - continue - } - prefix := imsi[:len(imsi)-4] - prefixes[prefix] = struct{}{} - } - } - if dataType == "txt" { - for _, v := range data.([][]string) { - imsi := v[0] - if len(imsi) < 6 { - continue - } - prefix := imsi[:len(imsi)-4] - prefixes[prefix] = struct{}{} - } - } - - // 根据前缀重新加载插入 - var num int64 = 0 - for prefix := range prefixes { - // 直接删除前缀的记录 - r.udmSubRepository.DeletePrefixByIMSI(neId, prefix) - // keys udm-sd:4600001000004* - subArr := r.dataByRedis(prefix+"*", neId) - if len(subArr) > 0 { - num += r.udmSubRepository.Inserts(subArr) - } - } - return num -} - -// Delete 删除单个不重新加载 -func (r *UDMSubImpl) Delete(neId, imsi string) int64 { - return r.udmSubRepository.Delete(neId, imsi) -} - -// LoadData 删除范围后重新加载 num表示imsi后几位 -func (r *UDMSubImpl) LoadData(neId, imsi, num string) int64 { - prefix := imsi[:len(imsi)-len(num)-1] - // 直接删除前缀的记录 - delNum := r.udmSubRepository.DeletePrefixByIMSI(neId, prefix) - // keys udm-sd:4600001000004* - authArr := r.dataByRedis(prefix+"*", neId) - if len(authArr) > 0 { - return r.udmSubRepository.Inserts(authArr) - } - return delNum -} diff --git a/src/modules/network_data/service/udm_user_info.go b/src/modules/network_data/service/udm_user_info.go new file mode 100644 index 00000000..da610724 --- /dev/null +++ b/src/modules/network_data/service/udm_user_info.go @@ -0,0 +1,33 @@ +package service + +import ( + "be.ems/src/modules/network_data/model" + "be.ems/src/modules/network_data/repository" +) + +// 实例化服务层 UDMUserInfo 结构体 +var NewUDMUserInfo = &UDMUserInfo{ + udmUserInfoRepository: repository.NewUDMUserInfo, +} + +// UDM用户IMSI拓展信息 服务层处理 +type UDMUserInfo struct { + // UDM用户IMSI信息数据信息 + udmUserInfoRepository *repository.UDMUserInfo +} + +// SelectByIMSIAndNeID 通过IMSI和网元标识查询信息 +func (r *UDMUserInfo) SelectByIMSIAndNeID(imsi, neId string) model.UDMUserInfo { + return r.udmUserInfoRepository.SelectByIMSIAndNeID(imsi, neId) +} + +// Save 新增或修改信息 +func (r *UDMUserInfo) Save(u model.UDMUserInfo) bool { + r.udmUserInfoRepository.Delete(u.IMSI, u.NeId) + return r.udmUserInfoRepository.Inserts([]model.UDMUserInfo{u}) > 0 +} + +// Delete 删除信息 +func (r *UDMUserInfo) Delete(imsi, neId string) int64 { + return r.udmUserInfoRepository.Delete(imsi, neId) +} diff --git a/src/modules/network_element/controller/ne_config.go b/src/modules/network_element/controller/ne_config.go index 0c74b33c..e1d737bb 100644 --- a/src/modules/network_element/controller/ne_config.go +++ b/src/modules/network_element/controller/ne_config.go @@ -4,6 +4,7 @@ import ( "encoding/json" "strings" + cm_omc "be.ems/features/cm/omc" "be.ems/src/framework/i18n" "be.ems/src/framework/utils/ctx" "be.ems/src/framework/utils/parse" @@ -191,14 +192,25 @@ func (s *NeConfigController) DataInfo(c *gin.Context) { return } - // 网元直连 - resData, err := neFetchlink.NeConfigInfo(neInfo, query.ParamName) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + if query.NeType == "OMC" { + var o *cm_omc.ConfigOMC + resData, err := o.Query(query.ParamName) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.OkData(resData)) return - } + } else { + // 网元直连 + resData, err := neFetchlink.NeConfigInfo(neInfo, query.ParamName) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } - c.JSON(200, result.Ok(resData)) + c.JSON(200, result.Ok(resData)) + } } // 网元参数配置数据修改 @@ -223,14 +235,24 @@ func (s *NeConfigController) DataEdit(c *gin.Context) { c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } - - // 网元直连 - resData, err := neFetchlink.NeConfigUpdate(neInfo, body.ParamName, body.Loc, body.ParamData) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + if body.NeType == "OMC" { + var o *cm_omc.ConfigOMC + resData, err := o.Modify(body.ParamName, body.ParamData) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.OkData(resData)) return + } else { + // 网元直连 + resData, err := neFetchlink.NeConfigUpdate(neInfo, body.ParamName, body.Loc, body.ParamData) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.OkData(resData)) } - c.JSON(200, result.OkData(resData)) } // 网元参数配置数据新增(array) diff --git a/src/modules/network_element/controller/ne_host.go b/src/modules/network_element/controller/ne_host.go index 57685740..7f8b9cdc 100644 --- a/src/modules/network_element/controller/ne_host.go +++ b/src/modules/network_element/controller/ne_host.go @@ -4,10 +4,10 @@ import ( "strings" "be.ems/src/framework/i18n" + "be.ems/src/framework/telnet" "be.ems/src/framework/utils/ctx" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/ssh" - "be.ems/src/framework/utils/telnet" "be.ems/src/framework/vo/result" "be.ems/src/modules/network_element/model" neService "be.ems/src/modules/network_element/service" diff --git a/src/modules/network_element/controller/ne_info.go b/src/modules/network_element/controller/ne_info.go index ea0ded6e..45e0c4ed 100644 --- a/src/modules/network_element/controller/ne_info.go +++ b/src/modules/network_element/controller/ne_info.go @@ -193,7 +193,7 @@ func (s *NeInfoController) OAMFileRead(c *gin.Context) { return } - data, err := s.neInfoService.NeConfOAMRead(querys.NeType, querys.NeID) + data, err := s.neInfoService.NeConfOAMReadSync(querys.NeType, querys.NeID) if err != nil { c.JSON(200, result.ErrMsg(err.Error())) return @@ -224,7 +224,7 @@ func (s *NeInfoController) OAMFileWrite(c *gin.Context) { return } - err := s.neInfoService.NeConfOAMSync(neInfo, body.Content, body.Sync) + err := s.neInfoService.NeConfOAMWirteSync(neInfo, body.Content, body.Sync) if err != nil { c.JSON(200, result.ErrMsg(err.Error())) return diff --git a/src/modules/network_element/fetch_link/hlr.go b/src/modules/network_element/fetch_link/hlr.go new file mode 100644 index 00000000..8a4c1198 --- /dev/null +++ b/src/modules/network_element/fetch_link/hlr.go @@ -0,0 +1,68 @@ +// 网元HLR服务8080端口。 +// 融合到UDM网元,也许是UDM的HLR服务。 + +package fetchlink + +import ( + "encoding/json" + "fmt" + "strings" + + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/fetch" + "be.ems/src/modules/network_element/model" +) + +// HLRTraceStart HLR跟踪任务开始 +// +// data参数 {traceID:"跟踪任务ID", imsi:"IMSI和MSISDN必填一个,都带的话以IMSI为准", msisdn:""} +func HLRTraceStart(neInfo model.NeInfo, data map[string]any) (string, error) { + // 网元参数配置新增(array) + neUrl := fmt.Sprintf("http://%s:%d/trace-manage/v1/add-task", neInfo.IP, neInfo.Port) + resBytes, err := fetch.PostJSON(neUrl, data, nil) + var resData map[string]string + if err != nil { + errStr := err.Error() + logger.Warnf("HLRTraceStart Post \"%s\"", neUrl) + logger.Errorf("HLRTraceStart %s", errStr) + return "", fmt.Errorf("NeService HLR API Error") + } + + // 序列化结果 + err = json.Unmarshal(resBytes, &resData) + if err != nil { + logger.Errorf("HLRTraceStart Unmarshal %s", err.Error()) + return "", err + } + if v, ok := resData["code"]; ok && v == "0" { + return strings.TrimSpace(strings.ToLower(resData["message"])), nil + } + return "", fmt.Errorf(resData["message"]) +} + +// HLRTraceStop HLR跟踪任务停止 +// +// data参数 {traceIDArray: ["跟踪任务ID数组"]} +func HLRTraceStop(neInfo model.NeInfo, data map[string]any) (string, error) { + // 网元参数配置新增(array) + neUrl := fmt.Sprintf("http://%s:%d/trace-manage/v1/delete-task", neInfo.IP, neInfo.Port) + resBytes, err := fetch.PostJSON(neUrl, data, nil) + var resData map[string]string + if err != nil { + errStr := err.Error() + logger.Warnf("HLRTraceStop Post \"%s\"", neUrl) + logger.Errorf("HLRTraceStop %s", errStr) + return "", fmt.Errorf("NeService HLR API Error") + } + + // 序列化结果 + err = json.Unmarshal(resBytes, &resData) + if err != nil { + logger.Errorf("HLRTraceStop Unmarshal %s", err.Error()) + return "", err + } + if v, ok := resData["code"]; ok && v == "0" { + return strings.TrimSpace(strings.ToLower(resData["message"])), nil + } + return "", fmt.Errorf(resData["message"]) +} diff --git a/src/modules/network_element/fetch_link/ne_config.go b/src/modules/network_element/fetch_link/ne_config.go index 5596ed6e..4695351a 100644 --- a/src/modules/network_element/fetch_link/ne_config.go +++ b/src/modules/network_element/fetch_link/ne_config.go @@ -52,9 +52,9 @@ func NeConfigOMC(neInfo model.NeInfo) (map[string]any, error) { // NeConfigInfo 网元配置信息 func NeConfigInfo(neInfo model.NeInfo, paramName string) (map[string]any, error) { - // 网元配置对端网管信息 + // 网元参数配置信息 neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/%s", neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType), paramName) - resBytes, err := fetch.Get(neUrl, nil, 60_000) + resBytes, err := fetch.Get(neUrl, nil, 30_000) if err != nil { logger.Warnf("NeConfigInfo Get \"%s\"", neUrl) logger.Errorf("NeConfigInfo %s", err.Error()) diff --git a/src/modules/network_element/fetch_link/ne_trace.go b/src/modules/network_element/fetch_link/ne_trace.go new file mode 100644 index 00000000..387633fa --- /dev/null +++ b/src/modules/network_element/fetch_link/ne_trace.go @@ -0,0 +1,121 @@ +package fetchlink + +import ( + "encoding/json" + "fmt" + "strings" + + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/fetch" + "be.ems/src/modules/network_element/model" +) + +// NeTraceInfo 网元跟踪任务信息 +func NeTraceInfo(neInfo model.NeInfo, traceId string) (map[string]any, error) { + // 跟踪任务信息 + neUrl := fmt.Sprintf("http://%s:%d/api/rest/traceManagement/v1/subscriptions?id=%s", neInfo.IP, neInfo.Port, traceId) + resBytes, err := fetch.Get(neUrl, nil, 30_000) + if err != nil { + logger.Warnf("NeTraceInfo Get \"%s\"", neUrl) + logger.Errorf("NeTraceInfo %s", err.Error()) + return nil, fmt.Errorf("NeService Trace Info API Error") + } + + // 序列化结果 + var resData map[string]any + err = json.Unmarshal(resBytes, &resData) + if err != nil { + logger.Errorf("NeTraceInfo Unmarshal %s", err.Error()) + return nil, err + } + return resData, nil +} + +// NeTraceAdd 网元跟踪任务新增 +func NeTraceAdd(neInfo model.NeInfo, data map[string]any) (map[string]any, error) { + // 跟踪任务创建 + neUrl := fmt.Sprintf("http://%s:%d/api/rest/traceManagement/v1/subscriptions", neInfo.IP, neInfo.Port) + resBytes, err := fetch.PostJSON(neUrl, data, nil) + var resData map[string]any + if err != nil { + errStr := err.Error() + logger.Warnf("NeTraceAdd POST \"%s\"", neUrl) + if !(strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "400")) { + logger.Errorf("NeTraceAdd %s", errStr) + return nil, fmt.Errorf("NeService Trace Add API Error") + } + } + + // 200 成功无数据时 + if len(resBytes) == 0 { + return resData, nil + } + + // 序列化结果 + err = json.Unmarshal(resBytes, &resData) + if err != nil { + logger.Errorf("NeTraceAdd Unmarshal %s", err.Error()) + return nil, err + } + return resData, nil +} + +// NeTraceEdit 网元跟踪任务编辑 +func NeTraceEdit(neInfo model.NeInfo, data map[string]any) (map[string]any, error) { + // 网元参数配置新增(array) + neUrl := fmt.Sprintf("http://%s:%d/api/rest/traceManagement/v1/subscriptions", neInfo.IP, neInfo.Port) + resBytes, err := fetch.PutJSON(neUrl, data, nil) + var resData map[string]any + if err != nil { + errStr := err.Error() + logger.Warnf("NeTraceEdit PUT \"%s\"", neUrl) + if strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "204") { + return resData, nil + } + logger.Errorf("NeTraceEdit %s", errStr) + return nil, fmt.Errorf("NeService Trace Edit API Error") + } + + // 200 成功无数据时 + if len(resBytes) == 0 { + return resData, nil + } + + // 序列化结果 + err = json.Unmarshal(resBytes, &resData) + if err != nil { + logger.Errorf("NeTraceEdit Unmarshal %s", err.Error()) + return nil, err + } + return resData, nil +} + +// NeTraceDelete 网元跟踪任务删除 +func NeTraceDelete(neInfo model.NeInfo, traceId string) (map[string]any, error) { + // 网元参数配置删除(array) + neUrl := fmt.Sprintf("http://%s:%d/api/rest/traceManagement/v1/subscriptions?id=%s", neInfo.IP, neInfo.Port, traceId) + resBytes, err := fetch.Delete(neUrl, nil) + var resData map[string]any + if err != nil { + errStr := err.Error() + logger.Warnf("NeTraceDelete Delete \"%s\"", neUrl) + if strings.HasPrefix(errStr, "201") || strings.HasPrefix(errStr, "204") { + return resData, nil + } + logger.Errorf("NeTraceDelete %s", errStr) + return nil, fmt.Errorf("NeService Trace Delete API Error") + } + + // 200 成功无数据时 + if len(resBytes) == 0 { + return resData, nil + } + + // 序列化结果 + err = json.Unmarshal(resBytes, &resData) + if err != nil { + logger.Errorf("NeTraceDelete Unmarshal %s", err.Error()) + return nil, err + } + return resData, nil +} diff --git a/src/modules/network_element/fetch_link/smf.go b/src/modules/network_element/fetch_link/smf.go new file mode 100644 index 00000000..09954625 --- /dev/null +++ b/src/modules/network_element/fetch_link/smf.go @@ -0,0 +1,68 @@ +package fetchlink + +import ( + "encoding/json" + "fmt" + "strings" + + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/fetch" + "be.ems/src/modules/network_element/model" +) + +// SMFSubInfo SMF在线订阅用户列表信息 +// +// 查询参数 {"imsi":"360000100000130","msisdn":"8612300000130","upstate":"Inactive","pageNum":"1"} +// +// 返回结果 {"rows":[],"total":0} +func SMFSubInfo(neInfo model.NeInfo, data map[string]string) (map[string]any, error) { + // neUrl := "http://127.0.0.1:4523/m1/3157310-1528434-82b449ee/api/rest/ueManagement/v1/elementType/smf/objectType/ueInfo?apifoxApiId=150640017" + neUrl := fmt.Sprintf("http://%s:%s/api/rest/ueManagement/v1/elementType/smf/objectType/ueInfo", "172.16.20.150", "33030") + // neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/smf/objectType/ueInfo", neInfo.IP, neInfo.Port) + // 查询参数拼接 + query := []string{} + if v, ok := data["imsi"]; ok && v != "" { + query = append(query, fmt.Sprintf("imsi=%s", v)) + } + if v, ok := data["msisdn"]; ok && v != "" { + query = append(query, fmt.Sprintf("msisdn=%s", v)) + } + if v, ok := data["upstate"]; ok && v != "" { + query = append(query, fmt.Sprintf("upstate=%s", v)) + } + // 固定页数量50条 + if v, ok := data["pageNum"]; ok && v != "" { + query = append(query, fmt.Sprintf("pageNum=%s", v)) + } + + if len(query) > 0 { + neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&")) + } + + resBytes, err := fetch.Get(neUrl, nil, 60_000) + if err != nil { + logger.Warnf("SMFSubInfo Get \"%s\"", neUrl) + logger.Errorf("SMFSubInfo %s", err.Error()) + return nil, fmt.Errorf("NeService SMF API Error") + } + + // 序列化结果 {"data":[],"total":0} + var resData map[string]any + err = json.Unmarshal(resBytes, &resData) + if err != nil { + logger.Errorf("SMFSubInfo Unmarshal %s", err.Error()) + return nil, err + } + + // 固定返回字段,方便前端解析 + if v, ok := resData["data"]; ok && v != nil { + resData["rows"] = v.([]any) + delete(resData, "data") + } else { + resData["rows"] = []any{} + } + if v, ok := resData["total"]; !ok || v == nil { + resData["total"] = 0 + } + return resData, nil +} diff --git a/src/modules/network_element/fetch_link/udm.go b/src/modules/network_element/fetch_link/udm.go index 2f1119c3..d027f9f0 100644 --- a/src/modules/network_element/fetch_link/udm.go +++ b/src/modules/network_element/fetch_link/udm.go @@ -1,3 +1,6 @@ +// 网元UDM服务,可能是8080、33030端口服务 +// 融合的UDM网元视情况调整。 + package fetchlink import ( @@ -25,8 +28,7 @@ func UDMImportAuth(udmIP string, data map[string]any) (string, error) { } // 序列化结果 - err = json.Unmarshal(resBytes, &resData) - if err != nil { + if err = json.Unmarshal(resBytes, &resData); err != nil { logger.Errorf("UDMImportAuth Unmarshal %s", err.Error()) return "", err } diff --git a/src/modules/network_element/ne_config_test.go b/src/modules/network_element/ne_config_test.go index 5d693c3c..92636a6c 100644 --- a/src/modules/network_element/ne_config_test.go +++ b/src/modules/network_element/ne_config_test.go @@ -21,7 +21,7 @@ import ( const ( // 数据库 - DbHost = "192.168.8.58" + DbHost = "127.0.0.1" DbPort = 33066 DbUser = "root" DbPassswd = "1000omc@kp!" @@ -29,10 +29,10 @@ const ( // 配置文件路径 configParamDir = "../../../config/param" // configParamFile = "*" // 目录下全部更新 - configParamFile = "cbc_param_config.yaml" // 单文件更新 + configParamFile = "omc_param_config.yaml" // 单文件更新 ) -func TestEncrypt(t *testing.T) { +func TestConfig(t *testing.T) { fileNameList, err := getDirFileNameList(configParamDir) if err != nil { log.Fatal(err) diff --git a/src/modules/network_element/repository/ne_info.impl.go b/src/modules/network_element/repository/ne_info.impl.go index b50a39c5..f6dfc19a 100644 --- a/src/modules/network_element/repository/ne_info.impl.go +++ b/src/modules/network_element/repository/ne_info.impl.go @@ -2,7 +2,6 @@ package repository import ( "fmt" - "sort" "strings" "time" @@ -82,29 +81,21 @@ func (r *NeInfoImpl) convertResultRows(rows []map[string]any) []model.NeInfo { arr = append(arr, item) } - // 排序 - sort.Slice(arr, func(i, j int) bool { - // 前一个 - after := arr[i] - afterIndex := 0 - for i, v := range neListSort { - if after.NeType == v { - afterIndex = i - break + // 创建优先级映射 + priority := make(map[string]int) + for i, v := range neListSort { + priority[v] = i + } + // 冒泡排序 + n := len(arr) + for i := 0; i < n-1; i++ { + for j := 0; j < n-i-1; j++ { + if priority[arr[j].NeType] > priority[arr[j+1].NeType] { + // 交换元素 + arr[j], arr[j+1] = arr[j+1], arr[j] } } - // 后一个 - befter := arr[j] - befterIndex := 0 - for i, v := range neListSort { - if befter.NeType == v { - befterIndex = i - break - } - } - // 升序 - return afterIndex < befterIndex - }) + } return arr } @@ -188,7 +179,7 @@ func (r *NeInfoImpl) SelectPage(query map[string]any) map[string]any { params = append(params, pageSize) // 查询数据 - querySql := r.selectSql + whereSql + " order by ne_type asc, ne_id desc " + pageSql + querySql := r.selectSql + whereSql + " order by ne_type asc, ne_id asc " + pageSql results, err := datasource.RawDB("", querySql, params) if err != nil { logger.Errorf("query err => %v", err) @@ -221,7 +212,7 @@ func (r *NeInfoImpl) SelectList(neInfo model.NeInfo) []model.NeInfo { } // 查询数据 - querySql := r.selectSql + whereSql + " order by ne_type asc, ne_id desc " + querySql := r.selectSql + whereSql + " order by ne_type asc, ne_id asc " results, err := datasource.RawDB("", querySql, params) if err != nil { logger.Errorf("query err => %v", err) diff --git a/src/modules/network_element/service/ne_host.go b/src/modules/network_element/service/ne_host.go index 7b6f0c16..08f54432 100644 --- a/src/modules/network_element/service/ne_host.go +++ b/src/modules/network_element/service/ne_host.go @@ -10,7 +10,7 @@ type INeHost interface { // SelectList 根据实体查询 SelectList(neHost model.NeHost) []model.NeHost - // SelectByIds 通过ID查询 + // SelectById 通过ID查询 SelectById(hostId string) model.NeHost // CheckUniqueHostTitle 校验分组组和主机名称是否唯一 diff --git a/src/modules/network_element/service/ne_info.go b/src/modules/network_element/service/ne_info.go index b3e9838c..94e08e63 100644 --- a/src/modules/network_element/service/ne_info.go +++ b/src/modules/network_element/service/ne_info.go @@ -1,8 +1,8 @@ package service import ( + "be.ems/src/framework/telnet" "be.ems/src/framework/utils/ssh" - "be.ems/src/framework/utils/telnet" "be.ems/src/modules/network_element/model" ) @@ -58,11 +58,11 @@ type INeInfo interface { // num 是网元主机telnet 1:4100 2:5200 NeRunTelnetClient(neType, neId string, num int) (*telnet.ConnTelnet, error) - // neConfOAMRead 网元OAM配置文件读取 - NeConfOAMRead(neType, neId string) (map[string]any, error) + // NeConfOAMReadSync 网元OAM配置文件读取 + NeConfOAMReadSync(neType, neId string) (map[string]any, error) - // NeConfOAMSync 网元OAM配置文件生成并同步 - NeConfOAMSync(neInfo model.NeInfo, content map[string]any, sync bool) error + // NeConfOAMWirteSync 网元OAM配置文件生成并同步 + NeConfOAMWirteSync(neInfo model.NeInfo, content map[string]any, sync bool) error // NeConfPara5GRead 网元公共配置文件读取 NeConfPara5GRead() (map[string]any, error) diff --git a/src/modules/network_element/service/ne_info.impl.go b/src/modules/network_element/service/ne_info.impl.go index 0dedbb18..ee18501a 100644 --- a/src/modules/network_element/service/ne_info.impl.go +++ b/src/modules/network_element/service/ne_info.impl.go @@ -11,9 +11,9 @@ import ( "be.ems/src/framework/constants/cachekey" "be.ems/src/framework/logger" "be.ems/src/framework/redis" + "be.ems/src/framework/telnet" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/ssh" - "be.ems/src/framework/utils/telnet" neFetchlink "be.ems/src/modules/network_element/fetch_link" "be.ems/src/modules/network_element/model" "be.ems/src/modules/network_element/repository" @@ -429,13 +429,74 @@ func (r *NeInfoImpl) NeRunTelnetClient(neType, neId string, num int) (*telnet.Co return telnetClient, nil } +// NeConfOAMReadSync 网元OAM配置文件读取 +func (r *NeInfoImpl) NeConfOAMReadSync(neType, neId string) (map[string]any, error) { + oamData, err := r.neConfOAMRead(neType, neId, true) + if err != nil { + return nil, err + } + + // UPF和SMF 全小写的key + if _, ok := oamData["httpmanagecfg"]; ok { + content := map[string]any{} + // 网元HTTP服务 + // if v, ok := oamData["httpmanagecfg"]; ok { + // item := v.(map[string]any) + // } + // 对网管HTTP配置 + if v, ok := oamData["oamconfig"]; ok { + item := v.(map[string]any) + if v, ok := item["iptype"]; ok && v != "" && v != nil { + ipType := v.(string) + if ipType == "ipv6" { + content["omcIP"] = item["ipv6"] + } + if ipType == "ipv4" { + content["omcIP"] = item["ipv4"] + } + } + content["oamEnable"] = item["enable"] + content["oamPort"] = item["port"] + } + // 对网管SNMP配置 + if v, ok := oamData["snmpconfig"]; ok { + item := v.(map[string]any) + content["snmpEnable"] = item["enable"] + content["snmpPort"] = item["port"] + } + // 对网管KPI上报配置 + if v, ok := oamData["kpiconfig"]; ok { + item := v.(map[string]any) + content["kpiEnable"] = item["enable"] + content["kpiTimer"] = item["timer"] + } + + oamData := r.neConfOAMData() + r.neConfOAMWirte(neType, neId, oamData, false) + r.NeConfOAMWirteSync(model.NeInfo{ + NeType: neType, + NeId: neId, + }, content, false) + return r.neConfOAMRead(neType, neId, false) + } + + // NSSF和MME 配置KPIconfig名不一致时 + if v, ok := oamData["KPIconfig"]; ok && v != nil { + item := v.(map[string]any) + oamData["kpiConfig"] = item + delete(oamData, "KPIconfig") + r.neConfOAMWirte(neType, neId, oamData, false) + } + + return oamData, nil +} + // neConfOAMData 网元OAM配置文件默认格式数据 func (r *NeInfoImpl) neConfOAMData() map[string]any { return map[string]any{ "httpManageCfg": map[string]any{ "ipType": "ipv4", - // 必改 - "ipv4": "172.60.5.2", + "ipv4": "172.16.5.1", // 必改 "ipv6": "", "port": 33030, "scheme": "http", @@ -443,11 +504,12 @@ func (r *NeInfoImpl) neConfOAMData() map[string]any { "oamConfig": map[string]any{ "enable": true, "ipType": "ipv4", - "ipv4": "172.60.5.1", // 必改 + "ipv4": "172.16.5.100", // 必改 "ipv6": "", "port": 33030, "scheme": "http", - "neConfig": map[string]any{ // 必改 + // 必改 + "neConfig": map[string]any{ "neId": "001", "rmUid": "4400HX1XXX001", "neName": "XXX_001", @@ -460,7 +522,7 @@ func (r *NeInfoImpl) neConfOAMData() map[string]any { "snmpConfig": map[string]any{ "enable": false, "ipType": "ipv4", - "ipv4": "172.60.5.2", // 必改 + "ipv4": "172.16.5.1", // 必改 "ipv6": "", "port": 4957, }, @@ -472,15 +534,39 @@ func (r *NeInfoImpl) neConfOAMData() map[string]any { } } -// neConfOAMRead 网元OAM配置文件读取 -func (r *NeInfoImpl) NeConfOAMRead(neType, neId string) (map[string]any, error) { +// neConfOAMRead 网元OAM配置文件读取 sync从网元端同步到本地 +func (r *NeInfoImpl) neConfOAMRead(neType, neId string, sync bool) (map[string]any, error) { neTypeLower := strings.ToLower(neType) + fileName := "oam_manager.yaml" // 网管本地路径 - omcPath := "/usr/local/etc/omc/ne_config" + localFilePath := fmt.Sprintf("/usr/local/etc/omc/ne_config/%s/%s/%s", neTypeLower, neId, fileName) if runtime.GOOS == "windows" { - omcPath = fmt.Sprintf("C:%s", omcPath) + localFilePath = fmt.Sprintf("C:%s", localFilePath) + } + + // 从网元端同步到本地 + if sync { + // 网元主机的SSH客户端 + sshClient, err := NewNeInfoImpl.NeRunSSHClient(neType, neId) + if err != nil { + return nil, fmt.Errorf("ne info ssh client err") + } + defer sshClient.Close() + // 网元主机的SSH客户端进行文件传输 + sftpClient, err := sshClient.NewClientSFTP() + if err != nil { + return nil, fmt.Errorf("ne info sftp client err") + } + defer sftpClient.Close() + // 网元端文件路径 + neFilePath := fmt.Sprintf("/usr/local/etc/%s/%s", neTypeLower, fileName) + // 修改网元文件权限 + sshClient.RunCMD(fmt.Sprintf("sudo touch %s && sudo chmod o+rw %s", neFilePath, neFilePath)) + // 网元端复制到本地 + if err = sftpClient.CopyFileRemoteToLocal(neFilePath, localFilePath); err != nil { + return nil, fmt.Errorf("copy oam config err") + } } - localFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neId, "oam_manager.yaml") // 读取文件内容 bytes, err := os.ReadFile(localFilePath) @@ -538,7 +624,7 @@ func (r *NeInfoImpl) neConfOAMWirte(neType, neId string, content any, sync bool) neFilePath := fmt.Sprintf("/usr/local/etc/%s/%s", neTypeLower, fileName) neFileDir := filepath.ToSlash(filepath.Dir(neFilePath)) // 修改网元文件权限 - sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p %s && sudo chmod 775 %s && sudo touch %s && sudo chmod o+w %s", neFileDir, neFileDir, neFilePath, neFilePath)) + sshClient.RunCMD(fmt.Sprintf("sudo mkdir -p %s && sudo chmod 775 %s && sudo touch %s && sudo chmod o+rw %s", neFileDir, neFileDir, neFilePath, neFilePath)) // 复制到网元进行覆盖 if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil { return fmt.Errorf("please check if scp remote copy is allowed") @@ -548,9 +634,9 @@ func (r *NeInfoImpl) neConfOAMWirte(neType, neId string, content any, sync bool) return nil } -// NeConfOAMSync 网元OAM配置文件生成并同步 -func (r *NeInfoImpl) NeConfOAMSync(neInfo model.NeInfo, content map[string]any, sync bool) error { - oamData, err := r.NeConfOAMRead(neInfo.NeType, neInfo.NeId) +// NeConfOAMWirteSync 网元OAM配置文件生成并同步 +func (r *NeInfoImpl) NeConfOAMWirteSync(neInfo model.NeInfo, content map[string]any, sync bool) error { + oamData, err := r.neConfOAMRead(neInfo.NeType, neInfo.NeId, false) if oamData == nil || err != nil { return fmt.Errorf("error read OAM file info") } @@ -638,6 +724,8 @@ func (r *NeInfoImpl) NeConfOAMSync(neInfo model.NeInfo, content map[string]any, item := v.(map[string]any) if neInfo.NeType == "UPF" { item["timer"] = 5 + } else { + item["timer"] = 60 } if kpiEnable, ok := content["kpiEnable"]; ok && kpiEnable != nil { diff --git a/src/modules/network_element/service/ne_version.impl.go b/src/modules/network_element/service/ne_version.impl.go index 6d309223..11549142 100644 --- a/src/modules/network_element/service/ne_version.impl.go +++ b/src/modules/network_element/service/ne_version.impl.go @@ -200,18 +200,26 @@ func (r *NeVersionImpl) operateCommand(action, neType string, neFilePaths []stri cmdStrArr := []string{} if neType == "OMC" { omcStrArr := []string{} - omcStrArr = append(omcStrArr, pkgCmdStr) if action == "install" { - omcStrArr = append(omcStrArr, "/usr/local/omc/bin/setomc.sh -m install") // 初始化数据库 + // 安装软件包 + pkgCmdStr = fmt.Sprintf("sudo M_PARAM=install dpkg -i %s", strings.Join(neFilePaths, " ")) + if strings.HasSuffix(fileExt, "rpm") { + pkgCmdStr = fmt.Sprintf("sudo M_PARAM=install rpm -Uvh %s", strings.Join(neFilePaths, " ")) + } + omcStrArr = append(omcStrArr, pkgCmdStr) } else { - omcStrArr = append(omcStrArr, "/usr/local/omc/bin/setomc.sh -m upgrade") // 升级数据库 + // 升级软件包 + pkgCmdStr = fmt.Sprintf("sudo M_PARAM=upgrade dpkg -i %s", strings.Join(neFilePaths, " ")) + if strings.HasSuffix(fileExt, "rpm") { + pkgCmdStr = fmt.Sprintf("sudo M_PARAM=upgrade rpm -Uvh %s", strings.Join(neFilePaths, " ")) + } + omcStrArr = append(omcStrArr, pkgCmdStr) } - omcStrArr = append(omcStrArr, "sudo systemctl restart restagent") // 重启服务 - omcStrArr = append(omcStrArr, fmt.Sprintf("sudo rm %s", strings.Join(neFilePaths, " "))) // 删除软件包 + // 删除软件包 + omcStrArr = append(omcStrArr, fmt.Sprintf("sudo rm %s", strings.Join(neFilePaths, " "))) - // 2s后安装 + // 2s后执行omc相关命令 cmdStrArr = append(cmdStrArr, fmt.Sprintf("nohup sh -c \"sleep 2s && %s\" > /tmp/omc_%s.out 2>&1 & \n", strings.Join(omcStrArr, " && "), action)) - // 结束 cmdStrArr = append(cmdStrArr, fmt.Sprintf("echo '%s' \n", okFlagStr)) return okFlagStr, cmdStrArr, nil } else if neType == "IMS" { @@ -473,14 +481,14 @@ func (r *NeVersionImpl) operateCommand(action, neType string, neFilePaths []stri if strings.Contains(pkgCmdStr, "adb") { para5GData := NewNeInfoImpl.Para5GData cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/adb/default/adb.conf /usr/local/etc/adb/adb.conf \n") - cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/bind 127.0.0.1/bind %s/g\" /usr/local/etc/adb/adb.conf \n", para5GData["DB_IP"])) + cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/bind 127.0.0.1/bind 127.0.0.1 %s/g\" /usr/local/etc/adb/adb.conf \n", para5GData["DB_IP"])) cmdStrArr = append(cmdStrArr, "sudo service adb restart \n") } // kvdb if strings.Contains(pkgCmdStr, "kvdb") { para5GData := NewNeInfoImpl.Para5GData cmdStrArr = append(cmdStrArr, "sudo cp /usr/local/etc/kvdb/default/kvdb.conf /usr/local/etc/kvdb/kvdb.conf \n") - cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/bind 127.0.0.1/bind %s/g\" /usr/local/etc/kvdb/kvdb.conf \n", para5GData["DB_IP"])) + cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/bind 127.0.0.1/bind 127.0.0.1 %s/g\" /usr/local/etc/kvdb/kvdb.conf \n", para5GData["DB_IP"])) cmdStrArr = append(cmdStrArr, "sudo service kvdb restart \n") } } @@ -592,7 +600,7 @@ func (r *NeVersionImpl) operateDome(action string, neVersion model.NeVersion) er return fmt.Errorf("error found neinfo") } // ========= 网元OAM配置文件 start ========== - if err := NewNeInfoImpl.NeConfOAMSync(neInfo, nil, true); err != nil { + if err := NewNeInfoImpl.NeConfOAMWirteSync(neInfo, nil, true); err != nil { return fmt.Errorf("error wirte OAM file info") } // ========= 网元OAM配置文件 end =========== diff --git a/src/modules/trace/controller/tcpdump.go b/src/modules/trace/controller/tcpdump.go index 94012723..0f0d7bd0 100644 --- a/src/modules/trace/controller/tcpdump.go +++ b/src/modules/trace/controller/tcpdump.go @@ -15,7 +15,7 @@ import ( // 实例化控制层 TcpdumpController 结构体 var NewTcpdump = &TcpdumpController{ - TcpdumpService: traceService.NewTcpdumpImpl, + TcpdumpService: traceService.NewTCPdump, neInfoService: neService.NewNeInfoImpl, } @@ -24,7 +24,7 @@ var NewTcpdump = &TcpdumpController{ // PATH /tcpdump type TcpdumpController struct { // 信令抓包服务 - TcpdumpService traceService.ITcpdump + TcpdumpService *traceService.TCPdump // 网元信息服务 neInfoService neService.INeInfo } diff --git a/src/modules/trace/controller/trace_data.go b/src/modules/trace/controller/trace_data.go new file mode 100644 index 00000000..2d8222b9 --- /dev/null +++ b/src/modules/trace/controller/trace_data.go @@ -0,0 +1,62 @@ +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" + traceService "be.ems/src/modules/trace/service" + "github.com/gin-gonic/gin" +) + +// 实例化控制层 TraceDataController 结构体 +var NewTraceData = &TraceDataController{ + traceDataService: traceService.NewTraceData, +} + +// 跟踪任务数据 +// +// PATH /data +type TraceDataController struct { + // 跟踪_数据信息服务 + traceDataService *traceService.TraceData +} + +// 跟踪任务数据列表 +// +// GET /list +func (s *TraceDataController) List(c *gin.Context) { + query := ctx.QueryMap(c) + + // 查询数据 + data := s.traceDataService.SelectPage(query) + c.JSON(200, result.Ok(data)) +} + +// 跟踪任务数据删除 +// +// DELETE /:ids +func (s *TraceDataController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) + rowIds := c.Param("ids") + if rowIds == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + // 处理字符转id数组后去重 + ids := strings.Split(rowIds, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + c.JSON(200, result.Err(nil)) + return + } + rows, err := s.traceDataService.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)) +} diff --git a/src/modules/trace/controller/trace_task.go b/src/modules/trace/controller/trace_task.go new file mode 100644 index 00000000..7598c567 --- /dev/null +++ b/src/modules/trace/controller/trace_task.go @@ -0,0 +1,131 @@ +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/trace/model" + traceService "be.ems/src/modules/trace/service" + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" +) + +// 实例化控制层 TraceTaskController 结构体 +var NewTraceTask = &TraceTaskController{ + traceTaskService: traceService.NewTraceTask, +} + +// 跟踪任务 +// +// PATH /task +type TraceTaskController struct { + // 跟踪_任务信息服务 + traceTaskService *traceService.TraceTask +} + +// 跟踪任务列表 +// +// GET /list +func (s *TraceTaskController) List(c *gin.Context) { + query := ctx.QueryMap(c) + + // 查询数据 + data := s.traceTaskService.SelectPage(query) + c.JSON(200, result.Ok(data)) +} + +// 跟踪任务信息 +// +// GET /:id +func (s *TraceTaskController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) + id := c.Param("id") + if id == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + data := s.traceTaskService.SelectById(id) + if data.ID == id { + c.JSON(200, result.OkData(data)) + return + } + c.JSON(200, result.Err(nil)) +} + +// 跟踪任务新增 +// +// POST / +func (s *TraceTaskController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.TraceTask + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil || body.ID != "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + body.CreateBy = ctx.LoginUserToUserName(c) + if err = s.traceTaskService.Insert(body); err != nil { + c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error()))) + return + } + c.JSON(200, result.Ok(nil)) +} + +// 跟踪任务修改 +// +// PUT / +func (s *TraceTaskController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.TraceTask + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil || body.ID == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 检查是否存在 + taskInfo := s.traceTaskService.SelectById(body.ID) + if taskInfo.ID != body.ID { + // 没有可访问任务信息数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "task.noData"))) + return + } + + body.UpdateBy = ctx.LoginUserToUserName(c) + if err = s.traceTaskService.Update(body); err != nil { + c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error()))) + return + } + c.JSON(200, result.Ok(nil)) +} + +// 跟踪任务删除 +// +// DELETE /:ids +func (s *TraceTaskController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) + rowIds := c.Param("ids") + if rowIds == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + // 处理字符转id数组后去重 + ids := strings.Split(rowIds, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + c.JSON(200, result.Err(nil)) + return + } + rows, err := s.traceTaskService.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)) +} diff --git a/src/modules/trace/controller/trace_task_hlr.go b/src/modules/trace/controller/trace_task_hlr.go new file mode 100644 index 00000000..4b659015 --- /dev/null +++ b/src/modules/trace/controller/trace_task_hlr.go @@ -0,0 +1,242 @@ +package controller + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + + "be.ems/src/framework/i18n" + "be.ems/src/framework/utils/ctx" + "be.ems/src/framework/utils/generate" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/vo/result" + neService "be.ems/src/modules/network_element/service" + "be.ems/src/modules/trace/model" + traceService "be.ems/src/modules/trace/service" + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" +) + +// 实例化控制层 TraceTaskHlrController 结构体 +var NewTraceTaskHlr = &TraceTaskHlrController{ + neInfoService: neService.NewNeInfoImpl, + traceTaskHlrService: traceService.NewTraceTaskHlr, +} + +// 跟踪任务网元HLR +// +// PATH /task/hlr +type TraceTaskHlrController struct { + // 网元信息服务 + neInfoService neService.INeInfo + // 跟踪_任务给HRL网元信息服务 + traceTaskHlrService *traceService.TraceTaskHlr +} + +// 跟踪任务列表 +// +// GET /list +func (s *TraceTaskHlrController) List(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys model.TraceTaskHlrQuery + if err := c.ShouldBindQuery(&querys); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询数据 + data := s.traceTaskHlrService.SelectPage(querys) + c.JSON(200, result.Ok(data)) +} + +// 跟踪任务删除 +// +// DELETE /:ids +func (s *TraceTaskHlrController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) + rowIds := c.Param("ids") + if rowIds == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + // 处理字符转id数组后去重 + ids := strings.Split(rowIds, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + c.JSON(200, result.Err(nil)) + return + } + rows, err := s.traceTaskHlrService.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)) +} + +// 跟踪任务创建 +// +// POST /start +func (s *TraceTaskHlrController) Start(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body struct { + IMSI string `json:"imsi"` // IMSI + MSISDN string `json:"msisdn"` // MSISDN + StartTime int64 `json:"startTime"` // 开始时间 + EndTime int64 `json:"endTime"` // 结束时间 + Remark string `json:"remark"` // 备注说明 + } + if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + if body.IMSI == "" && body.MSISDN == "" { + c.JSON(400, result.CodeMsg(400, "imsi amd msisdn is empty")) + return + } + + task := model.TraceTaskHlr{ + IMSI: body.IMSI, + MSISDN: body.MSISDN, + StartTime: body.StartTime, + EndTime: body.EndTime, + Remark: body.Remark, + CreateBy: ctx.LoginUserToUserName(c), + } + id, err := s.traceTaskHlrService.Start(task) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.OkData(id)) +} + +// 跟踪任务停止 +// +// POST /stop +func (s *TraceTaskHlrController) Stop(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body struct { + ID string `json:"id" binding:"required"` // 任务ID + } + if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 处理字符转id数组后去重 + ids := strings.Split(body.ID, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + c.JSON(200, result.Err(nil)) + return + } + + errArr := []map[string]any{} + for _, id := range uniqueIDs { + task := s.traceTaskHlrService.SelectById(id) + if task.ID != id || task.ID == "" { + errArr = append(errArr, map[string]any{"id": id, "err": "task not found"}) + continue + } + + task.UpdateBy = ctx.LoginUserToUserName(c) + err := s.traceTaskHlrService.Stop(task) + if err != nil { + errArr = append(errArr, map[string]any{"id": id, "err": err.Error()}) + continue + } + } + c.JSON(200, result.OkData(errArr)) +} + +// 跟踪任务文件 +// +// POST /file +func (s *TraceTaskHlrController) File(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body struct { + ID string `json:"id" binding:"required"` // 任务ID + Dir string `json:"dir" binding:"required"` // 网元文件目录 + } + if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + task := s.traceTaskHlrService.SelectById(body.ID) + if task.ID != body.ID || task.ID == "" { + c.JSON(200, result.CodeMsg(400, "task not found")) + return + } + + list, err := s.traceTaskHlrService.File(task.TraceId, body.Dir) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.OkData(list)) +} + +// 跟踪任务文件从网元到本地 +// +// GET /filePull +func (s *TraceTaskHlrController) FilePull(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys struct { + NeType string `form:"neType" binding:"required"` + NeID string `form:"neId" binding:"required"` + Path string `form:"path" binding:"required"` + FileName string `form:"fileName" binding:"required"` + DelTemp bool `form:"delTemp"` // 删除本地临时文件 + } + 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 + } + + // 网元主机的SSH客户端 + sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + defer sshClient.Close() + // 网元主机的SSH客户端进行文件传输 + sftpClient, err := sshClient.NewClientSFTP() + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + defer sftpClient.Close() + + nePath := filepath.ToSlash(filepath.Join(querys.Path, querys.FileName)) + fileName := generate.Code(6) + "_" + querys.FileName + localFilePath := filepath.Join("/tmp/omc/pull", fileName) + if runtime.GOOS == "windows" { + localFilePath = fmt.Sprintf("C:%s", localFilePath) + } + // 复制到本地 + if err = sftpClient.CopyFileRemoteToLocal(nePath, localFilePath); err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + + defer func() { + if querys.DelTemp { + _ = os.Remove(localFilePath) + } + }() + c.FileAttachment(localFilePath, fileName) +} diff --git a/src/modules/trace/model/trace_data.go b/src/modules/trace/model/trace_data.go new file mode 100644 index 00000000..368d16e7 --- /dev/null +++ b/src/modules/trace/model/trace_data.go @@ -0,0 +1,23 @@ +package model + +// TraceData 跟踪_数据 trace_data +type TraceData struct { + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` + TaskId int64 `json:"taskId" gorm:"task_id"` // 任务ID + IMSI string `json:"imsi" gorm:"imsi"` + MSISDN string `json:"msisdn" gorm:"msisdn"` // 可能存在 + SrcAddr string `json:"srcAddr" gorm:"src_addr"` // 源地址带端口 + DstAddr string `json:"dstAddr" gorm:"dst_addr"` // 目标地址带端口 + IfType int64 `json:"ifType" gorm:"if_type"` // 接口类型,未分类 + MsgType int64 `json:"msgType" gorm:"msg_type"` + MsgDirect int64 `json:"msgDirect" gorm:"msg_direct"` + Length int64 `json:"length" gorm:"length"` // 去除头后的原始数据byte长度 + Timestamp int64 `json:"timestamp" gorm:"timestamp"` // 毫秒 + RawMsg string `json:"rawMsg" gorm:"raw_msg"` // 去除头后的原始数据byteBase64 + DecMsg string `json:"decMsg" gorm:"dec_msg"` // TCP内容消息 +} + +// TableName 表名称 +func (*TraceData) TableName() string { + return "trace_data" +} diff --git a/src/modules/trace/model/trace_task.go b/src/modules/trace/model/trace_task.go new file mode 100644 index 00000000..752d4f70 --- /dev/null +++ b/src/modules/trace/model/trace_task.go @@ -0,0 +1,31 @@ +package model + +// TraceTask 跟踪_任务 +type TraceTask struct { + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 跟踪任务ID + TraceId string `json:"traceId" gorm:"trace_id"` // 任务编号 + TraceType string `json:"traceType" gorm:"trace_type"` // 1-Interface,2-Device,3-User + StartTime int64 `json:"startTime" gorm:"start_time"` // 开始时间 毫秒 + EndTime int64 `json:"endTime" gorm:"end_time"` // 结束时间 毫秒 + Interfaces string `json:"interfaces" gorm:"interfaces"` // 接口跟踪必须 例如 N8,N10 + IMSI string `json:"imsi" gorm:"imsi"` // 用户跟踪必须 + MSISDN string `json:"msisdn" gorm:"msisdn"` // 用户跟踪可选 + UeIp string `json:"ueIp" gorm:"ue_ip"` // 设备跟踪必须 IP + SrcIp string `json:"srcIp" gorm:"src_ip"` // 源地址IP + DstIp string `json:"dstIp" gorm:"dst_ip"` // 目标地址IP + SignalPort int64 `json:"signalPort" gorm:"signal_port"` // 地址IP端口 + CreateBy string `json:"createBy" gorm:"create_by"` // 创建者 + CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间 + UpdateBy string `json:"updateBy" gorm:"update_by"` // 更新者 + UpdateTime int64 `json:"updateTime" gorm:"update_time"` // 更新时间 + Remark string `json:"remark" gorm:"remark"` // 备注 + NeType string `json:"neType" gorm:"ne_type"` // 网元类型 + NeId string `json:"neId" gorm:"ne_id"` // 网元ID + NotifyUrl string `json:"notifyUrl" gorm:"notify_url"` // 信息数据通知回调地址UDP 例如udp:192.168.5.58:29500 + FetchMsg string `json:"fetchMsg" gorm:"fetch_msg"` // 任务下发请求响应消息 +} + +// TableName 表名称 +func (*TraceTask) TableName() string { + return "trace_task" +} diff --git a/src/modules/trace/model/trace_task_hlr.go b/src/modules/trace/model/trace_task_hlr.go new file mode 100644 index 00000000..2d306c4d --- /dev/null +++ b/src/modules/trace/model/trace_task_hlr.go @@ -0,0 +1,35 @@ +package model + +// TraceTaskHlr 跟踪_任务给HRL网元 trace_task_hlr +type TraceTaskHlr struct { + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` + TraceId string `json:"traceId" gorm:"trace_id"` // 任务编号 + IMSI string `json:"imsi" gorm:"imsi"` // IMSI + MSISDN string `json:"msisdn" gorm:"msisdn"` // MSISDN + StartTime int64 `json:"startTime" gorm:"start_time"` // 开始时间 + EndTime int64 `json:"endTime" gorm:"end_time"` // 结束时间 + Status string `json:"status" gorm:"status"` // 任务状态(0停止 1进行) + Msg string `json:"msg" gorm:"msg"` // 任务信息 + Remark string `json:"remark" gorm:"remark"` // 备注说明 + CreateBy string `json:"createBy" gorm:"create_by"` // 创建者 + CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间 + UpdateBy string `json:"updateBy" gorm:"update_by"` // 更新者 + UpdateTime int64 `json:"updateTime" gorm:"update_time"` // 更新时间 +} + +// TableName 表名称 +func (*TraceTaskHlr) TableName() string { + return "trace_task_hlr" +} + +// TraceTaskHlrQuery 查询参数结构体 +type TraceTaskHlrQuery struct { + IMSI string `json:"imsi" form:"imsi"` // imsi + MSISDN string `json:"msisdn" form:"msisdn"` // msisdn + StartTime string `json:"startTime" form:"startTime"` + EndTime string `json:"endTime" form:"endTime"` + SortField string `json:"sortField" form:"sortField" binding:"omitempty,oneof=imsi msisdn"` // 排序字段,填写结果字段 + 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"` +} diff --git a/src/modules/trace/repository/trace_data.go b/src/modules/trace/repository/trace_data.go new file mode 100644 index 00000000..c1e791b4 --- /dev/null +++ b/src/modules/trace/repository/trace_data.go @@ -0,0 +1,246 @@ +package repository + +import ( + "strings" + + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" + "be.ems/src/modules/trace/model" +) + +// 实例化数据层 TraceData 结构体 +var NewTraceData = &TraceData{ + selectSql: `select id, task_id, imsi, msisdn, src_addr, dst_addr, if_type, msg_type, msg_direct, length, timestamp, raw_msg, dec_msg from trace_data`, + + resultMap: map[string]string{ + "id": "ID", + "task_id": "TaskId", + "imsi": "IMSI", + "msisdn": "MSISDN", + "src_addr": "SrcAddr", + "dst_addr": "DstAddr", + "if_type": "IfType", + "msg_type": "MsgType", + "msg_direct": "MsgDirect", + "length": "Length", + "timestamp": "Timestamp", + "raw_msg": "RawMsg", + "dec_msg": "DecMsg", + }, +} + +// CDREventIMSImpl 跟踪_任务给HRL网元 数据层处理 +type TraceData struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *TraceData) convertResultRows(rows []map[string]any) []model.TraceData { + arr := make([]model.TraceData, 0) + for _, row := range rows { + item := model.TraceData{} + 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 *TraceData) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["imsi"]; ok && v != "" { + conditions = append(conditions, "imsi like concat(?, '%')") + params = append(params, v) + } + if v, ok := query["msisdn"]; ok && v != "" { + conditions = append(conditions, "msisdn like concat(?, '%')") + params = append(params, v) + } + if v, ok := query["startTime"]; ok && v != "" { + conditions = append(conditions, "timestamp >= ?") + params = append(params, v) + } + if v, ok := query["endTime"]; ok && v != "" { + conditions = append(conditions, "timestamp <= ?") + params = append(params, v) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.TraceData{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from trace_data" + 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(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 查询数据 + querySql := r.selectSql + whereSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + result["rows"] = r.convertResultRows(results) + return result +} + +// SelectList 根据实体查询 +func (r *TraceData) SelectList(data model.TraceData) []model.TraceData { + // 查询条件拼接 + var conditions []string + var params []any + if data.IMSI != "" { + conditions = append(conditions, "imsi = ?") + params = append(params, data.IMSI) + } + if data.MSISDN != "" { + conditions = append(conditions, "msisdn = ?") + params = append(params, data.MSISDN) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by id desc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIds 通过ID查询 +func (r *TraceData) SelectByIds(ids []string) []model.TraceData { + placeholder := repo.KeyPlaceholderByQuery(len(ids)) + querySql := r.selectSql + " where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(ids) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.TraceData{} + } + // 转换实体 + return r.convertResultRows(results) +} + +// Insert 新增信息 +func (r *TraceData) Insert(data model.TraceData) string { + // 参数拼接 + params := make(map[string]any) + if data.TaskId > 0 { + params["task_id"] = data.TaskId + } + if data.IMSI != "" { + params["imsi"] = data.IMSI + } + if data.MSISDN != "" { + params["msisdn"] = data.MSISDN + } + if data.SrcAddr != "" { + params["src_addr"] = data.SrcAddr + } + if data.DstAddr != "" { + params["dst_addr"] = data.DstAddr + } + if data.IfType > -1 { + params["if_type"] = data.IfType + } + if data.MsgType > -1 { + params["msg_type"] = data.MsgType + } + if data.MsgDirect > -1 { + params["msg_direct"] = data.MsgDirect + } + if data.Length > 0 { + params["length"] = data.Length + } + if data.Timestamp > 0 { + params["timestamp"] = data.Timestamp + } + if data.RawMsg != "" { + params["raw_msg"] = data.RawMsg + } + if data.DecMsg != "" { + params["dec_msg"] = data.DecMsg + } + + // 构建执行语句 + keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params) + sql := "insert into trace_data (" + strings.Join(keys, ",") + ")values(" + placeholder + ")" + + db := datasource.DefaultDB() + // 开启事务 + tx := db.Begin() + // 执行插入 + err := tx.Exec(sql, values...).Error + if err != nil { + logger.Errorf("insert row : %v", err.Error()) + tx.Rollback() + return "" + } + // 获取生成的自增 ID + var insertedID string + err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID) + if err != nil { + logger.Errorf("insert last id : %v", err.Error()) + tx.Rollback() + return "" + } + // 提交事务 + tx.Commit() + return insertedID +} + +// DeleteByIds 批量删除信息 +func (r *TraceData) DeleteByIds(ids []string) int64 { + placeholder := repo.KeyPlaceholderByQuery(len(ids)) + sql := "delete from trace_data where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(ids) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + logger.Errorf("delete err => %v", err) + return 0 + } + return results +} diff --git a/src/modules/trace/repository/trace_task.go b/src/modules/trace/repository/trace_task.go new file mode 100644 index 00000000..39f3aa30 --- /dev/null +++ b/src/modules/trace/repository/trace_task.go @@ -0,0 +1,358 @@ +package repository + +import ( + "fmt" + "strings" + "time" + + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" + "be.ems/src/modules/trace/model" +) + +// 实例化数据层 TraceTask 结构体 +var NewTraceTask = &TraceTask{ + selectSql: `select id, trace_id, trace_type, start_time, end_time, + interfaces, imsi, msisdn, + ue_ip, src_ip, dst_ip, signal_port, + create_by, create_time, update_by, update_time, remark, + ne_type, ne_id, notify_url, fetch_msg + from trace_task`, + + resultMap: map[string]string{ + "id": "ID", + "trace_id": "TraceId", + "trace_type": "TraceType", + "start_time": "StartTime", + "end_time": "EndTime", + "interfaces": "Interfaces", + "imsi": "IMSI", + "msisdn": "MSISDN", + "ue_ip": "UeIp", + "src_ip": "SrcIp", + "dst_ip": "DstIp", + "signal_port": "SignalPort", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", + "update_time": "UpdateTime", + "remark": "Remark", + "ne_type": "NeType", + "ne_id": "NeId", + "notify_url": "NotifyUrl", + "fetch_msg": "FetchMsg", + }, +} + +// TraceTask 跟踪_任务 数据层处理 +type TraceTask struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *TraceTask) convertResultRows(rows []map[string]any) []model.TraceTask { + arr := make([]model.TraceTask, 0) + for _, row := range rows { + item := model.TraceTask{} + 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 *TraceTask) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["neType"]; ok && v != "" { + conditions = append(conditions, "ne_type = ?") + params = append(params, v) + } + if v, ok := query["imsi"]; ok && v != "" { + conditions = append(conditions, "imsi like concat(?, '%')") + params = append(params, v) + } + if v, ok := query["msisdn"]; ok && v != "" { + conditions = append(conditions, "msisdn like concat(?, '%')") + params = append(params, v) + } + if v, ok := query["startTime"]; ok && v != "" { + conditions = append(conditions, "start_time >= ?") + params = append(params, v) + } + if v, ok := query["endTime"]; ok && v != "" { + conditions = append(conditions, "end_time <= ?") + params = append(params, v) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.TraceTask{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from trace_task" + 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(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 排序 + orderSql := "" + if v, ok := query["sortField"]; ok && v != "" { + sortSql := v.(string) + if v, ok := query["sortOrder"]; ok && v != "" { + if v.(string) == "desc" { + sortSql += " desc " + } else { + sortSql += " asc " + } + } + orderSql = fmt.Sprintf(" order by %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 +} + +// SelectList 根据实体查询 +func (r *TraceTask) SelectList(task model.TraceTask) []model.TraceTask { + // 查询条件拼接 + var conditions []string + var params []any + if task.IMSI != "" { + conditions = append(conditions, "imsi = ?") + params = append(params, task.IMSI) + } + if task.SrcIp != "" { + conditions = append(conditions, "src_ip = ?") + params = append(params, task.SrcIp) + } + if task.DstIp != "" { + conditions = append(conditions, "dst_ip = ?") + params = append(params, task.DstIp) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by id desc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIds 通过ID查询 +func (r *TraceTask) SelectByIds(ids []string) []model.TraceTask { + placeholder := repo.KeyPlaceholderByQuery(len(ids)) + querySql := r.selectSql + " where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(ids) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.TraceTask{} + } + // 转换实体 + return r.convertResultRows(results) +} + +// Insert 新增信息 +func (r *TraceTask) Insert(task model.TraceTask) string { + // 参数拼接 + params := make(map[string]any) + if task.TraceId != "" { + params["trace_id"] = task.TraceId + } + if task.TraceType != "" { + params["trace_type"] = task.TraceType + } + if task.StartTime > 0 { + params["start_time"] = task.StartTime + } + if task.EndTime > 0 { + params["end_time"] = task.EndTime + } + if task.Interfaces != "" { + params["interfaces"] = task.Interfaces + } + if task.IMSI != "" { + params["imsi"] = task.IMSI + } + if task.MSISDN != "" { + params["msisdn"] = task.MSISDN + } + if task.UeIp != "" { + params["ue_ip"] = task.UeIp + } + if task.SrcIp != "" { + params["src_ip"] = task.SrcIp + } + if task.DstIp != "" { + params["dst_ip"] = task.DstIp + } + if task.SignalPort != 0 { + params["signal_port"] = task.SignalPort + } + if task.NeType != "" { + params["ne_type"] = task.NeType + } + if task.NeId != "" { + params["ne_id"] = task.NeId + } + if task.NotifyUrl != "" { + params["notify_url"] = task.NotifyUrl + } + if task.FetchMsg != "" { + params["fetch_msg"] = task.FetchMsg + } + if task.Remark != "" { + params["remark"] = task.Remark + } + if task.CreateBy != "" { + params["create_by"] = task.CreateBy + params["create_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params) + sql := "insert into trace_task (" + strings.Join(keys, ",") + ")values(" + placeholder + ")" + + db := datasource.DefaultDB() + // 开启事务 + tx := db.Begin() + // 执行插入 + err := tx.Exec(sql, values...).Error + if err != nil { + logger.Errorf("insert row : %v", err.Error()) + tx.Rollback() + return "" + } + // 获取生成的自增 ID + var insertedID string + err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID) + if err != nil { + logger.Errorf("insert last id : %v", err.Error()) + tx.Rollback() + return "" + } + // 提交事务 + tx.Commit() + return insertedID +} + +// Update 修改信息 +func (r *TraceTask) Update(task model.TraceTask) int64 { + // 参数拼接 + params := make(map[string]any) + params["trace_id"] = task.TraceId + params["trace_type"] = task.TraceType + params["ne_type"] = task.NeType + params["ne_id"] = task.NeId + params["notify_url"] = task.NotifyUrl + + params["start_time"] = task.StartTime + params["end_time"] = task.EndTime + params["fetch_msg"] = task.FetchMsg + params["remark"] = task.Remark + + params["interfaces"] = task.Interfaces + + params["imsi"] = task.IMSI + params["msisdn"] = task.MSISDN + + params["ue_ip"] = task.UeIp + params["src_ip"] = task.SrcIp + params["dst_ip"] = task.DstIp + params["signal_port"] = task.SignalPort + + if task.UpdateBy != "" { + params["update_by"] = task.UpdateBy + params["update_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, values := repo.KeyValueByUpdate(params) + sql := "update trace_task set " + strings.Join(keys, ",") + " where id = ?" + + // 执行更新 + values = append(values, task.ID) + rows, err := datasource.ExecDB("", sql, values) + if err != nil { + logger.Errorf("update row : %v", err.Error()) + return 0 + } + return rows +} + +// DeleteByIds 批量删除信息 +func (r *TraceTask) DeleteByIds(ids []string) int64 { + placeholder := repo.KeyPlaceholderByQuery(len(ids)) + sql := "delete from trace_task where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(ids) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + logger.Errorf("delete err => %v", err) + return 0 + } + return results +} + +// LastID 最后一条ID +func (r *TraceTask) LastID() int64 { + // 查询数据 + querySql := "SELECT id as 'str' FROM trace_task ORDER BY id DESC LIMIT 1" + results, err := datasource.RawDB("", querySql, nil) + if err != nil { + logger.Errorf("query err %v", err) + return 0 + } + if len(results) > 0 { + return parse.Number(results[0]["str"]) + } + return 0 +} diff --git a/src/modules/trace/repository/trace_task_hlr.go b/src/modules/trace/repository/trace_task_hlr.go new file mode 100644 index 00000000..15b6cbf5 --- /dev/null +++ b/src/modules/trace/repository/trace_task_hlr.go @@ -0,0 +1,316 @@ +package repository + +import ( + "fmt" + "strings" + "time" + + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" + "be.ems/src/modules/trace/model" +) + +// 实例化数据层 TraceTaskHlr 结构体 +var NewTraceTaskHlr = &TraceTaskHlr{ + selectSql: `select id, trace_id, imsi, msisdn, start_time, end_time, status, msg, remark, create_by, create_time, update_by, update_time from trace_task_hlr`, + + resultMap: map[string]string{ + "id": "ID", + "trace_id": "TraceId", + "imsi": "IMSI", + "msisdn": "MSISDN", + "start_time": "StartTime", + "end_time": "EndTime", + "status": "Status", + "msg": "Msg", + "remark": "Remark", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", + "update_time": "UpdateTime", + }, +} + +// TraceTaskHlr 跟踪_任务给HRL网元 数据层处理 +type TraceTaskHlr struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *TraceTaskHlr) convertResultRows(rows []map[string]any) []model.TraceTaskHlr { + arr := make([]model.TraceTaskHlr, 0) + for _, row := range rows { + item := model.TraceTaskHlr{} + 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 *TraceTaskHlr) SelectPage(querys model.TraceTaskHlrQuery) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if querys.IMSI != "" { + conditions = append(conditions, "imsi like concat(?, '%')") + params = append(params, querys.IMSI) + } + if querys.MSISDN != "" { + conditions = append(conditions, "msisdn like concat(?, '%')") + params = append(params, querys.MSISDN) + } + if querys.StartTime != "" && len(querys.StartTime) == 13 { + conditions = append(conditions, "start_time >= ?") + params = append(params, querys.StartTime) + } + if querys.EndTime != "" && len(querys.EndTime) == 13 { + conditions = append(conditions, "end_time <= ?") + params = append(params, querys.EndTime) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.TraceTaskHlr{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from trace_task_hlr" + 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 +} + +// SelectList 根据实体查询 +func (r *TraceTaskHlr) SelectList(task model.TraceTaskHlr) []model.TraceTaskHlr { + // 查询条件拼接 + var conditions []string + var params []any + if task.IMSI != "" { + conditions = append(conditions, "imsi = ?") + params = append(params, task.IMSI) + } + if task.MSISDN != "" { + conditions = append(conditions, "msisdn = ?") + params = append(params, task.MSISDN) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by id desc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIds 通过ID查询 +func (r *TraceTaskHlr) SelectByIds(ids []string) []model.TraceTaskHlr { + placeholder := repo.KeyPlaceholderByQuery(len(ids)) + querySql := r.selectSql + " where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(ids) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.TraceTaskHlr{} + } + // 转换实体 + return r.convertResultRows(results) +} + +// Insert 新增信息 +func (r *TraceTaskHlr) Insert(task model.TraceTaskHlr) string { + // 参数拼接 + params := make(map[string]any) + if task.TraceId != "" { + params["trace_id"] = task.TraceId + } + if task.IMSI != "" { + params["imsi"] = task.IMSI + } + if task.MSISDN != "" { + params["msisdn"] = task.MSISDN + } + if task.StartTime != 0 { + params["start_time"] = task.StartTime + } + if task.EndTime != 0 { + params["end_time"] = task.EndTime + } + if task.Status != "" { + params["status"] = task.Status + } + if task.Msg != "" { + params["msg"] = task.Msg + } + if task.Remark != "" { + params["remark"] = task.Remark + } + if task.CreateBy != "" { + params["create_by"] = task.CreateBy + params["create_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params) + sql := "insert into trace_task_hlr (" + strings.Join(keys, ",") + ")values(" + placeholder + ")" + + db := datasource.DefaultDB() + // 开启事务 + tx := db.Begin() + // 执行插入 + err := tx.Exec(sql, values...).Error + if err != nil { + logger.Errorf("insert row : %v", err.Error()) + tx.Rollback() + return "" + } + // 获取生成的自增 ID + var insertedID string + err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID) + if err != nil { + logger.Errorf("insert last id : %v", err.Error()) + tx.Rollback() + return "" + } + // 提交事务 + tx.Commit() + return insertedID +} + +// Update 修改信息 +func (r *TraceTaskHlr) Update(task model.TraceTaskHlr) int64 { + // 参数拼接 + params := make(map[string]any) + if task.TraceId != "" { + params["trace_id"] = task.TraceId + } + if task.IMSI != "" { + params["imsi"] = task.IMSI + } + if task.MSISDN != "" { + params["msisdn"] = task.MSISDN + } + if task.StartTime != 0 { + params["start_time"] = task.StartTime + } + if task.EndTime != 0 { + params["end_time"] = task.EndTime + } + if task.Status != "" { + params["status"] = task.Status + } + if task.Msg != "" { + params["msg"] = task.Msg + } + if task.Remark != "" { + params["remark"] = task.Remark + } + if task.UpdateBy != "" { + params["update_by"] = task.UpdateBy + params["update_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, values := repo.KeyValueByUpdate(params) + sql := "update trace_task_hlr set " + strings.Join(keys, ",") + " where id = ?" + + // 执行更新 + values = append(values, task.ID) + rows, err := datasource.ExecDB("", sql, values) + if err != nil { + logger.Errorf("update row : %v", err.Error()) + return 0 + } + return rows +} + +// DeleteByIds 批量删除信息 +func (r *TraceTaskHlr) DeleteByIds(ids []string) int64 { + placeholder := repo.KeyPlaceholderByQuery(len(ids)) + sql := "delete from trace_task_hlr where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(ids) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + logger.Errorf("delete err => %v", err) + return 0 + } + return results +} + +// LastID 最后一条ID +func (r *TraceTaskHlr) LastID() int64 { + // 查询数据 + querySql := "SELECT id as 'str' FROM trace_task_hlr ORDER BY id DESC LIMIT 1" + results, err := datasource.RawDB("", querySql, nil) + if err != nil { + logger.Errorf("query err %v", err) + return 0 + } + if len(results) > 0 { + return parse.Number(results[0]["str"]) + } + return 0 +} diff --git a/src/modules/trace/service/tcpdump.go b/src/modules/trace/service/tcpdump.go index 9f77fb06..a0ed1621 100644 --- a/src/modules/trace/service/tcpdump.go +++ b/src/modules/trace/service/tcpdump.go @@ -1,16 +1,248 @@ package service -// 信令抓包 服务层接口 -type ITcpdump interface { - // DumpStart 触发tcpdump开始抓包 - DumpStart(neType, neId, cmdStr string) (string, error) +import ( + "fmt" + "os" + "path/filepath" + "regexp" + "runtime" + "strings" + "sync" + "time" - // DumpStop 停止已存在抓包句柄 - DumpStop(neType, neId, taskCode string) (string, error) + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/file" + neService "be.ems/src/modules/network_element/service" +) - // DumpDownload 抓包文件网元端复制到本地输出zip文件 - DumpDownload(neType, neId, taskCode string) (string, error) - - // UPFTrace UPF标准版内部抓包 - UPFTrace(neType, neId, cmdStr string) (string, error) +// 实例化服务层 TCPdump 结构体 +var NewTCPdump = &TCPdump{ + neInfoService: neService.NewNeInfoImpl, +} + +// 信令抓包 服务层处理 +type TCPdump struct { + // 网元信息服务 + neInfoService neService.INeInfo +} + +// 抓包进程PID +var dumpPIDMap sync.Map + +// DumpStart 触发tcpdump开始抓包 +func (s *TCPdump) DumpStart(neType, neId, cmdStr string) (string, error) { + // 命令检查 + if strings.Contains(cmdStr, "w") { + return "", fmt.Errorf("command cannot contain -w") + } + + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, neId) + if neInfo.NeId != neId || neInfo.IP == "" { + return "", fmt.Errorf("app.common.noNEInfo") + } + // 网元主机的SSH客户端 + sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) + if err != nil { + return "", err + } + defer sshClient.Close() + + // 检查是否安装tcpdump + if msg, err := sshClient.RunCMD("sudo tcpdump --version"); err != nil { + // bash: tcpdump: command not found + msg = strings.TrimSpace(msg) + logger.Errorf("DumpStart err: %s => %s", msg, err.Error()) + return "", fmt.Errorf(msg) + } + + taskCode := time.Now().Format("20060102150405") + // 存放文件目录 /tmp/omc/tcpdump/udm/001/20240817104241 + neDirTemp := fmt.Sprintf("/tmp/omc/tcpdump/%s/%s/%s", strings.ToLower(neInfo.NeType), neInfo.NeId, taskCode) + sshClient.RunCMD(fmt.Sprintf("mkdir -p %s && sudo chmod 777 -R /tmp/omc", neDirTemp)) + + // 命令拼装 + logPath := fmt.Sprintf("%s/tcpdump.log", neDirTemp) + filePath := fmt.Sprintf("%s/part_%s.pcap ", neDirTemp, taskCode) + if strings.Contains(cmdStr, "-G") { + filePath = fmt.Sprintf("%s/part_%%Y%%m%%d%%H%%M%%S.pcap ", neDirTemp) + } + sendCmd := fmt.Sprintf("sudo timeout 60m sudo tcpdump -i any %s -w %s > %s 2>&1 & echo $!", cmdStr, filePath, logPath) + // sudo timeout 60m sudo tcpdump -i any -n -s 0 -v -G 60 -W 6 -w /tmp/omc/tcpdump/udm/001/20240817104241/part_%Y-%m-%d_%H:%M:%S.pcap > /tmp/omc/tcpdump/udm/001/20240817104241/tcpdump.log 2>&1 & echo $! + // sudo timeout 60m sudo tcpdump -i any -n -s 0 -v -w /tmp/omc/tcpdump/udm/001/20240817105440/part_2024-08-17_10:54:40.pcap > /tmp/omc/tcpdump/udm/001/20240817105440/tcpdump.log 2>&1 & echo $! + // + // timeout 超时60分钟后发送kill命令,1分钟后强制终止命令。tcpdump -G 文件轮转间隔时间(秒) -W 文件轮转保留最近数量 + // sudo timeout --kill-after=1m 60m sudo tcpdump -i any -n -s 0 -v -G 10 -W 7 -w /tmp/part_%Y%m%d%H%M%S.pcap > /tmp/part.log 2>&1 & echo $! + // sudo kill $(pgrep -P 722729) + outputPID, err := sshClient.RunCMD(sendCmd) + outputPID = strings.TrimSpace(outputPID) + if err != nil || strings.HasPrefix(outputPID, "stderr:") { + logger.Errorf("DumpStart err: %s => %s", outputPID, err.Error()) + return "", err + } + + // 检查进程 ps aux | grep tcpdump + // 强杀 sudo pkill tcpdump + pidKey := fmt.Sprintf("%s_%s_%s", strings.ToLower(neInfo.NeType), neInfo.NeId, taskCode) + dumpPIDMap.Store(pidKey, outputPID) + return taskCode, err +} + +// DumpStop 停止已存在抓包句柄 +func (s *TCPdump) DumpStop(neType, neId, taskCode string) (string, error) { + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, neId) + if neInfo.NeId != neId || neInfo.IP == "" { + return "", fmt.Errorf("app.common.noNEInfo") + } + // 网元主机的SSH客户端 + sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) + if err != nil { + return "", err + } + defer sshClient.Close() + + // 是否存在执行过的进程 + pidKey := fmt.Sprintf("%s_%s_%s", strings.ToLower(neInfo.NeType), neInfo.NeId, taskCode) + pid, ok := dumpPIDMap.Load(pidKey) + if !ok || pid == "" { + return "", fmt.Errorf("tcpdump is not running") + } + defer dumpPIDMap.Delete(pidKey) + + // 存放文件目录 /tmp/omc/tcpdump/udm/001/20240817104241 + neDirTemp := fmt.Sprintf("/tmp/omc/tcpdump/%s/%s/%s", strings.ToLower(neInfo.NeType), neInfo.NeId, taskCode) + // 命令拼装 + sendCmd := fmt.Sprintf("pids=$(pgrep -P %s) && [ -n \"$pids\" ] && sudo kill $pids;sudo timeout 2s cat %s/tcpdump.log", pid, neDirTemp) + // pids=$(pgrep -P 1914341) && [ -n "$pids" ] && sudo kill $pids;sudo timeout 2s cat tcpdump.log + output, err := sshClient.RunCMD(sendCmd) + if err != nil || strings.HasPrefix(output, "stderr:") { + logger.Warnf("DumpStop err: %s => %s", strings.TrimSpace(output), err.Error()) + return "", err + } + return output, nil +} + +// DumpDownload 抓包文件网元端复制到本地输出zip文件 +func (s *TCPdump) DumpDownload(neType, neId, taskCode string) (string, error) { + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, neId) + if neInfo.NeId != neId || neInfo.IP == "" { + return "", fmt.Errorf("app.common.noNEInfo") + } + // 网元主机的SSH客户端 + sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) + if err != nil { + return "", err + } + defer sshClient.Close() + // 网元主机的SSH客户端进行文件传输 + sftpClient, err := sshClient.NewClientSFTP() + if err != nil { + return "", fmt.Errorf("ne info sftp client err") + } + defer sftpClient.Close() + + neTypeLower := strings.ToLower(neInfo.NeType) + // 网管本地路径 + localDirPath := fmt.Sprintf("/tmp/omc/tcpdump/zip/%s/%s", neTypeLower, neInfo.NeId) + if runtime.GOOS == "windows" { + localDirPath = fmt.Sprintf("C:%s", localDirPath) + } + + // 网元pcap目录 /tmp/omc/tcpdump/udm/001/20240817104241 + sshClient.RunCMD("mkdir -p /tmp/omc && sudo chmod 777 -R /tmp/omc") + neDirTemp := fmt.Sprintf("/tmp/omc/tcpdump/%s/%s/%s", neTypeLower, neInfo.NeId, taskCode) + // 网元端复制到本地 + localDirFilePath := filepath.Join(localDirPath, taskCode) + if err = sftpClient.CopyDirRemoteToLocal(neDirTemp, localDirFilePath); err != nil { + return "", fmt.Errorf("copy tcpdump file err") + } + + // 压缩zip文件名 + zipFileName := fmt.Sprintf("%s-%s-pcap-%s.zip", neTypeLower, neInfo.NeId, taskCode) + zipFilePath := filepath.Join(localDirPath, zipFileName) + if err := file.CompressZipByDir(zipFilePath, localDirFilePath); err != nil { + return "", fmt.Errorf("compress zip err") + } + + _ = os.RemoveAll(localDirFilePath) // 删除本地临时目录 + return zipFilePath, nil +} + +// UPFTrace UPF标准版内部抓包 +func (s *TCPdump) UPFTrace(neType, neId, cmdStr string) (string, error) { + // 命令检查 + if strings.Contains(cmdStr, "file") { + return "", fmt.Errorf("command cannot contain file") + } + + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, neId) + if neInfo.NeId != neId || neInfo.IP == "" { + return "", fmt.Errorf("app.common.noNEInfo") + } + // 网元主机的SSH客户端 + sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) + if err != nil { + return "", err + } + defer sshClient.Close() + // 网元主机的Telnet客户端 + telnetClient, err := s.neInfoService.NeRunTelnetClient("UPF", neInfo.NeId, 2) + if err != nil { + return "", err + } + defer telnetClient.Close() + + // 命令拼装 + fileName := fmt.Sprintf("%s_%s_part_%s.pcap ", neInfo.NeType, neInfo.NeId, time.Now().Format("20060102150405")) + pcapCmd := fmt.Sprintf("%s\r\n", cmdStr) + // 以off结尾是停止抓包,不需要写文件 + if !strings.Contains(cmdStr, "off") { + // pcap trace rx tx max 100000 intfc any file UPF_001_part_20240817164516.pcap + pcapCmd = fmt.Sprintf("%s file %s\r\n", cmdStr, fileName) + } + // 发送命令 UPF内部默认输出路径/tmp只能写文件名 + // pcap trace rx tx max 100000 intfc any file upf_test.pcap + // pcap trace rx tx off + output, err := telnetClient.RunCMD(pcapCmd) + if err != nil { + logger.Warnf("DumpUPF err: %s => %s", output, err.Error()) + return "", err + } + + // 结果截取 + arr := strings.Split(output, "\r\n") + if len(arr) == 2 { + return "", fmt.Errorf("trace pacp run failed") + } + if len(arr) > 3 { + resMsg := arr[2] + // pcap trace: unknown input `f file UPF_001_part_2024-08-19...' + // pcap trace: dispatch trace already enabled... + // pcap trace: dispatch trace already disabled... + // pcap trace: No packets captured... + // Write 100000 packets to /tmp/UPF_001_part_20240817164516.pcap, and stop capture... + if strings.Contains(resMsg, "unknown input") { + return "", fmt.Errorf("trace pacp unknown input") + } + if strings.Contains(resMsg, "already enabled") { + return "", fmt.Errorf("trace pacp already running") + } + if strings.Contains(resMsg, "already disabled") { + return "", fmt.Errorf("trace pacp not running") + } + if strings.Contains(resMsg, "No packets") { + return "", fmt.Errorf("trace pacp not packets") + } + if strings.Contains(resMsg, "packets to") { + matches := regexp.MustCompile(`(/tmp/[^,\s]+)`).FindStringSubmatch(resMsg) + if len(matches) == 0 { + return "", fmt.Errorf("file path not found") + } + return matches[0], nil + } + } + return "trace pacp running", nil } diff --git a/src/modules/trace/service/tcpdump.impl.go b/src/modules/trace/service/tcpdump.impl.go deleted file mode 100644 index 72194832..00000000 --- a/src/modules/trace/service/tcpdump.impl.go +++ /dev/null @@ -1,248 +0,0 @@ -package service - -import ( - "fmt" - "os" - "path/filepath" - "regexp" - "runtime" - "strings" - "sync" - "time" - - "be.ems/src/framework/logger" - "be.ems/src/framework/utils/file" - neService "be.ems/src/modules/network_element/service" -) - -// 实例化服务层 TcpdumpImpl 结构体 -var NewTcpdumpImpl = &TcpdumpImpl{ - neInfoService: neService.NewNeInfoImpl, -} - -// 信令抓包 服务层处理 -type TcpdumpImpl struct { - // 网元信息服务 - neInfoService neService.INeInfo -} - -// 抓包进程PID -var dumpPIDMap sync.Map - -// DumpStart 触发tcpdump开始抓包 -func (s *TcpdumpImpl) DumpStart(neType, neId, cmdStr string) (string, error) { - // 命令检查 - if strings.Contains(cmdStr, "w") { - return "", fmt.Errorf("command cannot contain -w") - } - - // 查询网元获取IP - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, neId) - if neInfo.NeId != neId || neInfo.IP == "" { - return "", fmt.Errorf("app.common.noNEInfo") - } - // 网元主机的SSH客户端 - sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) - if err != nil { - return "", err - } - defer sshClient.Close() - - // 检查是否安装tcpdump - if msg, err := sshClient.RunCMD("sudo tcpdump --version"); err != nil { - // bash: tcpdump: command not found - msg = strings.TrimSpace(msg) - logger.Errorf("DumpStart err: %s => %s", msg, err.Error()) - return "", fmt.Errorf(msg) - } - - taskCode := time.Now().Format("20060102150405") - // 存放文件目录 /tmp/omc/tcpdump/udm/001/20240817104241 - neDirTemp := fmt.Sprintf("/tmp/omc/tcpdump/%s/%s/%s", strings.ToLower(neInfo.NeType), neInfo.NeId, taskCode) - sshClient.RunCMD(fmt.Sprintf("mkdir -p %s && sudo chmod 777 -R /tmp/omc", neDirTemp)) - - // 命令拼装 - logPath := fmt.Sprintf("%s/tcpdump.log", neDirTemp) - filePath := fmt.Sprintf("%s/part_%s.pcap ", neDirTemp, taskCode) - if strings.Contains(cmdStr, "-G") { - filePath = fmt.Sprintf("%s/part_%%Y%%m%%d%%H%%M%%S.pcap ", neDirTemp) - } - sendCmd := fmt.Sprintf("sudo timeout 60m sudo tcpdump -i any %s -w %s > %s 2>&1 & echo $!", cmdStr, filePath, logPath) - // sudo timeout 60m sudo tcpdump -i any -n -s 0 -v -G 60 -W 6 -w /tmp/omc/tcpdump/udm/001/20240817104241/part_%Y-%m-%d_%H:%M:%S.pcap > /tmp/omc/tcpdump/udm/001/20240817104241/tcpdump.log 2>&1 & echo $! - // sudo timeout 60m sudo tcpdump -i any -n -s 0 -v -w /tmp/omc/tcpdump/udm/001/20240817105440/part_2024-08-17_10:54:40.pcap > /tmp/omc/tcpdump/udm/001/20240817105440/tcpdump.log 2>&1 & echo $! - // - // timeout 超时60分钟后发送kill命令,1分钟后强制终止命令。tcpdump -G 文件轮转间隔时间(秒) -W 文件轮转保留最近数量 - // sudo timeout --kill-after=1m 60m sudo tcpdump -i any -n -s 0 -v -G 10 -W 7 -w /tmp/part_%Y%m%d%H%M%S.pcap > /tmp/part.log 2>&1 & echo $! - // sudo kill $(pgrep -P 722729) - outputPID, err := sshClient.RunCMD(sendCmd) - outputPID = strings.TrimSpace(outputPID) - if err != nil || strings.HasPrefix(outputPID, "stderr:") { - logger.Errorf("DumpStart err: %s => %s", outputPID, err.Error()) - return "", err - } - - // 检查进程 ps aux | grep tcpdump - // 强杀 sudo pkill tcpdump - pidKey := fmt.Sprintf("%s_%s_%s", strings.ToLower(neInfo.NeType), neInfo.NeId, taskCode) - dumpPIDMap.Store(pidKey, outputPID) - return taskCode, err -} - -// DumpStop 停止已存在抓包句柄 -func (s *TcpdumpImpl) DumpStop(neType, neId, taskCode string) (string, error) { - // 查询网元获取IP - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, neId) - if neInfo.NeId != neId || neInfo.IP == "" { - return "", fmt.Errorf("app.common.noNEInfo") - } - // 网元主机的SSH客户端 - sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) - if err != nil { - return "", err - } - defer sshClient.Close() - - // 是否存在执行过的进程 - pidKey := fmt.Sprintf("%s_%s_%s", strings.ToLower(neInfo.NeType), neInfo.NeId, taskCode) - pid, ok := dumpPIDMap.Load(pidKey) - if !ok || pid == "" { - return "", fmt.Errorf("tcpdump is not running") - } - defer dumpPIDMap.Delete(pidKey) - - // 存放文件目录 /tmp/omc/tcpdump/udm/001/20240817104241 - neDirTemp := fmt.Sprintf("/tmp/omc/tcpdump/%s/%s/%s", strings.ToLower(neInfo.NeType), neInfo.NeId, taskCode) - // 命令拼装 - sendCmd := fmt.Sprintf("pids=$(pgrep -P %s) && [ -n \"$pids\" ] && sudo kill $pids;sudo timeout 2s cat %s/tcpdump.log", pid, neDirTemp) - // pids=$(pgrep -P 1914341) && [ -n "$pids" ] && sudo kill $pids;sudo timeout 2s cat tcpdump.log - output, err := sshClient.RunCMD(sendCmd) - if err != nil || strings.HasPrefix(output, "stderr:") { - logger.Warnf("DumpStop err: %s => %s", strings.TrimSpace(output), err.Error()) - return "", err - } - return output, nil -} - -// DumpDownload 抓包文件网元端复制到本地输出zip文件 -func (s *TcpdumpImpl) DumpDownload(neType, neId, taskCode string) (string, error) { - // 查询网元获取IP - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, neId) - if neInfo.NeId != neId || neInfo.IP == "" { - return "", fmt.Errorf("app.common.noNEInfo") - } - // 网元主机的SSH客户端 - sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) - if err != nil { - return "", err - } - defer sshClient.Close() - // 网元主机的SSH客户端进行文件传输 - sftpClient, err := sshClient.NewClientSFTP() - if err != nil { - return "", fmt.Errorf("ne info sftp client err") - } - defer sftpClient.Close() - - neTypeLower := strings.ToLower(neInfo.NeType) - // 网管本地路径 - localDirPath := fmt.Sprintf("/tmp/omc/tcpdump/%s/%s", neTypeLower, neInfo.NeId) - if runtime.GOOS == "windows" { - localDirPath = fmt.Sprintf("C:%s", localDirPath) - } - - // 网元pcap目录 /tmp/omc/tcpdump/udm/001/20240817104241 - sshClient.RunCMD("mkdir -p /tmp/omc && sudo chmod 777 -R /tmp/omc") - neDirTemp := fmt.Sprintf("/tmp/omc/tcpdump/%s/%s/%s", neTypeLower, neInfo.NeId, taskCode) - // 网元端复制到本地 - localDirFilePath := filepath.Join(localDirPath, taskCode) - if err = sftpClient.CopyDirRemoteToLocal(neDirTemp, localDirFilePath); err != nil { - return "", fmt.Errorf("copy tcpdump file err") - } - - // 压缩zip文件名 - zipFileName := fmt.Sprintf("%s-%s-pcap-%s.zip", neTypeLower, neInfo.NeId, taskCode) - zipFilePath := filepath.Join(localDirPath, zipFileName) - if err := file.CompressZipByDir(zipFilePath, localDirFilePath); err != nil { - return "", fmt.Errorf("compress zip err") - } - - _ = os.RemoveAll(localDirFilePath) // 删除本地临时目录 - return zipFilePath, nil -} - -// UPFTrace UPF标准版内部抓包 -func (s *TcpdumpImpl) UPFTrace(neType, neId, cmdStr string) (string, error) { - // 命令检查 - if strings.Contains(cmdStr, "file") { - return "", fmt.Errorf("command cannot contain file") - } - - // 查询网元获取IP - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, neId) - if neInfo.NeId != neId || neInfo.IP == "" { - return "", fmt.Errorf("app.common.noNEInfo") - } - // 网元主机的SSH客户端 - sshClient, err := s.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) - if err != nil { - return "", err - } - defer sshClient.Close() - // 网元主机的Telnet客户端 - telnetClient, err := s.neInfoService.NeRunTelnetClient("UPF", neInfo.NeId, 2) - if err != nil { - return "", err - } - defer telnetClient.Close() - - // 命令拼装 - fileName := fmt.Sprintf("%s_%s_part_%s.pcap ", neInfo.NeType, neInfo.NeId, time.Now().Format("20060102150405")) - pcapCmd := fmt.Sprintf("%s\r\n", cmdStr) - // 以off结尾是停止抓包,不需要写文件 - if !strings.Contains(cmdStr, "off") { - // pcap trace rx tx max 100000 intfc any file UPF_001_part_20240817164516.pcap - pcapCmd = fmt.Sprintf("%s file %s\r\n", cmdStr, fileName) - } - // 发送命令 UPF内部默认输出路径/tmp只能写文件名 - // pcap trace rx tx max 100000 intfc any file upf_test.pcap - // pcap trace rx tx off - output, err := telnetClient.RunCMD(pcapCmd) - if err != nil { - logger.Warnf("DumpUPF err: %s => %s", output, err.Error()) - return "", err - } - - // 结果截取 - arr := strings.Split(output, "\r\n") - if len(arr) == 2 { - return "", fmt.Errorf("trace pacp run failed") - } - if len(arr) > 3 { - resMsg := arr[2] - // pcap trace: unknown input `f file UPF_001_part_2024-08-19...' - // pcap trace: dispatch trace already enabled... - // pcap trace: dispatch trace already disabled... - // pcap trace: No packets captured... - // Write 100000 packets to /tmp/UPF_001_part_20240817164516.pcap, and stop capture... - if strings.Contains(resMsg, "unknown input") { - return "", fmt.Errorf("trace pacp unknown input") - } - if strings.Contains(resMsg, "already enabled") { - return "", fmt.Errorf("trace pacp already running") - } - if strings.Contains(resMsg, "already disabled") { - return "", fmt.Errorf("trace pacp not running") - } - if strings.Contains(resMsg, "No packets") { - return "", fmt.Errorf("trace pacp not packets") - } - if strings.Contains(resMsg, "packets to") { - matches := regexp.MustCompile(`(/tmp/[^,\s]+)`).FindStringSubmatch(resMsg) - if len(matches) == 0 { - return "", fmt.Errorf("file path not found") - } - return matches[0], nil - } - } - return "trace pacp running", nil -} diff --git a/src/modules/trace/service/trace_data.go b/src/modules/trace/service/trace_data.go new file mode 100644 index 00000000..4a9ee7c6 --- /dev/null +++ b/src/modules/trace/service/trace_data.go @@ -0,0 +1,54 @@ +package service + +import ( + "fmt" + + "be.ems/src/modules/trace/model" + "be.ems/src/modules/trace/repository" +) + +// 实例化数据层 TraceData 结构体 +var NewTraceData = &TraceData{ + traceDataRepository: repository.NewTraceData, +} + +// TraceData 跟踪_数据 服务层处理 +type TraceData struct { + // 跟踪_数据信息 + traceDataRepository *repository.TraceData +} + +// SelectPage 根据条件分页查询 +func (r *TraceData) SelectPage(query map[string]any) map[string]any { + return r.traceDataRepository.SelectPage(query) +} + +// SelectById 通过ID查询 +func (r *TraceData) SelectById(id string) model.TraceData { + tasks := r.traceDataRepository.SelectByIds([]string{id}) + if len(tasks) > 0 { + return tasks[0] + } + return model.TraceData{} +} + +// Insert 新增信息 +func (r *TraceData) Insert(task model.TraceData) string { + return r.traceDataRepository.Insert(task) +} + +// DeleteByIds 批量删除信息 +func (r *TraceData) DeleteByIds(ids []string) (int64, error) { + // 检查是否存在 + rows := r.traceDataRepository.SelectByIds(ids) + if len(rows) <= 0 { + return 0, fmt.Errorf("not data") + } + + if len(rows) == len(ids) { + rows := r.traceDataRepository.DeleteByIds(ids) + return rows, nil + } + // 删除信息失败! + return 0, fmt.Errorf("delete fail") +} diff --git a/src/modules/trace/service/trace_task.go b/src/modules/trace/service/trace_task.go new file mode 100644 index 00000000..e9891b28 --- /dev/null +++ b/src/modules/trace/service/trace_task.go @@ -0,0 +1,294 @@ +package service + +import ( + "encoding/json" + "fmt" + "strings" + + "be.ems/src/framework/config" + "be.ems/src/framework/logger" + "be.ems/src/framework/socket" + "be.ems/src/framework/utils/date" + "be.ems/src/framework/utils/parse" + neFetchlink "be.ems/src/modules/network_element/fetch_link" + neService "be.ems/src/modules/network_element/service" + "be.ems/src/modules/trace/model" + "be.ems/src/modules/trace/repository" +) + +// 实例化数据层 TraceTask 结构体 +var NewTraceTask = &TraceTask{ + udpService: socket.SocketUDP{}, + traceTaskRepository: repository.NewTraceTask, + traceDataRepository: repository.NewTraceData, +} + +// TraceTask 跟踪任务 服务层处理 +type TraceTask struct { + // UDP服务对象 + udpService socket.SocketUDP + // 跟踪_任务数据信息 + traceTaskRepository *repository.TraceTask + // 跟踪_数据信息 + traceDataRepository *repository.TraceData +} + +// CreateUDP 创建UDP数据通道 +func (r *TraceTask) CreateUDP() error { + // 跟踪配置是否开启 + if v := config.Get("trace.enabled"); v != nil { + if !v.(bool) { + return nil + } + } + host := "127.0.0.1" + if v := config.Get("trace.host"); v != nil { + host = v.(string) + } + var port int64 = 33033 + if v := config.Get("trace.port"); v != nil { + port = parse.Number(v) + } + + // 初始化UDP服务 + r.udpService = socket.SocketUDP{Addr: host, Port: port} + if _, err := r.udpService.New(); err != nil { + return err + } + + // 接收处理UDP数据 + go r.udpService.Resolve(2048, func(data []byte, n int) { + logger.Infof("socket UDP: %s", string(data)) + mData, err := UDPDataHandler(data, n) + if err != nil { + logger.Errorf("udp resolve data fail: %s", err.Error()) + return + } + // 插入数据库做记录 + r.traceDataRepository.Insert(model.TraceData{ + TaskId: parse.Number(mData["taskId"]), + IMSI: mData["imsi"].(string), + SrcAddr: mData["srcAddr"].(string), + DstAddr: mData["dstAddr"].(string), + IfType: parse.Number(mData["ifType"]), + MsgType: parse.Number(mData["msgType"]), + MsgDirect: parse.Number(mData["msgDirect"]), + Length: parse.Number(mData["dataLen"]), + RawMsg: mData["dataInfo"].(string), + Timestamp: parse.Number(mData["timestamp"]), + DecMsg: mData["decMsg"].(string), + }) + + // 推送文件 + if v, ok := mData["pcapFile"]; ok && v != "" { + logger.Infof("pcapFile: %s", v) + } + }) + + // ============ 测试接收网元UDP发过来的数据 + // 初始化TCP服务 后续调整TODO + tcpService := socket.SocketTCP{Addr: host, Port: port + 1} + if _, err := tcpService.New(); err != nil { + return err + } + // 接收处理TCP数据 + go tcpService.Resolve(1024, func(data []byte, n int) { + logger.Infof("socket TCP: %s", string(data)) + mData, err := UDPDataHandler(data, n) + if err != nil { + logger.Errorf("tcp resolve data fail: %s", err.Error()) + return + } + // 插入数据库做记录 + r.traceDataRepository.Insert(model.TraceData{ + TaskId: parse.Number(mData["taskId"]), + IMSI: mData["imsi"].(string), + SrcAddr: mData["srcAddr"].(string), + DstAddr: mData["dstAddr"].(string), + IfType: parse.Number(mData["ifType"]), + MsgType: parse.Number(mData["msgType"]), + MsgDirect: parse.Number(mData["msgDirect"]), + Length: parse.Number(mData["dataLen"]), + RawMsg: mData["dataInfo"].(string), + Timestamp: parse.Number(mData["timestamp"]), + DecMsg: mData["decMsg"].(string), + }) + + // 推送文件 + if v, ok := mData["pcapFile"]; ok && v != "" { + logger.Infof("pcapFile: %s", v) + } + }) + return nil +} + +// CloseUDP 关闭UDP数据通道 +func (r *TraceTask) CloseUDP() { + r.udpService.Close() +} + +// SelectPage 根据条件分页查询 +func (r *TraceTask) SelectPage(query map[string]any) map[string]any { + return r.traceTaskRepository.SelectPage(query) +} + +// SelectById 通过ID查询 +func (r *TraceTask) SelectById(id string) model.TraceTask { + tasks := r.traceTaskRepository.SelectByIds([]string{id}) + if len(tasks) > 0 { + return tasks[0] + } + return model.TraceTask{} +} + +// Insert 新增信息 +func (r *TraceTask) Insert(task model.TraceTask) error { + // 跟踪配置是否开启 + if v := config.Get("trace.enabled"); v != nil { + if !v.(bool) { + return fmt.Errorf("tracking is not enabled") + } + } + host := "127.0.0.1" + if v := config.Get("trace.host"); v != nil { + host = v.(string) + } + var port int64 = 33033 + if v := config.Get("trace.port"); v != nil { + port = parse.Number(v) + } + task.NotifyUrl = fmt.Sprintf("udp:%s:%d", host, port) + + // 查询网元获取IP + neInfo := neService.NewNeInfoImpl.SelectNeInfoByNeTypeAndNeID(task.NeType, task.NeId) + if neInfo.NeId != task.NeId || neInfo.IP == "" { + return fmt.Errorf("app.common.noNEInfo") + } + traceId := r.traceTaskRepository.LastID() + 1 // 生成任务ID < 65535 + task.TraceId = fmt.Sprint(traceId) + + // 发送任务给网元 + data := map[string]any{ + "neType": neInfo.NeType, + "neId": neInfo.NeId, + "notifyUrl": task.NotifyUrl, + "id": traceId, + "startTime": date.ParseDateToStr(task.StartTime, date.YYYY_MM_DD_HH_MM_SS), + "endTime": date.ParseDateToStr(task.EndTime, date.YYYY_MM_DD_HH_MM_SS), + } + switch task.TraceType { + case "1": // Interface + data["traceType"] = "Interface" + data["interfaces"] = strings.Split(task.Interfaces, ",") + case "2": // Device + data["traceType"] = "Device" + data["ueIp"] = task.UeIp + data["srcIp"] = task.SrcIp + data["dstIp"] = task.DstIp + data["signalPort"] = task.SignalPort + task.UeIp = neInfo.IP + case "3": // UE + data["traceType"] = "UE" + data["imsi"] = task.IMSI + data["msisdn"] = task.MSISDN + default: + return fmt.Errorf("trace type is not disabled") + } + msg, err := neFetchlink.NeTraceAdd(neInfo, data) + if err != nil { + return err + } + s, _ := json.Marshal(msg) + task.FetchMsg = string(s) + + // 插入数据库 + r.traceTaskRepository.Insert(task) + return nil +} + +// Update 修改信息 +func (r *TraceTask) Update(task model.TraceTask) error { + // 跟踪配置是否开启 + if v := config.Get("trace.enabled"); v != nil { + if !v.(bool) { + return fmt.Errorf("tracking is not enabled") + } + } + host := "127.0.0.1" + if v := config.Get("trace.host"); v != nil { + host = v.(string) + } + var port int64 = 33033 + if v := config.Get("trace.port"); v != nil { + port = parse.Number(v) + } + task.NotifyUrl = fmt.Sprintf("udp:%s:%d", host, port) + + // 查询网元获取IP + neInfo := neService.NewNeInfoImpl.SelectNeInfoByNeTypeAndNeID(task.NeType, task.NeId) + if neInfo.NeId != task.NeId || neInfo.IP == "" { + return fmt.Errorf("app.common.noNEInfo") + } + + // 查询网元任务信息 + if msg, err := neFetchlink.NeTraceInfo(neInfo, task.TraceId); err == nil { + s, _ := json.Marshal(msg) + task.FetchMsg = string(s) + // 修改任务信息 + data := map[string]any{ + "neType": neInfo.NeType, + "neId": neInfo.NeId, + "notifyUrl": task.NotifyUrl, + "id": parse.Number(task.TraceId), + "startTime": date.ParseDateToStr(task.StartTime, date.YYYY_MM_DD_HH_MM_SS), + "endTime": date.ParseDateToStr(task.EndTime, date.YYYY_MM_DD_HH_MM_SS), + } + switch task.TraceType { + case "1": // Interface + data["traceType"] = "Interface" + data["interfaces"] = strings.Split(task.Interfaces, ",") + case "2": // Device + task.UeIp = neInfo.IP + data["traceType"] = "Device" + data["ueIp"] = task.UeIp + data["srcIp"] = task.SrcIp + data["dstIp"] = task.DstIp + data["signalPort"] = task.SignalPort + case "3": // UE + data["traceType"] = "UE" + data["imsi"] = task.IMSI + data["msisdn"] = task.MSISDN + default: + return fmt.Errorf("trace type is not disabled") + } + neFetchlink.NeTraceEdit(neInfo, data) + } + + // 更新数据库 + r.traceTaskRepository.Update(task) + return nil +} + +// DeleteByIds 批量删除信息 +func (r *TraceTask) DeleteByIds(ids []string) (int64, error) { + // 检查是否存在 + rows := r.traceTaskRepository.SelectByIds(ids) + if len(rows) <= 0 { + return 0, fmt.Errorf("not data") + } + + if len(rows) == len(ids) { + // 停止任务 + for _, v := range rows { + neInfo := neService.NewNeInfoImpl.SelectNeInfoByNeTypeAndNeID(v.NeType, v.NeId) + if neInfo.NeId != v.NeId || neInfo.IP == "" { + continue + } + neFetchlink.NeTraceDelete(neInfo, v.TraceId) + } + num := r.traceTaskRepository.DeleteByIds(ids) + return num, nil + } + // 删除信息失败! + return 0, fmt.Errorf("delete fail") +} diff --git a/src/modules/trace/service/trace_task_hlr.go b/src/modules/trace/service/trace_task_hlr.go new file mode 100644 index 00000000..2cad7167 --- /dev/null +++ b/src/modules/trace/service/trace_task_hlr.go @@ -0,0 +1,208 @@ +package service + +import ( + "encoding/json" + "fmt" + "path/filepath" + + "be.ems/src/framework/utils/date" + "be.ems/src/framework/utils/ssh" + neFetchlink "be.ems/src/modules/network_element/fetch_link" + neModel "be.ems/src/modules/network_element/model" + neService "be.ems/src/modules/network_element/service" + "be.ems/src/modules/trace/model" + "be.ems/src/modules/trace/repository" +) + +// 实例化数据层 TraceTaskHlr 结构体 +var NewTraceTaskHlr = &TraceTaskHlr{ + traceTaskHlrRepository: repository.NewTraceTaskHlr, + neInfoService: neService.NewNeInfoImpl, +} + +// TraceTaskHlr 跟踪_任务给HRL网元 服务层处理 +type TraceTaskHlr struct { + // 跟踪_任务给HRL网元数据信息 + traceTaskHlrRepository *repository.TraceTaskHlr + // 网元信息服务 + neInfoService neService.INeInfo +} + +// SelectPage 根据条件分页查询 +func (r *TraceTaskHlr) SelectPage(querys model.TraceTaskHlrQuery) map[string]any { + return r.traceTaskHlrRepository.SelectPage(querys) +} + +// SelectById 通过ID查询 +func (r *TraceTaskHlr) SelectById(id string) model.TraceTaskHlr { + tasks := r.traceTaskHlrRepository.SelectByIds([]string{id}) + if len(tasks) > 0 { + return tasks[0] + } + return model.TraceTaskHlr{} +} + +// Insert 新增信息 +func (r *TraceTaskHlr) Insert(task model.TraceTaskHlr) string { + return r.traceTaskHlrRepository.Insert(task) +} + +// Update 修改信息 +func (r *TraceTaskHlr) Update(task model.TraceTaskHlr) int64 { + return r.traceTaskHlrRepository.Update(task) +} + +// DeleteByIds 批量删除信息 +func (r *TraceTaskHlr) DeleteByIds(ids []string) (int64, error) { + // 检查是否存在 + rows := r.traceTaskHlrRepository.SelectByIds(ids) + if len(rows) <= 0 { + return 0, fmt.Errorf("not data") + } + + if len(rows) == len(ids) { + // 停止任务 + neInfos := r.neInfoService.SelectList(neModel.NeInfo{NeType: "UDM"}, false, false) + for _, r := range rows { + if r.Status == "0" { + continue + } + for _, v := range neInfos { + neFetchlink.HLRTraceStop(v, map[string]any{ + "traceIDArray": []string{r.TraceId}, + }) + } + } + num := r.traceTaskHlrRepository.DeleteByIds(ids) + return num, nil + } + // 删除信息失败! + return 0, fmt.Errorf("delete fail") +} + +// Start 创建任务 +func (r *TraceTaskHlr) Start(task model.TraceTaskHlr) (string, error) { + hlrList := []map[string]any{} + traceId := r.traceTaskHlrRepository.LastID() + 1 // 生成任务ID < 65535 + data := map[string]any{ + "traceID": traceId, + "imsi": task.IMSI, + "msisdn": task.MSISDN, + } + if task.StartTime > task.EndTime { + return "", fmt.Errorf("startTime must less than endTime") + } + if task.StartTime > 0 { + data["startTime"] = date.ParseDateToStr(task.StartTime, date.YYYY_MM_DDTHH_MM_SSZ) + } + if task.StartTime > 0 { + data["endTime"] = date.ParseDateToStr(task.EndTime, date.YYYY_MM_DDTHH_MM_SSZ) + } + + // 发送创建任务 + neInfos := r.neInfoService.SelectList(neModel.NeInfo{NeType: "UDM"}, false, false) + for _, neInfo := range neInfos { + hlrItem := map[string]any{ + "neType": neInfo.NeType, + "neId": neInfo.NeId, + "msg": "", + } + msg, err := neFetchlink.HLRTraceStart(neInfo, data) + if err != nil { + hlrItem["err"] = err.Error() + } else { + hlrItem["err"] = msg + } + hlrList = append(hlrList, hlrItem) + } + + msg, _ := json.Marshal(hlrList) + task.Msg = string(msg) + task.Status = "1" + task.TraceId = fmt.Sprint(traceId) + id := r.traceTaskHlrRepository.Insert(task) + if id == "" { + return "", fmt.Errorf("start task fail") + } + return id, nil +} + +// Stop 停止任务 +func (r *TraceTaskHlr) Stop(task model.TraceTaskHlr) error { + hlrList := []map[string]any{} + // 发送停止任务 + neInfos := r.neInfoService.SelectList(neModel.NeInfo{NeType: "UDM"}, false, false) + for _, neInfo := range neInfos { + hlrItem := map[string]any{ + "neType": neInfo.NeType, + "neId": neInfo.NeId, + "msg": "", + } + msg, err := neFetchlink.HLRTraceStop(neInfo, map[string]any{ + "traceIDArray": []string{task.TraceId}, + }) + if err != nil { + hlrItem["err"] = err.Error() + } else { + hlrItem["err"] = msg + } + hlrList = append(hlrList, hlrItem) + } + + msg, _ := json.Marshal(hlrList) + task.Msg = string(msg) + task.Status = "0" + rows := r.traceTaskHlrRepository.Update(task) + if rows <= 0 { + return fmt.Errorf("stop task fail") + } + return nil +} + +// File 任务文件 +func (r *TraceTaskHlr) File(traceId, dirPath string) ([]map[string]any, error) { + hlrList := []map[string]any{} + // 查询所有匹配的网元类型 + neInfos := r.neInfoService.SelectList(neModel.NeInfo{NeType: "UDM"}, false, false) + if len(neInfos) == 0 { + return nil, fmt.Errorf("not found network element") + } + + // 遍历多个网元主机获取文件 + for _, neInfo := range neInfos { + hlrItem := map[string]any{ + "neType": neInfo.NeType, + "neId": neInfo.NeId, + "neName": neInfo.NeName, + "err": "", + } + + // 网元主机的SSH客户端 + sshClient, err := r.neInfoService.NeRunSSHClient(neInfo.NeType, neInfo.NeId) + if err != nil { + hlrItem["err"] = "ssh link fail" + hlrList = append(hlrList, hlrItem) + continue + } + defer sshClient.Close() + + // 获取文件列表 + fileName := fmt.Sprintf("%s_%s", neInfo.NeName, traceId) + _, rows, err := ssh.FileList(sshClient, filepath.ToSlash(dirPath), fileName) + if err != nil { + hlrItem["err"] = "file not found" + hlrList = append(hlrList, hlrItem) + continue + } + + // 遍历组装 + for _, v := range rows { + if v.FileType == "file" { + hlrItem["fileName"] = v.FileName + hlrItem["filePath"] = filepath.ToSlash(filepath.Join(dirPath, v.FileName)) + hlrList = append(hlrList, hlrItem) + } + } + } + return hlrList, nil +} diff --git a/src/modules/trace/service/trace_task_udp_data.go b/src/modules/trace/service/trace_task_udp_data.go new file mode 100644 index 00000000..057ddf41 --- /dev/null +++ b/src/modules/trace/service/trace_task_udp_data.go @@ -0,0 +1,330 @@ +package service + +import ( + "encoding/base64" + "encoding/binary" + "fmt" + "os" + "runtime" + "strings" + "time" + + "golang.org/x/net/http/httpguts" + "golang.org/x/net/http2/hpack" +) + +const ( + GTPU_V1_VERSION = 1 << 5 + GTPU_VER_MASK = 7 << 5 + GTPU_PT_GTP = 1 << 4 + GTPU_HEADER_LEN = 12 + GTPU_E_S_PB_BIT = 7 + GTPU_E_BI = 1 << 2 +) + +const ( + GTPU_HEADER_VERSION_INDEX = 0 + GTPU_HEADER_MSG_TYPE_INDEX = 1 + GTPU_HEADER_LENGTH_INDEX = 2 + GTPU_HEADER_TEID_INDEX = 4 +) + +type ExtHeader struct { + TaskId uint32 + IMSI string + IfType int + MsgType int + MsgDirect int // 0-recv,1-send + TimeStamp int64 + SrcIP string + DstIP string + SrcPort uint16 + DstPort uint16 + Proto int // Protocol + PPI int // only for SCTP + DataLen uint16 + DataInfo []byte +} + +// parseUDPData 解析UDP数据 +func parseUDPData(rvMsg []byte, rvLen int) (ExtHeader, error) { + var extHdr ExtHeader + // var tr dborm.TraceData + var off int + msg := rvMsg + + verFlags := msg[GTPU_HEADER_VERSION_INDEX] + + gtpuHdrLen := GTPU_HEADER_LEN + + localTeid := binary.BigEndian.Uint32(msg[GTPU_HEADER_TEID_INDEX:]) + + extHdr.TaskId = localTeid + + if (verFlags & GTPU_E_S_PB_BIT) != 0 { + if (verFlags & GTPU_E_BI) != 0 { + extTypeIndex := GTPU_HEADER_LEN - 1 + + extType := msg[extTypeIndex] + + if extType == 0xFE { + extHdr.IMSI = string(msg[extTypeIndex+2 : extTypeIndex+17]) + extHdr.IfType = int(msg[extTypeIndex+17]) + extHdr.MsgType = int(msg[extTypeIndex+18]) + extHdr.MsgDirect = int(msg[extTypeIndex+19]) + + extHdr.TimeStamp = time.Now().UTC().UnixMilli() + // extHdr.TimeStamp = int64(binary.BigEndian.Uint64(msg[extTypeIndex+19:])) + // fmt.Printf("ext info %v %s %d %d %d \n", msg[(extTypeIndex+2):(extTypeIndex+20)], extHdr.IMSI, extHdr.IfType, extHdr.MsgType, extHdr.MsgDirect) + // set offset of IP Packet + off = 40 + 4 + //src ip: msg+40+12 + extHdr.SrcIP = fmt.Sprintf("%d.%d.%d.%d", msg[off+12], msg[off+13], msg[off+14], msg[off+15]) + //dst ip: msg+40+12+4 + extHdr.DstIP = fmt.Sprintf("%d.%d.%d.%d", msg[off+16], msg[off+17], msg[off+18], msg[off+19]) + extHdr.SrcPort = uint16(binary.BigEndian.Uint16(msg[off+20:])) + extHdr.DstPort = uint16(binary.BigEndian.Uint16(msg[off+22:])) + // fmt.Printf("info %s:%d %s:%d \n", extHdr.SrcIP, extHdr.SrcPort, extHdr.DstIP, extHdr.DstPort) + // ip header start msg+40 + extHdr.DataLen = uint16(rvLen - off) + extHdr.DataInfo = make([]byte, int(rvLen-off)) + copy(extHdr.DataInfo, []byte(msg[off:])) + + // 132 SCTP + // 6 TCP + // 17 UDP + extHdr.Proto = int(msg[off+9]) + if extHdr.Proto == 132 { + extHdr.PPI = int(msg[off+47]) + extHdr.DataLen = uint16(binary.BigEndian.Uint16(msg[(off+34):]) - 16) + // fmt.Printf("dat len %d %d \n", extHdr.DataLen, extHdr.PPI) + } + } + + for extType != 0 && extTypeIndex < rvLen { + extLen := msg[extTypeIndex+1] << 2 + if extLen == 0 { + return extHdr, fmt.Errorf("error, extLen is zero") + } + + gtpuHdrLen += int(extLen) + extTypeIndex += int(extLen) + extType = msg[extTypeIndex] + } + } + } else { + gtpuHdrLen -= 4 + } + return extHdr, nil +} + +// UDPDataHandler UDP数据处理 +func UDPDataHandler(data []byte, n int) (map[string]any, error) { + extHdr, err := parseUDPData(data, n) + if err != nil { + return nil, err + } + if extHdr.TaskId == 0 || extHdr.DataLen < 1 { + return nil, fmt.Errorf("data error") + } + + m := map[string]any{ + "taskId": extHdr.TaskId, + "imsi": extHdr.IMSI, + "ifType": extHdr.IfType, + "srcAddr": fmt.Sprintf("%s:%d", extHdr.SrcIP, extHdr.SrcPort), + "dstAddr": fmt.Sprintf("%s:%d", extHdr.DstIP, extHdr.DstPort), + "msgType": extHdr.MsgType, + "msgDirect": extHdr.MsgDirect, + "timestamp": extHdr.TimeStamp, + "dataLen": extHdr.DataLen, + // "dataInfo": extHdr.DataInfo, + "decMsg": "", + } + // Base64 编码 + m["dataInfo"] = base64.StdEncoding.EncodeToString(extHdr.DataInfo) + + if extHdr.Proto == 6 { // TCP + // 取响应数据 + iplen := uint16(binary.BigEndian.Uint16(extHdr.DataInfo[2:])) + tcplen := uint16(iplen - 32 - 20) + hdrlen := uint16(binary.BigEndian.Uint16(extHdr.DataInfo[20+32+1:])) + offset := uint16(52) + // fmt.Printf("HTTP %d %d %d \n", iplen, tcplen, hdrlen) + if tcplen > (hdrlen + 9) { // has data + doffset := uint16(offset + hdrlen + 9) + datlen := uint16(binary.BigEndian.Uint16(extHdr.DataInfo[doffset+1:])) + // fmt.Printf("HTTP datlen %d \n", datlen) + m["decMsg"], _ = httpDataMsg(extHdr.DataInfo[offset+9:offset+9+hdrlen], extHdr.DataInfo[doffset+9:doffset+datlen+9]) + } else { + m["decMsg"], _ = httpDataMsg(extHdr.DataInfo[offset+9:hdrlen], nil) + } + } + + // pcap文件 + m["pcapFile"] = writePcap(extHdr) + return m, nil +} + +// =========== TCP协议Body =========== + +// httpDataMsg Http数据信息处理 +func httpDataMsg(header []byte, data []byte) (string, error) { + var remainSize = uint32(16 << 20) + var sawRegular bool + var invalid bool // pseudo header field errors + var Fields []hpack.HeaderField + + invalid = false + hdec := hpack.NewDecoder(4096, nil) + hdec.SetEmitEnabled(true) + hdec.SetMaxStringLength(int(16 << 20)) + hdec.SetEmitFunc(func(hf hpack.HeaderField) { + if !httpguts.ValidHeaderFieldValue(hf.Value) { + // Don't include the value in the error, because it may be sensitive. + invalid = true + } + isPseudo := strings.HasPrefix(hf.Name, ":") + if isPseudo { + if sawRegular { + invalid = true + } + } else { + sawRegular = true + if !validWireHeaderFieldName(hf.Name) { + invalid = true + } + } + + if invalid { + hdec.SetEmitEnabled(false) + return + } + + size := hf.Size() + if size > remainSize { + hdec.SetEmitEnabled(false) + //mh.Truncated = true + return + } + remainSize -= size + + Fields = append(Fields, hf) + }) + + // defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {}) + + frag := header + if _, err := hdec.Write(frag); err != nil { + return "", err + } + + if err := hdec.Close(); err != nil { + return "", err + } + + // hdec.SetEmitFunc(func(hf hpack.HeaderField) {}) + + var headers []byte + var line string + for i := range Fields { + line = fmt.Sprintf("\"%s\":\"%s\",", Fields[i].Name, Fields[i].Value) + headers = append(headers, []byte(line)...) + } + + if len(data) > 0 { + return fmt.Sprintf("{ %s \"content\":%s }", string(headers), string(data)), nil + } else { + return fmt.Sprintf("{ %s }", string(headers)), nil + } +} + +// validWireHeaderFieldName 校验报文头字段名称 +func validWireHeaderFieldName(v string) bool { + if len(v) == 0 { + return false + } + for _, r := range v { + if !httpguts.IsTokenRune(r) { + return false + } + if 'A' <= r && r <= 'Z' { + return false + } + } + return true +} + +// =========== writePcap 写Pcap文件 =========== + +const magicMicroseconds = 0xA1B2C3D4 +const versionMajor = 2 +const versionMinor = 4 + +func writeEmptyPcap(filename string, timeStamp int64, length int, data []byte) error { + var err error + var file *os.File + if _, err = os.Stat(filename); os.IsNotExist(err) { + file, err = os.Create(filename) + // File Header + var fileHeaderBuf [24]byte + binary.LittleEndian.PutUint32(fileHeaderBuf[0:4], magicMicroseconds) + binary.LittleEndian.PutUint16(fileHeaderBuf[4:6], versionMajor) + binary.LittleEndian.PutUint16(fileHeaderBuf[6:8], versionMinor) + // bytes 8:12 stay 0 (timezone = UTC) + // bytes 12:16 stay 0 (sigfigs is always set to zero, according to + // http://wiki.wireshark.org/Development/LibpcapFileFormat + binary.LittleEndian.PutUint32(fileHeaderBuf[16:20], 0x00040000) + binary.LittleEndian.PutUint32(fileHeaderBuf[20:24], 0x00000071) + if _, err := file.Write(fileHeaderBuf[:]); err != nil { + return err + } + } else { + file, err = os.OpenFile(filename, os.O_WRONLY|os.O_APPEND, 0666) + } + if err != nil { + return err + } + defer file.Close() + + // Packet Header + var packetHeaderBuf [24]byte + t := time.UnixMilli(timeStamp) + if t.IsZero() { + t = time.Now() + } + secs := t.Unix() + usecs := t.Nanosecond() / 1000 + binary.LittleEndian.PutUint32(packetHeaderBuf[0:4], uint32(secs)) + binary.LittleEndian.PutUint32(packetHeaderBuf[4:8], uint32(usecs)) + binary.LittleEndian.PutUint32(packetHeaderBuf[8:12], uint32(length+16)) + binary.LittleEndian.PutUint32(packetHeaderBuf[12:16], uint32(length+16)) + if _, err := file.Write(packetHeaderBuf[:]); err != nil { + return err + } + + // 数据包内容的定义 + cooked := [...]byte{0x00, 0x00, 0x03, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00} + if _, err := file.Write(cooked[:]); err != nil { + return err + } + + // Packet Data + if _, err := file.Write(data); err != nil { + return err + } + return nil +} + +// writePcap 写Pcap文件并返回文件路径 +func writePcap(extHdr ExtHeader) string { + filePath := fmt.Sprintf("/tmp/trace_%d .pcap", extHdr.TaskId) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + err := writeEmptyPcap(filePath, extHdr.TimeStamp, int(extHdr.DataLen), extHdr.DataInfo) + if err != nil { + return "" + } + return filePath +} diff --git a/src/modules/trace/trace.go b/src/modules/trace/trace.go index feef0d16..db3b777c 100644 --- a/src/modules/trace/trace.go +++ b/src/modules/trace/trace.go @@ -5,6 +5,7 @@ import ( "be.ems/src/framework/middleware" "be.ems/src/framework/middleware/collectlogs" "be.ems/src/modules/trace/controller" + "be.ems/src/modules/trace/service" "github.com/gin-gonic/gin" ) @@ -13,6 +14,9 @@ import ( func Setup(router *gin.Engine) { logger.Infof("开始加载 ====> trace 模块路由") + // 启动时需要的初始参数 + InitLoad() + traceGroup := router.Group("/trace") // 信令抓包 @@ -38,4 +42,77 @@ func Setup(router *gin.Engine) { controller.NewTcpdump.UPFTrace, ) } + + // 跟踪任务 网元HLR (免登录) + taskHLRGroup := traceGroup.Group("/task/hlr") + { + taskHLRGroup.GET("/list", + controller.NewTraceTaskHlr.List, + ) + taskHLRGroup.DELETE("/:ids", + controller.NewTraceTaskHlr.Remove, + ) + taskHLRGroup.POST("/start", + controller.NewTraceTaskHlr.Start, + ) + taskHLRGroup.POST("/stop", + controller.NewTraceTaskHlr.Stop, + ) + taskHLRGroup.POST("/file", + controller.NewTraceTaskHlr.File, + ) + taskHLRGroup.GET("/filePull", + controller.NewTraceTaskHlr.FilePull, + ) + } + + // 跟踪任务 + taskGroup := traceGroup.Group("/task") + { + taskGroup.GET("/list", + middleware.PreAuthorize(nil), + controller.NewTraceTask.List, + ) + taskGroup.GET("/:id", + middleware.PreAuthorize(nil), + controller.NewTraceTask.Info, + ) + taskGroup.POST("", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.task", collectlogs.BUSINESS_TYPE_INSERT)), + controller.NewTraceTask.Add, + ) + taskGroup.PUT("", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.task", collectlogs.BUSINESS_TYPE_UPDATE)), + controller.NewTraceTask.Edit, + ) + taskGroup.DELETE("/:ids", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.task", collectlogs.BUSINESS_TYPE_DELETE)), + controller.NewTraceTask.Remove, + ) + } + + // 跟踪数据 + taskDataGroup := traceGroup.Group("/data") + { + taskDataGroup.GET("/list", + middleware.PreAuthorize(nil), + controller.NewTraceData.List, + ) + taskDataGroup.DELETE("/:ids", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.taskData", collectlogs.BUSINESS_TYPE_DELETE)), + controller.NewTraceData.Remove, + ) + } +} + +// InitLoad 初始参数 +func InitLoad() { + // 创建跟踪任务信令数据通道UDP + if err := service.NewTraceTask.CreateUDP(); err != nil { + logger.Errorf("socket udp init fail: %s", err.Error()) + } } diff --git a/src/modules/ws/controller/ws.go b/src/modules/ws/controller/ws.go index 4ff3def6..1b78ed73 100644 --- a/src/modules/ws/controller/ws.go +++ b/src/modules/ws/controller/ws.go @@ -10,10 +10,10 @@ import ( "be.ems/src/framework/i18n" "be.ems/src/framework/logger" + "be.ems/src/framework/telnet" "be.ems/src/framework/utils/ctx" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/ssh" - "be.ems/src/framework/utils/telnet" "be.ems/src/framework/vo/result" "be.ems/src/modules/ws/service" "github.com/gin-gonic/gin" @@ -286,10 +286,6 @@ func (s *WSController) Telnet(c *gin.Context) { go s.wsService.ClientWriteListen(wsClient) go s.wsService.ClientReadListen(wsClient, service.ReceiveTelnet) - // 等待1秒,排空首次消息 - time.Sleep(1 * time.Second) - _ = clientSession.Read() - // 实时读取Telnet消息直接输出 msTicker := time.NewTicker(100 * time.Millisecond) defer msTicker.Stop() @@ -298,7 +294,7 @@ func (s *WSController) Telnet(c *gin.Context) { case ms := <-msTicker.C: outputByte := clientSession.Read() if len(outputByte) > 0 { - outputStr := strings.TrimRight(string(outputByte), "\x00") + outputStr := string(outputByte) msgByte, _ := json.Marshal(result.Ok(map[string]any{ "requestId": fmt.Sprintf("telnet_%s_%d", neHost.HostID, ms.UnixMilli()), "data": outputStr, diff --git a/src/modules/ws/model/net_connect.go b/src/modules/ws/model/net_connect.go index 945ede5d..6b67edb6 100644 --- a/src/modules/ws/model/net_connect.go +++ b/src/modules/ws/model/net_connect.go @@ -8,13 +8,13 @@ type NetConnectData struct { Status string `json:"status"` Laddr net.Addr `json:"localaddr"` Raddr net.Addr `json:"remoteaddr"` - PID int32 `json:"PID"` + PID int32 `json:"pid"` Name string `json:"name"` } // NetConnectQuery 网络连接进程查询 type NetConnectQuery struct { - Port int32 `json:"port"` - ProcessName string `json:"processName"` - ProcessID int32 `json:"processID"` + Port int32 `json:"port"` + Name string `json:"name"` + PID int32 `json:"pid"` } diff --git a/src/modules/ws/model/ps_process.go b/src/modules/ws/model/ps_process.go index e93247a8..d52e833b 100644 --- a/src/modules/ws/model/ps_process.go +++ b/src/modules/ws/model/ps_process.go @@ -2,37 +2,33 @@ package model // PsProcessData 进程数据 type PsProcessData struct { - PID int32 `json:"PID"` + PID int32 `json:"pid"` Name string `json:"name"` - PPID int32 `json:"PPID"` + PPID int32 `json:"ppid"` Username string `json:"username"` Status string `json:"status"` - StartTime string `json:"startTime"` + StartTime int64 `json:"startTime"` NumThreads int32 `json:"numThreads"` NumConnections int `json:"numConnections"` CpuPercent string `json:"cpuPercent"` - DiskRead string `json:"diskRead"` - DiskWrite string `json:"diskWrite"` - CmdLine string `json:"cmdLine"` + DiskRead uint64 `json:"diskRead"` + DiskWrite uint64 `json:"diskWrite"` - Rss string `json:"rss"` - VMS string `json:"vms"` - HWM string `json:"hwm"` - Data string `json:"data"` - Stack string `json:"stack"` - Locked string `json:"locked"` - Swap string `json:"swap"` + Rss uint64 `json:"rss"` + VMS uint64 `json:"vms"` + HWM uint64 `json:"hwm"` + Data uint64 `json:"data"` + Stack uint64 `json:"stack"` + Locked uint64 `json:"locked"` + Swap uint64 `json:"swap"` - CpuValue float64 `json:"cpuValue"` - RssValue uint64 `json:"rssValue"` - - Envs []string `json:"envs"` + CmdLine string `json:"cmdLine"` } // PsProcessQuery 进程查询 type PsProcessQuery struct { - Pid int32 `json:"pid"` + PID int32 `json:"pid"` Name string `json:"name"` Username string `json:"username"` } diff --git a/src/modules/ws/processor/net_connect.go b/src/modules/ws/processor/net_connect.go index 187de88b..5e242435 100644 --- a/src/modules/ws/processor/net_connect.go +++ b/src/modules/ws/processor/net_connect.go @@ -29,13 +29,16 @@ func GetNetConnections(requestID string, data any) ([]byte, error) { continue } for _, conn := range connections { - if query.ProcessID > 0 && query.ProcessID != conn.Pid { + if query.PID > 0 && query.PID != conn.Pid { continue } proc, err := process.NewProcess(conn.Pid) if err == nil { - name, _ := proc.Name() - if name != "" && query.ProcessName != "" && !strings.Contains(name, query.ProcessName) { + name, err := proc.Name() + if err != nil { + continue + } + if query.Name != "" && !strings.Contains(name, query.Name) { continue } if query.Port > 0 && query.Port != int32(conn.Laddr.Port) && query.Port != int32(conn.Raddr.Port) { diff --git a/src/modules/ws/processor/ps_process.go b/src/modules/ws/processor/ps_process.go index 660cc765..a685eba3 100644 --- a/src/modules/ws/processor/ps_process.go +++ b/src/modules/ws/processor/ps_process.go @@ -8,8 +8,6 @@ import ( "sync" "be.ems/src/framework/logger" - "be.ems/src/framework/utils/date" - "be.ems/src/framework/utils/parse" "be.ems/src/framework/vo/result" "be.ems/src/modules/ws/model" "github.com/shirou/gopsutil/v4/process" @@ -31,86 +29,68 @@ func GetProcessData(requestID string, data any) ([]byte, error) { return nil, err } - var ( - dataArr = []model.PsProcessData{} - resultMutex sync.Mutex - wg sync.WaitGroup - numWorkers = 4 - ) - - handleData := func(proc *process.Process) { + // 解析数据 + handleData := func(proc *process.Process) (model.PsProcessData, bool) { procData := model.PsProcessData{ PID: proc.Pid, } - if query.Pid > 0 && query.Pid != proc.Pid { - return - } - procName, err := proc.Name() - if procName == "" || err != nil { - return - } else { + if procName, err := proc.Name(); err == nil { procData.Name = procName } - if query.Name != "" && !strings.Contains(procData.Name, query.Name) { - return - } if username, err := proc.Username(); err == nil { procData.Username = username } + + // 查询过滤 + if query.PID > 0 && procData.PID != query.PID { + return procData, false + } + if query.Name != "" && !strings.Contains(procData.Name, query.Name) { + return procData, false + } if query.Username != "" && !strings.Contains(procData.Username, query.Username) { - return + return procData, false } procData.PPID, _ = proc.Ppid() - statusArray, _ := proc.Status() - if len(statusArray) > 0 { + if statusArray, err := proc.Status(); err == nil && len(statusArray) > 0 { procData.Status = strings.Join(statusArray, ",") } - createTime, procErr := proc.CreateTime() - if procErr == nil { - procData.StartTime = date.ParseDateToStr(createTime, date.YYYY_MM_DD_HH_MM_SS) + if createTime, err := proc.CreateTime(); err == nil { + procData.StartTime = createTime } procData.NumThreads, _ = proc.NumThreads() - procData.CpuValue, _ = proc.CPUPercent() - procData.CpuPercent = fmt.Sprintf("%.2f", procData.CpuValue) + "%" + if connections, err := proc.Connections(); err == nil { + procData.NumConnections = len(connections) + } + cpuPercent, _ := proc.CPUPercent() + procData.CpuPercent = fmt.Sprintf("%.2f", cpuPercent) menInfo, procErr := proc.MemoryInfo() if procErr == nil { - procData.Rss = parse.Bit(float64(menInfo.RSS)) - procData.Data = parse.Bit(float64(menInfo.Data)) - procData.VMS = parse.Bit(float64(menInfo.VMS)) - procData.HWM = parse.Bit(float64(menInfo.HWM)) - procData.Stack = parse.Bit(float64(menInfo.Stack)) - procData.Locked = parse.Bit(float64(menInfo.Locked)) - procData.Swap = parse.Bit(float64(menInfo.Swap)) - - procData.RssValue = menInfo.RSS - } else { - procData.Rss = "--" - procData.Data = "--" - procData.VMS = "--" - procData.HWM = "--" - procData.Stack = "--" - procData.Locked = "--" - procData.Swap = "--" - - procData.RssValue = 0 + procData.Rss = menInfo.RSS + procData.Data = menInfo.Data + procData.VMS = menInfo.VMS + procData.HWM = menInfo.HWM + procData.Stack = menInfo.Stack + procData.Locked = menInfo.Locked + procData.Swap = menInfo.Swap } - ioStat, procErr := proc.IOCounters() - if procErr == nil { - procData.DiskWrite = parse.Bit(float64(ioStat.WriteBytes)) - procData.DiskRead = parse.Bit(float64(ioStat.ReadBytes)) - } else { - procData.DiskWrite = "--" - procData.DiskRead = "--" + if ioStat, err := proc.IOCounters(); err == nil { + procData.DiskWrite = ioStat.WriteBytes + procData.DiskRead = ioStat.ReadBytes } procData.CmdLine, _ = proc.Cmdline() - procData.Envs, _ = proc.Environ() - resultMutex.Lock() - dataArr = append(dataArr, procData) - resultMutex.Unlock() + return procData, true } + var ( + dataArr = []model.PsProcessData{} + mu sync.Mutex + wg sync.WaitGroup + numWorkers = 4 + ) + chunkSize := (len(processes) + numWorkers - 1) / numWorkers for i := 0; i < numWorkers; i++ { wg.Add(1) @@ -122,9 +102,15 @@ func GetProcessData(requestID string, data any) ([]byte, error) { go func(start, end int) { defer wg.Done() + localDataArr := make([]model.PsProcessData, 0, end-start) // 本地切片避免竞态 for j := start; j < end; j++ { - handleData(processes[j]) + if data, ok := handleData(processes[j]); ok { + localDataArr = append(localDataArr, data) + } } + mu.Lock() + dataArr = append(dataArr, localDataArr...) + mu.Unlock() }(start, end) } diff --git a/src/modules/ws/service/ws_receive.impl.go b/src/modules/ws/service/ws_receive.impl.go index e946d9ac..918efcc5 100644 --- a/src/modules/ws/service/ws_receive.impl.go +++ b/src/modules/ws/service/ws_receive.impl.go @@ -7,8 +7,8 @@ import ( "time" "be.ems/src/framework/logger" + "be.ems/src/framework/telnet" "be.ems/src/framework/utils/ssh" - "be.ems/src/framework/utils/telnet" "be.ems/src/framework/vo/result" "be.ems/src/modules/ws/model" "be.ems/src/modules/ws/processor" @@ -234,9 +234,8 @@ func (s *WSReceiveImpl) Telnet(client *model.WSClient, reqMsg model.WSRequest) { } err = json.Unmarshal(msgByte, &data) if err == nil { - telnetClientSession := client.ChildConn.(*telnet.TelnetClientSession) - err = telnetClientSession.WindowChange(data.Rows, data.Cols) - _ = telnetClientSession.Read() + // telnetClientSession := client.ChildConn.(*telnet.TelnetClientSession) + // _ = telnetClientSession.WindowChange(data.Rows, data.Cols) } default: err = fmt.Errorf("message type %s not supported", reqMsg.Type) diff --git a/sshsvc/config/config.go b/sshsvc/config/config.go index 411d6758..591d7fdf 100644 --- a/sshsvc/config/config.go +++ b/sshsvc/config/config.go @@ -48,8 +48,42 @@ type YamlConfig struct { Timeout uint16 `yaml:"timeout"` Session string `yaml:"session"` MmlHome string `yaml:"mmlHome"` + UserName string `yaml:"userName"` + Password string `yaml:"password"` + AuthType string `yaml:"authType"` + TagNE string `yaml:"tagNE"` } `yaml:"sshd"` + TelnetServer struct { + ListenAddr string `yaml:"listenAddr"` + ListenPort uint16 `yaml:"listenPort"` + MaxConnNum uint8 `yaml:"maxConnNum"` + Timeout uint16 `yaml:"timeout"` + Session string `yaml:"session"` + MmlHome string `yaml:"mmlHome"` + UserName string `yaml:"userName"` + Password string `yaml:"password"` + AuthType string `yaml:"authType"` + TagNE string `yaml:"tagNE"` + } `yaml:"telnetServer"` + + SNMPServer struct { + ListenAddr string `yaml:"listenAddr"` + ListenPort uint16 `yaml:"listenPort"` + UserName string `yaml:"userName"` + AuthPass string `yaml:"authPass"` + AuthProto string `yaml:"authProto"` + PrivPass string `yaml:"privPass"` + PrivProto string `yaml:"privProto"` + EngineID string `yaml:"engineID"` + TrapPort uint16 `yaml:"trapPort"` + TrapListen bool `yaml:"trapListen"` + TrapBool bool `yaml:"trapBool"` + TrapTick uint16 `yaml:"trapTick"` + TimeOut uint16 `yaml:"timeOut"` + TrapTarget string `yaml:"trapTarget"` + } `yaml:"snmpServer"` + Database DbConfig `yaml:"database"` OMC struct { diff --git a/sshsvc/etc/sshsvc.yaml b/sshsvc/etc/sshsvc.yaml index 9c5dada8..ec28700a 100644 --- a/sshsvc/etc/sshsvc.yaml +++ b/sshsvc/etc/sshsvc.yaml @@ -21,15 +21,52 @@ logmml: # ssh service listen ipv4/v6 and port, support multiple routines # ip: 0.0.0.0 or ::0, support IPv4/v6 # session: single/multiple session for one user +# authType: local/radius sshd: listenAddr: 0.0.0.0 - listenPort: 2222 + listenPort: 32222 privateKey: ./.ssh/id_rsa - maxConnNum: 20 + maxConnNum: 2 timeout: 1800 session: multiple mmlHome: ./mmlhome + userName: manager + password: pass123 + authType: local + tagNE: hlr +# authType: local/omc +telnetServer: + listenAddr: 0.0.0.0 + listenPort: 32323 + maxConnNum: 2 + timeout: 1800 + session: multiple + mmlHome: ./mmlhome + userName: manager + password: pass123 + authType: local + tagNE: hlr + +# authproto: NoAuth/MD5/SHA +# privProto: NoPriv/DES/AES/AES192/AES256 +snmpServer: + listenAddr: '[::]' + listenPort: 34957 + userName: manager + authPass: pass123 + authproto: MD5 + privPass: "3F2A1B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1B2C3D4E" + privProto: DES + #engineID: "800007db03360102101101" + engineID: "8000000004323030313a6462383a3a39313636" + trapPort: 34958 + trapListen: true + trapBool: true + trapTick: 60 + timeOut: 5 + trapTarget: "2001:db8::9219" + database: type: mysql user: root diff --git a/sshsvc/makefile b/sshsvc/makefile index 8e53cce9..9f6b2f77 100644 --- a/sshsvc/makefile +++ b/sshsvc/makefile @@ -1,7 +1,7 @@ # Makefile for OMC-OMC-crontask project PROJECT = OMC -VERSION = 2.2408.1 +VERSION = 2.2409.3 LIBDIR = be.ems/lib BINNAME = sshsvc diff --git a/sshsvc/snmp/snmp.go b/sshsvc/snmp/snmp.go new file mode 100644 index 00000000..26cf2c9d --- /dev/null +++ b/sshsvc/snmp/snmp.go @@ -0,0 +1,439 @@ +package snmp + +import ( + "flag" + "fmt" + "log" + "net" + "os" + "path/filepath" + "strings" + "time" + + g "github.com/gosnmp/gosnmp" + "github.com/slayercat/GoSNMPServer" + "github.com/slayercat/GoSNMPServer/mibImps" +) + +type SNMPService struct { + ListenAddr string + ListenPort uint16 + UserName string + AuthPass string + AuthProto string + PrivPass string + PrivProto string + EngineID string + TrapPort uint16 + TrapListen bool + TrapBool bool + TrapTick uint16 + TimeOut uint16 + TrapTarget string + + ListenHost string + TrapHost string + SysDescr string + SysService int +} + +func (s *SNMPService) getAuthProto() g.SnmpV3AuthProtocol { + switch s.AuthProto { + case "NoAuth": + return g.NoAuth + case "MD5": + return g.MD5 + case "SHA": + return g.SHA + default: + } + return g.MD5 +} + +func (s *SNMPService) getPrivProto() g.SnmpV3PrivProtocol { + switch s.PrivProto { + case "NoPriv": + return g.NoPriv + case "DES": + return g.DES + case "AES": + return g.AES + case "AES192": + return g.AES192 + case "AES256": + return g.AES256 + default: + } + return g.DES +} + +func (s *SNMPService) setSecParamsList() []g.UsmSecurityParameters { + var secParamsList = []g.UsmSecurityParameters{ + { + UserName: s.UserName, + AuthenticationProtocol: s.getAuthProto(), + AuthenticationPassphrase: s.AuthPass, + PrivacyProtocol: s.getPrivProto(), + PrivacyPassphrase: s.PrivPass, + AuthoritativeEngineID: s.EngineID, + }, + // { + // UserName: "myuser2", + // AuthenticationProtocol: g.SHA, + // AuthenticationPassphrase: "mypassword2", + // PrivacyProtocol: g.DES, + // PrivacyPassphrase: "myprivacy2", + // AuthoritativeEngineID: s.EngineID, + // }, + // { + // UserName: "myuser2", + // AuthenticationProtocol: g.MD5, + // AuthenticationPassphrase: "mypassword2", + // PrivacyProtocol: g.AES, + // PrivacyPassphrase: "myprivacy2", + // AuthoritativeEngineID: s.EngineID, + // }, + } + return secParamsList +} + +func (s *SNMPService) StartSNMPServer() { + // 设置引擎启动次数和引varvar + var engineBoots uint32 = 1 + //var engineTime uint32 = uint32(time.Now().Unix() % 2147483647) // 使用当前时间初始化 + //var engineTime uint32 = 3600 // 使用当前时间初始化 + master := GoSNMPServer.MasterAgent{ + Logger: GoSNMPServer.NewDefaultLogger(), + SecurityConfig: GoSNMPServer.SecurityConfig{ + NoSecurity: true, + AuthoritativeEngineBoots: engineBoots, + // OnGetAuthoritativeEngineTime: func() uint32 { + // return engineTime + // }, + //AuthoritativeEngineID: GoSNMPServer.SNMPEngineID{EngineIDData: "0x800007DB03360102101100"}, + + Users: s.setSecParamsList(), + }, + SubAgents: []*GoSNMPServer.SubAgent{ + { + UserErrorMarkPacket: false, + CommunityIDs: []string{"public", "private"}, // SNMPv1 and SNMPv2c community strings + OIDs: s.handleOIDs(), + //OIDs: mibImps.All(), + }, + }, + } + + server := GoSNMPServer.NewSNMPServer(master) + err := server.ListenUDP("udp", s.ListenHost) + if err != nil { + log.Fatalf("Error in listen: %+v", err) + } + server.ServeForever() +} + +func (s *SNMPService) handleOIDs() []*GoSNMPServer.PDUValueControlItem { + customOIDs := []*GoSNMPServer.PDUValueControlItem{ + { + OID: "1.3.6.1.2.1.1.1.0", + Type: g.OctetString, + OnGet: func() (value interface{}, err error) { + return s.SysDescr, nil + }, + OnSet: func(value interface{}) error { + // 将[]uint8转换为string + if v, ok := value.([]uint8); ok { + s.SysDescr = string(v) + log.Printf("Set request for OID 1.3.6.1.2.1.1.1.0 with value %v", s.SysDescr) + return nil + } + return nil + }, + }, + { + OID: "1.3.6.1.2.1.1.3.0", + Type: g.TimeTicks, + OnGet: func() (value interface{}, err error) { + return uint32(time.Now().Unix()), nil + }, + }, + { + OID: "1.3.6.1.2.1.1.7.0", + Type: g.Integer, + OnGet: func() (value interface{}, err error) { + return s.SysService, nil + }, + OnSet: func(value interface{}) error { + // 将[]uint8转换为string + if v, ok := value.(int); ok { + s.SysService = v + log.Printf("Set request for OID 1.3.6.1.2.1.1.7.0 with value %v", s.SysService) + return nil + } + return nil + }, + }, + } + // 获取mibImps.All()返回的OID列表 + mibOIDs := mibImps.All() + + // 使用Map来检测并移除重复的OID + oidMap := make(map[string]*GoSNMPServer.PDUValueControlItem) + for _, oid := range customOIDs { + oidMap[oid.OID] = oid + } + for _, oid := range mibOIDs { + if _, exists := oidMap[oid.OID]; !exists { + oidMap[oid.OID] = oid + } else { + log.Printf("Duplicate OID found: %s", oid.OID) + } + } + + // 将Map转换为Slice + allOIDs := make([]*GoSNMPServer.PDUValueControlItem, 0, len(oidMap)) + for _, oid := range oidMap { + allOIDs = append(allOIDs, oid) + } + + return allOIDs +} + +func (s *SNMPService) StartTrapServer() { + flag.Usage = func() { + fmt.Printf("Usage:\n") + fmt.Printf(" %s\n", filepath.Base(os.Args[0])) + flag.PrintDefaults() + } + + tl := g.NewTrapListener() + tl.OnNewTrap = s.MyTrapHandler + + usmTable := g.NewSnmpV3SecurityParametersTable(g.NewLogger(log.New(os.Stdout, "", 0))) + for i := range s.setSecParamsList() { + sp := &s.setSecParamsList()[i] // 使用指针 + err := usmTable.Add(sp.UserName, sp) + if err != nil { + usmTable.Logger.Print(err) + } + } + + // 设置引擎启动次数和引varvar + //var engineBoots uint32 = 1 + // var engineTime uint32 = uint32(time.Now().Unix() % 2147483647) // 使用当前时间初始化 + //var engineTime uint32 = 3600 // 使用当前时间初始化 + gs := &g.GoSNMP{ + Target: s.TrapTarget, + Port: s.TrapPort, + Transport: "udp", + Timeout: time.Duration(s.TimeOut) * time.Second, // 设置超时时间为x秒 + Version: g.Version3, // Always using version3 for traps, only option that works with all SNMP versions simultaneously + MsgFlags: g.NoAuthNoPriv, + SecurityModel: g.UserSecurityModel, + SecurityParameters: &g.UsmSecurityParameters{ + UserName: s.UserName, + AuthoritativeEngineID: s.EngineID, + AuthoritativeEngineBoots: 1, + //AuthoritativeEngineTime: 3600, + AuthenticationProtocol: s.getAuthProto(), + AuthenticationPassphrase: s.AuthPass, + PrivacyProtocol: s.getPrivProto(), + PrivacyPassphrase: s.PrivPass, + }, + //TrapSecurityParametersTable: usmTable, + ContextEngineID: s.EngineID, + ContextName: "v3test", + } + tl.Params = gs + tl.Params.Logger = g.NewLogger(log.New(os.Stdout, "", 0)) + + // 定时发送Trap + if s.TrapBool { + go s.SendPeriodicTraps(gs) + } + go s.monitorNetwork(gs) + + if s.TrapListen { + err := tl.Listen(s.TrapHost) + if err != nil { + log.Panicf("error in listen: %s", err) + } + } +} + +func (s *SNMPService) MyTrapHandler(packet *g.SnmpPacket, addr *net.UDPAddr) { + log.Printf("got trapdata from %s\n", addr.IP) + for _, v := range packet.Variables { + switch v.Type { + case g.OctetString: + b := v.Value.([]byte) + fmt.Printf("OID: %s, string: %x\n", v.Name, b) + + default: + log.Printf("trap: %+v\n", v) + } + } +} + +func (s *SNMPService) SendPeriodicTraps(gs *g.GoSNMP) { + err := gs.Connect() + if err != nil { + log.Fatalf("Connect() err: %v", err) + } + defer gs.Conn.Close() + + ticker := time.NewTicker(time.Duration(s.TrapTick) * time.Second) // 每10秒发送一次Trap + defer ticker.Stop() + + for range ticker.C { // 每x秒发送一次Trap + trap := g.SnmpTrap{ + Variables: []g.SnmpPDU{ + { + Name: ".1.3.6.1.2.1.1.3.0", + Type: g.TimeTicks, + Value: uint32(time.Now().Unix()), + }, + { + Name: ".1.3.6.1.6.3.1.1.4.1.0", + Type: g.ObjectIdentifier, + Value: ".1.3.6.1.6.3.1.1.5.1", + }, + }, + } + _, err = gs.SendTrap(trap) + if err != nil { + log.Printf("error sending trap: %s", err) + } else { + log.Printf("trap sent successfully") + } + } +} + +// 1. 设备链路连接失败时发送Trap (LinkDown) +func (s *SNMPService) sendLinkDownTrap(gs *g.GoSNMP, ifIndex int, ifDescr string) { + trap := g.SnmpTrap{ + Variables: []g.SnmpPDU{ + { + Name: ".1.3.6.1.2.1.2.2.1.1", // ifIndex + Type: g.Integer, + Value: ifIndex, + }, + { + Name: ".1.3.6.1.2.1.2.2.1.2", // ifDescr + Type: g.OctetString, + Value: ifDescr, + }, + { + Name: ".1.3.6.1.6.3.1.1.5.3", // linkDown + Type: g.ObjectIdentifier, + Value: ".1.3.6.1.6.3.1.1.5.3", + }, + }, + } + + _, err := gs.SendTrap(trap) + if err != nil { + log.Printf("error sending LinkDown trap: %s", err) + } else { + log.Printf("LinkDown trap sent successfully") + } +} + +// 2. 设备链路恢复正常时发送Trap (LinkUp) +func (s *SNMPService) sendLinkUpTrap(gs *g.GoSNMP, ifIndex int, ifDescr string) { + trap := g.SnmpTrap{ + Variables: []g.SnmpPDU{ + { + Name: ".1.3.6.1.2.1.2.2.1.1", // ifIndex + Type: g.Integer, + Value: ifIndex, + }, + { + Name: ".1.3.6.1.2.1.2.2.1.2", // ifDescr + Type: g.OctetString, + Value: ifDescr, + }, + { + Name: ".1.3.6.1.6.3.1.1.5.4", // linkUp + Type: g.ObjectIdentifier, + Value: ".1.3.6.1.6.3.1.1.5.4", + }, + }, + } + + _, err := gs.SendTrap(trap) + if err != nil { + log.Printf("error sending LinkUp trap: %s", err) + } else { + log.Printf("LinkUp trap sent successfully") + } +} + +// 3. 设备鉴权失败时发送Trap (AuthenticationFailure) +func (s *SNMPService) sendAuthFailureTrap(gs *g.GoSNMP, username, descr string) { + trap := g.SnmpTrap{ + Variables: []g.SnmpPDU{ + { + Name: ".1.3.6.1.6.3.1.1.5.5", // authenticationFailure + Type: g.ObjectIdentifier, + Value: ".1.3.6.1.6.3.1.1.5.5", + }, + { + Name: ".1.3.6.1.4.1.2021.251.1", // 自定义OID,用于记录失败的用户名 + Type: g.OctetString, + Value: username, + }, + { + Name: ".1.3.6.1.4.1.2021.252.1", // 自定义OID,用于记录描述 + Type: g.OctetString, + Value: descr, + }, + }, + } + + _, err := gs.SendTrap(trap) + if err != nil { + log.Printf("error sending AuthenticationFailure trap: %s", err) + } else { + log.Printf("AuthenticationFailure trap sent successfully") + } +} + +func (s *SNMPService) monitorNetwork(gs *g.GoSNMP) { + // 假设有一个函数 checkLinkStatus 返回链路状态 + for { + serviceStatus := s.checkServiceStatus() + switch strings.ToUpper(serviceStatus) { + case "LINK_DOWN": + index := 1 + ifDescr := fmt.Sprintf("Link(index=%d) DOWN", index) + s.sendLinkDownTrap(gs, index, ifDescr) // 假设接口索引为1 + s.SysService = 0 + case "LINK_UP": + index := 1 + ifDescr := fmt.Sprintf("Link(index=%d) UP", index) + s.sendLinkUpTrap(gs, index, ifDescr) // 假设接口索引为1 + s.SysService = 0 + case "AUTH_FAILURE": + descr := "Authentication Failure" + s.sendAuthFailureTrap(gs, s.UserName, descr) + s.SysService = 0 + default: + } + + time.Sleep(10 * time.Second) // 每10秒检查一次 + } +} + +func (s *SNMPService) checkServiceStatus() string { + switch s.SysService { + case 1: + return "LINK_DOWN" + case 2: + return "LINK_UP" + case 3: + return "AUTH_FAILURE" + default: + } + return "NORMAL" +} diff --git a/sshsvc/sshsvc.go b/sshsvc/sshsvc.go index 9dab6ca2..5964e062 100644 --- a/sshsvc/sshsvc.go +++ b/sshsvc/sshsvc.go @@ -1,13 +1,16 @@ package main import ( - "errors" + "bufio" "fmt" "io" "net" "os" "os/exec" + "strconv" "strings" + "sync" + "time" "be.ems/lib/dborm" "be.ems/lib/global" @@ -15,15 +18,23 @@ import ( "be.ems/lib/mmlp" "be.ems/sshsvc/config" "be.ems/sshsvc/logmml" + "be.ems/sshsvc/snmp" + omctelnet "be.ems/sshsvc/telnet" //"github.com/gliderlabs/ssh" "golang.org/x/crypto/ssh" "golang.org/x/term" ) -var connNum int = 0 var conf *config.YamlConfig +var ( + telnetCC int + sshCC int + telnetMu sync.Mutex + sshMu sync.Mutex +) + func init() { conf = config.GetYamlConfig() log.InitLogger(conf.Logger.File, conf.Logger.Duration, conf.Logger.Count, "omc:sshsvc", config.GetLogLevel()) @@ -57,33 +68,32 @@ func main() { serverConfig := &ssh.ServerConfig{ PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { // 这里可以进行密码验证逻辑,例如检查用户名和密码是否匹配 - validUser, _, err := dborm.XormCheckLoginUser(conn.User(), string(password), conf.OMC.UserCrypt) - if err != nil { - return nil, err - } - if validUser == true { - sessionToken := fmt.Sprintf("%x", conn.SessionID()) // Generate new token to session ID - sourceAddr := conn.RemoteAddr().String() - timeOut := uint32(conf.Sshd.Timeout) - sessionMode := conf.Sshd.Session - log.Debugf("token:%s sourceAddr:%s", sessionToken, sourceAddr) - affected, err := dborm.XormInsertSession(conn.User(), sourceAddr, sessionToken, timeOut, sessionMode) - if err != nil { - log.Error("Failed to insert Session table:", err) - return nil, err - } - if affected == -1 { - err := errors.New("Failed to get session") - log.Error(err) - return nil, err - } + // validUser, _, err := dborm.XormCheckLoginUser(conn.User(), string(password), conf.OMC.UserCrypt) + // if err != nil { + // return nil, err + // } + // if validUser == true { + // sessionToken := fmt.Sprintf("%x", conn.SessionID()) // Generate new token to session ID + // sourceAddr := conn.RemoteAddr().String() + // timeOut := uint32(conf.Sshd.Timeout) + // sessionMode := conf.Sshd.Session + // log.Debugf("token:%s sourceAddr:%s", sessionToken, sourceAddr) + // affected, err := dborm.XormInsertSession(conn.User(), sourceAddr, sessionToken, timeOut, sessionMode) + // if err != nil { + // log.Error("Failed to insert Session table:", err) + // return nil, err + // } + // if affected == -1 { + // err := errors.New("Failed to get session") + // log.Error(err) + // return nil, err + // } - return nil, nil - } - - // if conn.User() == "admin" && string(password) == "123456" { // return nil, nil // } + if handleAuth(conf.Sshd.AuthType, conn.User(), string(password)) { + return nil, nil + } return nil, fmt.Errorf("invalid user or password") }, PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { @@ -101,8 +111,58 @@ func main() { log.Fatal("Failed to Listen: ", err) os.Exit(4) } + //fmt.Printf("MML SSH server startup, listen port:%d\n", conf.Sshd.ListenPort) + // 启动telnet服务器 + //telnetUri := fmt.Sprintf("%s:%d", conf.TelnetServer.ListenAddr, conf.TelnetServer.ListenPort) + // telnetListener, err := net.Listen("tcp", telnetUri) + // if err != nil { + // log.Fatal("Failed to Listen: ", err) + // os.Exit(4) + // } + //fmt.Printf("MML Telnet server startup, listen port:%d\n", conf.TelnetServer.ListenPort) + // telnetconn, err := telnetListener.Accept() + // if err != nil { + // log.Fatal("Failed to accept telnet connection: ", err) + // os.Exit(6) + // } - fmt.Printf("MML SSH server startup, listen port:%d\n", conf.Sshd.ListenPort) + telnetSvc := omctelnet.TelnetHandler{ + ListenAddr: conf.TelnetServer.ListenAddr, + ListenPort: conf.TelnetServer.ListenPort, + UserName: conf.TelnetServer.UserName, + Password: conf.TelnetServer.Password, + AuthType: conf.TelnetServer.AuthType, + MaxConnNum: conf.TelnetServer.MaxConnNum, + TagNE: conf.TelnetServer.TagNE, + ListenHost: conf.TelnetServer.ListenAddr + ":" + strconv.Itoa(int(conf.TelnetServer.ListenPort)), + } + go telnetSvc.StartTelnetServer() + // go StartTelnetServer(telnetSvc.ListenHost) + + snmpSvc := snmp.SNMPService{ + ListenAddr: conf.SNMPServer.ListenAddr, + ListenPort: conf.SNMPServer.ListenPort, + UserName: conf.SNMPServer.UserName, + AuthPass: conf.SNMPServer.AuthPass, + AuthProto: conf.SNMPServer.AuthProto, + PrivPass: conf.SNMPServer.PrivPass, + PrivProto: conf.SNMPServer.PrivProto, + EngineID: conf.SNMPServer.EngineID, + TrapPort: conf.SNMPServer.TrapPort, + TrapListen: conf.SNMPServer.TrapListen, + TrapBool: conf.SNMPServer.TrapBool, + TrapTick: conf.SNMPServer.TrapTick, + TimeOut: conf.SNMPServer.TimeOut, + TrapTarget: conf.SNMPServer.TrapTarget, + + ListenHost: conf.SNMPServer.ListenAddr + ":" + strconv.Itoa(int(conf.SNMPServer.ListenPort)), + TrapHost: conf.SNMPServer.ListenAddr + ":" + strconv.Itoa(int(conf.SNMPServer.TrapPort)), + SysDescr: "HLR server", + SysService: 0, + } + + go snmpSvc.StartSNMPServer() + go snmpSvc.StartTrapServer() for { conn, err := listener.Accept() @@ -115,6 +175,175 @@ func main() { } } +func handleAuth(authType, userName, password string) bool { + switch authType { + case "local": + if userName == conf.Sshd.UserName && password == conf.Sshd.Password { + return true + } + return false + case "radius": + exist, err := dborm.XEngDB().Table("OMC_PUB.sysUser").Where("userName=? AND password=md5(?)", userName, password).Exist() + if err != nil { + return false + } + return exist + case "omc": + + default: + } + + return false +} + +func StartTelnetServer(addr string) { + listener, err := net.Listen("tcp", addr) + if err != nil { + fmt.Println("Error starting Telnet server:", err) + return + } + defer listener.Close() + fmt.Println("Telnet server started on", addr) + + for { + conn, err := listener.Accept() + if err != nil { + fmt.Println("Error accepting Telnet connection:", err) + continue + } + + telnetMu.Lock() + if telnetCC >= int(conf.TelnetServer.MaxConnNum) { + telnetMu.Unlock() + io.WriteString(conn, "Connection limit reached. Try again later.\r\n") + conn.Close() + continue + } + telnetCC++ + telnetMu.Unlock() + + go handleTelnetConnection(conn) + } +} + +func handleTelnetConnection(conn net.Conn) { + defer func() { + telnetMu.Lock() + telnetCC-- + telnetMu.Unlock() + }() + defer conn.Close() + + reader := bufio.NewReader(conn) + writer := bufio.NewWriter(conn) + + // 发送欢迎信息 + writer.WriteString("Welcome to the Telnet server!\r\n") + writer.Flush() + + // 请求用户名 + writer.WriteString("Username: ") + writer.Flush() + user, _ := reader.ReadString('\n') + user = strings.TrimSpace(user) + + // 关闭回显模式 + writer.Write([]byte{255, 251, 1}) // IAC WILL ECHO + writer.Flush() + + // 请求密码 + writer.WriteString("Password: ") + writer.Flush() + + // 读取密码并清除控制序列 + var passBuilder strings.Builder + for { + b, err := reader.ReadByte() + if err != nil { + return + } + if b == '\n' || b == '\r' { + break + } + if b == 255 { // IAC + reader.ReadByte() // 忽略下一个字节 + reader.ReadByte() // 忽略下一个字节 + } else { + passBuilder.WriteByte(b) + } + } + pass := passBuilder.String() + + // 恢复回显模式 + writer.Write([]byte{255, 252, 1}) // IAC WONT ECHO + writer.Flush() + + if handleAuth(conf.TelnetServer.AuthType, user, pass) { + writer.WriteString("\r\nAuthentication successful!\r\n") + writer.Flush() + HandleCommands(user, conf.TelnetServer.TagNE, reader, writer) + } else { + writer.WriteString("\r\nAuthentication failed!\r\n") + writer.Flush() + } +} + +// 处理命令输 +func HandleCommands(user, tag string, reader *bufio.Reader, writer *bufio.Writer) { + header := fmt.Sprintf("[%s@%s]> ", user, tag) + clearLine := "\033[2K\r" // ANSI 转义序列,用于清除当前行 + for { + var commandBuilder strings.Builder + for { + b, err := reader.ReadByte() + if err != nil { + return + } + if b == '\n' || b == '\r' { + break + } + if b == '\xff' || b == '\xfe' || b == '\x01' { + continue + } + if b == 127 { // 处理退格键 + if commandBuilder.Len() > 0 { + // 手动截断字符串 + command := commandBuilder.String() + command = command[:len(command)-1] + commandBuilder.Reset() + commandBuilder.WriteString(command) + writer.WriteString("\b \b") // 回显退格 + writer.Flush() + } + } else { + // 回显用户输入的字符 + writer.WriteByte(b) + writer.Flush() + commandBuilder.WriteByte(b) + } + } + command := strings.TrimSpace(commandBuilder.String()) + + // 处理其他命令 + switch command { + case "hello": + writer.WriteString("\r\nHello, world!\r\n") + case "time": + writer.WriteString(fmt.Sprintf("\r\nCurrent time: %s\r\n", time.Now().Format(time.RFC1123))) + case "exit", "quit": + writer.WriteString("\r\nGoodbye!\r\n") + writer.Flush() + return + case "": + default: + writer.WriteString("\r\nUnknown command\r\n") + writer.Flush() + } + writer.WriteString(clearLine + header) + writer.Flush() + } +} + func handleSSHConnection(conn net.Conn, serverConfig *ssh.ServerConfig) { // SSH握手 sshConn, chans, reqs, err := ssh.NewServerConn(conn, serverConfig) @@ -141,13 +370,16 @@ func handleSSHConnection(conn net.Conn, serverConfig *ssh.ServerConfig) { continue } - connNum++ - if connNum > int(conf.Sshd.MaxConnNum) { + sshMu.Lock() + sshCC++ + if sshCC > int(conf.Sshd.MaxConnNum) { + sshMu.Unlock() log.Error("Maximum number of connections exceeded") //conn.Write([]byte("Reach max connections")) conn.Close() continue } + sshMu.Unlock() go handleSSHChannel(conn, sshConn, channel, requests) } @@ -196,8 +428,10 @@ func handleSSHChannel(conn net.Conn, sshConn *ssh.ServerConn, channel ssh.Channe } func closeConnection(conn net.Conn) { + sshMu.Lock() conn.Close() - connNum-- + sshCC-- + sshMu.Unlock() } func handleSSHShell(sshConn *ssh.ServerConn, channel ssh.Channel) { @@ -205,7 +439,7 @@ func handleSSHShell(sshConn *ssh.ServerConn, channel ssh.Channel) { // 检查通道是否支持终端 omcMmlVar := &mmlp.MmlVar{ - Version: "16.1.1", + Version: global.Version, Output: mmlp.DefaultFormatType, MmlHome: conf.Sshd.MmlHome, Limit: 50, @@ -213,9 +447,10 @@ func handleSSHShell(sshConn *ssh.ServerConn, channel ssh.Channel) { SessionToken: fmt.Sprintf("%x", sshConn.SessionID()), HttpUri: conf.OMC.HttpUri, UserAgent: config.GetDefaultUserAgent(), + TagNE: conf.Sshd.TagNE, } - term := term.NewTerminal(channel, fmt.Sprintf("[%s@omc]> ", omcMmlVar.User)) + term := term.NewTerminal(channel, fmt.Sprintf("[%s@%s]> ", omcMmlVar.User, omcMmlVar.TagNE)) // 启动交互式shell会话 for { line, err := term.ReadLine() diff --git a/sshsvc/telnet/telnet.go b/sshsvc/telnet/telnet.go new file mode 100644 index 00000000..28622b44 --- /dev/null +++ b/sshsvc/telnet/telnet.go @@ -0,0 +1,195 @@ +package omctelnet + +import ( + "bufio" + "fmt" + "io" + "net" + "strings" + "sync" + "time" + + "be.ems/lib/dborm" +) + +type TelnetHandler struct { + ListenAddr string + ListenPort uint16 + UserName string + Password string + AuthType string + MaxConnNum uint8 + TagNE string + ListenHost string + + connCount int + mu sync.Mutex +} + +func (t *TelnetHandler) handleTelnetAuth(authType, userName, password string) bool { + switch authType { + case "local": + if userName == t.UserName && password == t.Password { + return true + } + return false + case "radius", "omc": + exist, err := dborm.XEngDB().Table("OMC_PUB.sysUser").Where("userName=? AND password=md5(?)", userName, password).Exist() + if err != nil { + return false + } + return exist + + default: + } + + return false +} + +func (t *TelnetHandler) StartTelnetServer() { + listener, err := net.Listen("tcp", t.ListenHost) + if err != nil { + fmt.Println("Error starting Telnet server:", err) + return + } + defer listener.Close() + fmt.Println("Telnet server started on", t.ListenHost) + + for { + conn, err := listener.Accept() + if err != nil { + fmt.Println("Error accepting Telnet connection:", err) + continue + } + + t.mu.Lock() + if t.connCount >= int(t.MaxConnNum) { + t.mu.Unlock() + io.WriteString(conn, "Connection limit reached. Try again later.\r\n") + conn.Close() + continue + } + t.connCount++ + t.mu.Unlock() + + go t.handleTelnetConnection(conn) + } +} + +func (t *TelnetHandler) handleTelnetConnection(conn net.Conn) { + defer func() { + t.mu.Lock() + t.connCount-- + t.mu.Unlock() + }() + defer conn.Close() + + reader := bufio.NewReader(conn) + writer := bufio.NewWriter(conn) + + // 发送欢迎信息 + writer.WriteString("Welcome to the Telnet server!\r\n") + writer.Flush() + + // 请求用户名 + writer.WriteString("Username: ") + writer.Flush() + user, _ := reader.ReadString('\n') + user = strings.TrimSpace(user) + + // 关闭回显模式 + writer.Write([]byte{255, 251, 1}) // IAC WILL ECHO + writer.Flush() + + // 请求密码 + writer.WriteString("Password: ") + writer.Flush() + + // 读取密码并清除控制序列 + var passBuilder strings.Builder + for { + b, err := reader.ReadByte() + if err != nil { + return + } + if b == '\n' || b == '\r' { + break + } + if b == 255 { // IAC + reader.ReadByte() // 忽略下一个字节 + reader.ReadByte() // 忽略下一个字节 + } else { + passBuilder.WriteByte(b) + } + } + pass := passBuilder.String() + + // 恢复回显模式 + writer.Write([]byte{255, 252, 1}) // IAC WONT ECHO + writer.Flush() + + if t.handleTelnetAuth(t.AuthType, user, pass) { + writer.WriteString("\r\nAuthentication successful!\r\n") + writer.Flush() + t.HandleCommands(user, t.TagNE, reader, writer) + } else { + writer.WriteString("\r\nAuthentication failed!\r\n") + writer.Flush() + } +} + +// 处理命令输 +func (t *TelnetHandler) HandleCommands(user, tag string, reader *bufio.Reader, writer *bufio.Writer) { + header := fmt.Sprintf("[%s@%s]> ", user, tag) + clearLine := "\033[2K\r" // ANSI 转义序列,用于清除当前行 + for { + var commandBuilder strings.Builder + for { + b, err := reader.ReadByte() + if err != nil { + return + } + if b == '\n' || b == '\r' { + break + } + if b == '\xff' || b == '\xfe' || b == '\x01' { + continue + } + if b == 127 { // 处理退格键 + if commandBuilder.Len() > 0 { + // 手动截断字符串 + command := commandBuilder.String() + command = command[:len(command)-1] + commandBuilder.Reset() + commandBuilder.WriteString(command) + writer.WriteString("\b \b") // 回显退格 + writer.Flush() + } + } else { + // 回显用户输入的字符 + writer.WriteByte(b) + writer.Flush() + commandBuilder.WriteByte(b) + } + } + command := strings.TrimSpace(commandBuilder.String()) + + // 处理其他命令 + switch command { + case "hello": + writer.WriteString("\r\nHello, world!\r\n") + case "time": + writer.WriteString(fmt.Sprintf("\r\nCurrent time: %s\r\n", time.Now().Format(time.RFC1123))) + case "exit", "quit": + writer.WriteString("\r\nGoodbye!\r\n") + writer.Flush() + return + case "": + default: + writer.WriteString("\r\nUnknown command\r\n") + writer.Flush() + } + writer.WriteString(clearLine + header) + writer.Flush() + } +}