feat: support ims user, voip auth data and backup UE data
This commit is contained in:
@@ -703,10 +703,11 @@ INSERT INTO `sys_dict_data` VALUES (2192, 2192, 'menu.dashboard.overview.gnbBase
|
|||||||
INSERT INTO `sys_dict_data` VALUES (2193, 2193, 'menu.dashboard.overview.enbBase', '展示4G基站在线信息', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (2193, 2193, 'menu.dashboard.overview.enbBase', '展示4G基站在线信息', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (2194, 2194, 'menu.ueUser.imsUDM', 'IMS签约用户', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (2194, 2194, 'menu.ueUser.imsUDM', 'IMS签约用户', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (2195, 2195, 'menu.ueUser.imsUDMRemark', 'IMS签约用户菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (2195, 2195, 'menu.ueUser.imsUDMRemark', 'IMS签约用户菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (2196, 2196, 'menu.ueUser.voipUDM', 'VoIP签约用户', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (2196, 2196, 'menu.ueUser.voipUDM', 'VoIP鉴权数据', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (2197, 2197, 'menu.ueUser.voipUDMRemark', 'VoIP签约用户菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (2197, 2197, 'menu.ueUser.voipUDMRemark', 'VoIP鉴权数据菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (2198, 2198, 'menu.ueUser.exportFile', '导出文件管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (2198, 2198, 'menu.ueUser.exportFile', '导出文件管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (2199, 2199, 'menu.ueUser.exportFileRemark', '导出文件管理菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (2199, 2199, 'menu.ueUser.exportFileRemark', '导出文件管理菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT INTO `sys_dict_data` VALUES (2200, 2200, 'job.backup.ue.data', '定期从UE用户和数据表导出文件至指定目录', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
-- multi-tenancy
|
-- multi-tenancy
|
||||||
INSERT INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
INSERT INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||||
|
|||||||
@@ -703,10 +703,11 @@ INSERT INTO `sys_dict_data` VALUES (4192, 4192, 'menu.dashboard.overview.gnbBase
|
|||||||
INSERT INTO `sys_dict_data` VALUES (4193, 4193, 'menu.dashboard.overview.enbBase', 'Display 4G base station online information', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (4193, 4193, 'menu.dashboard.overview.enbBase', 'Display 4G base station online information', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (4194, 4194, 'menu.ueUser.imsUDM', 'IMS Subscribers', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (4194, 4194, 'menu.ueUser.imsUDM', 'IMS Subscribers', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (4195, 4195, 'menu.ueUser.imsUDMRemark', 'IMS Subscribers Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (4195, 4195, 'menu.ueUser.imsUDMRemark', 'IMS Subscribers Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (4196, 4196, 'menu.ueUser.voipUDM', 'VoIP Subscribers', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (4196, 4196, 'menu.ueUser.voipUDM', 'VoIP Authentication', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (4197, 4197, 'menu.ueUser.voipUDMRemark', 'VoIP Subscribers Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (4197, 4197, 'menu.ueUser.voipUDMRemark', 'VoIP Authentication Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (4198, 4198, 'menu.ueUser.exportFile', 'Exported File Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (4198, 4198, 'menu.ueUser.exportFile', 'Exported File Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
INSERT INTO `sys_dict_data` VALUES (4199, 4199, 'menu.ueUser.exportFileRemark', 'Exported File Management Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (4199, 4199, 'menu.ueUser.exportFileRemark', 'Exported File Management Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
INSERT INTO `sys_dict_data` VALUES (4200, 4200, 'job.backup.ue.data', 'Regularly export files from UE users and data tables to a specified directory', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
-- 多租户
|
-- 多租户
|
||||||
INSERT INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
INSERT INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ INSERT INTO `sys_job` VALUES (11, 'job.exportOperateLog', 'SYSTEM', 'exportTable
|
|||||||
INSERT INTO `sys_job` VALUES (12, 'job.exportIMSCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_ims\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callType\')) as call_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as call_duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as service_result,DATE_FORMAT(FROM_UNIXTIME(timestamp), \'%Y-%m-%d %H:%i:%s\') AS timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/ims_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1722224659251, '');
|
INSERT INTO `sys_job` VALUES (12, 'job.exportIMSCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_ims\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callType\')) as call_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as call_duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as service_result,DATE_FORMAT(FROM_UNIXTIME(timestamp), \'%Y-%m-%d %H:%i:%s\') AS timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/ims_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1722224659251, '');
|
||||||
INSERT INTO `sys_job` VALUES (13, 'job.exportSMFCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smf\",\"columns\":\"id,ne_type,ne_name,rm_uid,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) AS record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) AS charging_id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDType\')) AS subscriber_id_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDData\')) AS subscriber_id_data,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) AS duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.invocationTimestamp\')) as invocationTimestamp,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink\')) AS data_volume_uplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink\')) AS data_volume_downlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume\')) AS data_total_volume,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.pDUSessionChargingInformation.pDUAddress.pDUIPv4Address\')) AS pdu_ipv4_address,timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smf_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
INSERT INTO `sys_job` VALUES (13, 'job.exportSMFCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smf\",\"columns\":\"id,ne_type,ne_name,rm_uid,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) AS record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) AS charging_id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDType\')) AS subscriber_id_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDData\')) AS subscriber_id_data,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) AS duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.invocationTimestamp\')) as invocationTimestamp,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink\')) AS data_volume_uplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink\')) AS data_volume_downlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume\')) AS data_total_volume,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.pDUSessionChargingInformation.pDUAddress.pDUIPv4Address\')) AS pdu_ipv4_address,timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smf_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
||||||
INSERT INTO `sys_job` VALUES (14, 'job.exportSMSCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smsc\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceType\')) as service_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.result\')) as result,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.updateTime\')) as update_time\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smsc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
INSERT INTO `sys_job` VALUES (14, 'job.exportSMSCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smsc\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceType\')) as service_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.result\')) as result,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.updateTime\')) as update_time\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smsc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
||||||
INSERT INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/operate_log\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/ims_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smf_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smsc_cdr\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, '');
|
INSERT INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/operate_log\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/ims_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smf_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smsc_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_auth_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_sub_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_voip_auth\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_ims_user\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, '');
|
||||||
INSERT INTO `sys_job` VALUES (16, 'job.exportSGWCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_sgwc\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.accessPointNameNI\')) as accessPointNameNI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedIMSI\')) as IMSI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedMSISDN\')) as MSISDN,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedPDPPDNAddress\')) as PdpAddress,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) as duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordOpeningTime\')) as recordOpeningTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) as chargingID,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRSDownlink\')) AS dataVolumeGPRSDownlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRsUplink\')) as dataVolumeGPRsUplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.tai.tac\')) as tac,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.ecgi.eutraCellId\')) as cellID\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/sgwc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
INSERT INTO `sys_job` VALUES (16, 'job.exportSGWCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_sgwc\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.accessPointNameNI\')) as accessPointNameNI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedIMSI\')) as IMSI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedMSISDN\')) as MSISDN,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedPDPPDNAddress\')) as PdpAddress,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) as duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordOpeningTime\')) as recordOpeningTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) as chargingID,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRSDownlink\')) AS dataVolumeGPRSDownlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRsUplink\')) as dataVolumeGPRsUplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.tai.tac\')) as tac,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.ecgi.eutraCellId\')) as cellID\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/sgwc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
||||||
|
INSERT INTO `sys_job` VALUES (17, 'job.backup.ue.data', 'SYSTEM', 'exportUEData', '[{\"tableName\":\"u_auth_user\",\"columns\":\"imsi,ki,algo,amf,opc\",\"extras\":\"\",\"serviceName\":\"UDMAuthUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_auth_user\"},{\"tableName\":\"u_sub_user\",\"columns\":\"imsi,msisdn,ambr,nssai,arfb,sar,rat,cn_type,smf_sel,sm_data,eps_flag,eps_odb,hplmn_odb,ard,epstpl,context_id,apn_context,static_ip\",\"extras\":\"\",\"serviceName\":\"UDMSubUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_sub_user\"},{\"tableName\":\"u_voip_auth\",\"columns\":\"user_name,password\",\"extras\":\"\",\"serviceName\":\"UDMVoIPAuth\",\"orderBy\":\"user_name\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_voip_auth\"},{\"tableName\":\"u_ims_user\",\"columns\":\"imsi,msisdn,volte,vni\",\"extras\":\"\",\"serviceName\":\"UDMIMSUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_ims_user\"}]', '0 35 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1743479268652, '');
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|||||||
@@ -129,8 +129,8 @@ INSERT INTO `sys_menu` VALUES (1055, 'menu.common.edit', 116, 5, '#', NULL, '1',
|
|||||||
INSERT INTO `sys_menu` VALUES (1056, 'menu.common.export', 116, 6, '#', NULL, '1', '1', 'B', '1', '1', 'monitor:job:export', '#', 'supervisor', 1700000000000, NULL, 0, NULL);
|
INSERT INTO `sys_menu` VALUES (1056, 'menu.common.export', 116, 6, '#', NULL, '1', '1', 'B', '1', '1', 'monitor:job:export', '#', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||||
INSERT INTO `sys_menu` VALUES (2009, 'menu.ueUser.authUDM', 5, 1, 'auth', 'neUser/auth/index', '1', '1', 'M', '1', '1', 'neUser:auth:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.authUDMRemark');
|
INSERT INTO `sys_menu` VALUES (2009, 'menu.ueUser.authUDM', 5, 1, 'auth', 'neUser/auth/index', '1', '1', 'M', '1', '1', 'neUser:auth:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.authUDMRemark');
|
||||||
INSERT INTO `sys_menu` VALUES (2010, 'menu.ueUser.subUDM', 5, 2, 'sub', 'neUser/sub/index', '1', '1', 'M', '1', '1', 'neUser:sub:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.subUDMRemark');
|
INSERT INTO `sys_menu` VALUES (2010, 'menu.ueUser.subUDM', 5, 2, 'sub', 'neUser/sub/index', '1', '1', 'M', '1', '1', 'neUser:sub:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.subUDMRemark');
|
||||||
INSERT INTO `sys_menu` VALUES (2011, 'menu.ueUser.imsUDM', 5, 3, 'imsUDM', 'neUser/imsUDM/index', '1', '1', 'M', '1', '1', 'neUser:imsUDM:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.imsUDMRemark');
|
INSERT INTO `sys_menu` VALUES (2011, 'menu.ueUser.voipUDM', 5, 3, 'voip', 'neUser/voip/index', '1', '1', 'M', '1', '1', 'neUser:voip:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.voipUDMRemark');
|
||||||
INSERT INTO `sys_menu` VALUES (2012, 'menu.ueUser.voipUDM', 5, 4, 'voip', 'neUser/voip/index', '1', '1', 'M', '1', '1', 'neUser:voip:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.voipUDMRemark');
|
INSERT INTO `sys_menu` VALUES (2012, 'menu.ueUser.imsUDM', 5, 4, 'imsUDM', 'neUser/imsUDM/index', '1', '1', 'M', '1', '1', 'neUser:imsUDM:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.imsUDMRemark');
|
||||||
INSERT INTO `sys_menu` VALUES (2079, 'menu.ueUser.exportFile', 5, 20, 'exportFile', 'neUser/exportFile/index', '1', '1', 'M', '1', '1', 'neUser:exportFile:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.exportFileRemark');
|
INSERT INTO `sys_menu` VALUES (2079, 'menu.ueUser.exportFile', 5, 20, 'exportFile', 'neUser/exportFile/index', '1', '1', 'M', '1', '1', 'neUser:exportFile:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.exportFileRemark');
|
||||||
-- INSERT INTO `sys_menu` VALUES (2075, 'menu.config.neManage', 4, 1, 'neManage', 'configManage/neManage/index', '1', '0', 'M', '1', '0', 'configManage:neManage:index', 'icon-biaoqing', 'supervisor', 1700000000000, NULL, 0, 'menu.config.neManageRemark');
|
-- INSERT INTO `sys_menu` VALUES (2075, 'menu.config.neManage', 4, 1, 'neManage', 'configManage/neManage/index', '1', '0', 'M', '1', '0', 'configManage:neManage:index', 'icon-biaoqing', 'supervisor', 1700000000000, NULL, 0, 'menu.config.neManageRemark');
|
||||||
-- INSERT INTO `sys_menu` VALUES (2078, 'menu.config.backupManage', 4, 100, 'backupManage', 'configManage/backupManage/index', '1', '0', 'M', '1', '0', 'configManage:backupManage:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.config.backupManageRemark');
|
-- INSERT INTO `sys_menu` VALUES (2078, 'menu.config.backupManage', 4, 100, 'backupManage', 'configManage/backupManage/index', '1', '0', 'M', '1', '0', 'configManage:backupManage:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.config.backupManageRemark');
|
||||||
|
|||||||
36
database/install/u_ims_user.sql
Executable file
36
database/install/u_ims_user.sql
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
Navicat Premium Data Transfer
|
||||||
|
|
||||||
|
Source Server : omc@192.168.2.211
|
||||||
|
Source Server Type : MariaDB
|
||||||
|
Source Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2)
|
||||||
|
Source Host : 192.168.2.211:33066
|
||||||
|
Source Schema : tenants_db
|
||||||
|
|
||||||
|
Target Server Type : MariaDB
|
||||||
|
Target Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2)
|
||||||
|
File Encoding : 65001
|
||||||
|
|
||||||
|
Date: 09/04/2025 09:22:00
|
||||||
|
*/
|
||||||
|
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for u_ims_user
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `u_ims_user`;
|
||||||
|
CREATE TABLE `u_ims_user` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
`imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM/USIMID',
|
||||||
|
`msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
|
||||||
|
`volte` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
|
||||||
|
`vni` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
|
||||||
|
`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 `uk_imsi_ne`(`imsi`, `ne_id`) USING BTREE COMMENT 'imsi_neid'
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
34
database/install/u_voip_auth.sql
Executable file
34
database/install/u_voip_auth.sql
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
Navicat Premium Data Transfer
|
||||||
|
|
||||||
|
Source Server : omc@192.168.2.211
|
||||||
|
Source Server Type : MariaDB
|
||||||
|
Source Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2)
|
||||||
|
Source Host : 192.168.2.211:33066
|
||||||
|
Source Schema : tenants_db
|
||||||
|
|
||||||
|
Target Server Type : MariaDB
|
||||||
|
Target Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2)
|
||||||
|
File Encoding : 65001
|
||||||
|
|
||||||
|
Date: 09/04/2025 09:26:02
|
||||||
|
*/
|
||||||
|
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for u_voip_auth
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `u_voip_auth`;
|
||||||
|
CREATE TABLE `u_voip_auth` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
`user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
`password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
|
||||||
|
`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,
|
||||||
|
INDEX `idx_user_name`(`user_name`) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
@@ -710,10 +710,11 @@ REPLACE INTO `sys_dict_data` VALUES (2192, 2192, 'menu.dashboard.overview.gnbBas
|
|||||||
REPLACE INTO `sys_dict_data` VALUES (2193, 2193, 'menu.dashboard.overview.enbBase', '展示4G基站在线信息', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (2193, 2193, 'menu.dashboard.overview.enbBase', '展示4G基站在线信息', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (2194, 2194, 'menu.ueUser.imsUDM', 'IMS签约用户', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (2194, 2194, 'menu.ueUser.imsUDM', 'IMS签约用户', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (2195, 2195, 'menu.ueUser.imsUDMRemark', 'IMS签约用户菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (2195, 2195, 'menu.ueUser.imsUDMRemark', 'IMS签约用户菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (2196, 2196, 'menu.ueUser.voipUDM', 'VoIP签约用户', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (2196, 2196, 'menu.ueUser.voipUDM', 'VoIP鉴权数据', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (2197, 2197, 'menu.ueUser.voipUDMRemark', 'VoIP签约用户菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (2197, 2197, 'menu.ueUser.voipUDMRemark', 'VoIP鉴权数据菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (2198, 2198, 'menu.ueUser.exportFile', '导出文件管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (2198, 2198, 'menu.ueUser.exportFile', '导出文件管理', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (2199, 2199, 'menu.ueUser.exportFileRemark', '导出文件管理菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (2199, 2199, 'menu.ueUser.exportFileRemark', '导出文件管理菜单', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
REPLACE INTO `sys_dict_data` VALUES (2200, 2200, 'job.backup.ue.data', '定期备份UE用户和数据表', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
-- multi-tenancy
|
-- multi-tenancy
|
||||||
REPLACE INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
REPLACE INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||||
|
|||||||
@@ -709,10 +709,11 @@ REPLACE INTO `sys_dict_data` VALUES (4192, 4192, 'menu.dashboard.overview.gnbBas
|
|||||||
REPLACE INTO `sys_dict_data` VALUES (4193, 4193, 'menu.dashboard.overview.enbBase', 'Display 4G base station online information', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (4193, 4193, 'menu.dashboard.overview.enbBase', 'Display 4G base station online information', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (4194, 4194, 'menu.ueUser.imsUDM', 'IMS Subscribers', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (4194, 4194, 'menu.ueUser.imsUDM', 'IMS Subscribers', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (4195, 4195, 'menu.ueUser.imsUDMRemark', 'IMS Subscribers Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (4195, 4195, 'menu.ueUser.imsUDMRemark', 'IMS Subscribers Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (4196, 4196, 'menu.ueUser.voipUDM', 'VoIP Subscribers', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (4196, 4196, 'menu.ueUser.voipUDM', 'VoIP Authentication', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (4197, 4197, 'menu.ueUser.voipUDMRemark', 'VoIP Subscribers Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (4197, 4197, 'menu.ueUser.voipUDMRemark', 'VoIP Authentication Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (4198, 4198, 'menu.ueUser.exportFile', 'Exported File Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (4198, 4198, 'menu.ueUser.exportFile', 'Exported File Management', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
REPLACE INTO `sys_dict_data` VALUES (4199, 4199, 'menu.ueUser.exportFileRemark', 'Exported File Management Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (4199, 4199, 'menu.ueUser.exportFileRemark', 'Exported File Management Menu', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
REPLACE INTO `sys_dict_data` VALUES (4200, 4200, 'job.backup.ue.data', 'Backup regularly UE users and data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, '');
|
||||||
|
|
||||||
-- 多租户
|
-- 多租户
|
||||||
REPLACE INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
REPLACE INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ REPLACE INTO `sys_job` VALUES (11, 'job.exportOperateLog', 'SYSTEM', 'exportTabl
|
|||||||
REPLACE INTO `sys_job` VALUES (12, 'job.exportIMSCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_ims\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callType\')) as call_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as call_duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as service_result,DATE_FORMAT(FROM_UNIXTIME(timestamp), \'%Y-%m-%d %H:%i:%s\') AS timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/ims_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1722224659251, '');
|
REPLACE INTO `sys_job` VALUES (12, 'job.exportIMSCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_ims\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callType\')) as call_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as call_duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as service_result,DATE_FORMAT(FROM_UNIXTIME(timestamp), \'%Y-%m-%d %H:%i:%s\') AS timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/ims_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1722224659251, '');
|
||||||
REPLACE INTO `sys_job` VALUES (13, 'job.exportSMFCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smf\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) AS record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) AS charging_id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDType\')) AS subscriber_id_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDData\')) AS subscriber_id_data,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) AS duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.invocationTimestamp\')) as invocationTimestamp,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink\')) AS data_volume_uplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink\')) AS data_volume_downlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume\')) AS data_total_volume,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.pDUSessionChargingInformation.pDUAddress.pDUIPv4Address\')) AS pdu_ipv4_address,timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smf_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
REPLACE INTO `sys_job` VALUES (13, 'job.exportSMFCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smf\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) AS record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) AS charging_id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDType\')) AS subscriber_id_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDData\')) AS subscriber_id_data,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) AS duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.invocationTimestamp\')) as invocationTimestamp,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink\')) AS data_volume_uplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink\')) AS data_volume_downlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume\')) AS data_total_volume,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.pDUSessionChargingInformation.pDUAddress.pDUIPv4Address\')) AS pdu_ipv4_address,timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smf_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
||||||
REPLACE INTO `sys_job` VALUES (14, 'job.exportSMSCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smsc\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceType\')) as service_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.result\')) as result,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.updateTime\')) as update_time\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smsc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
REPLACE INTO `sys_job` VALUES (14, 'job.exportSMSCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smsc\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceType\')) as service_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.result\')) as result,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.updateTime\')) as update_time\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smsc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
||||||
REPLACE INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/operate_log\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/ims_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smf_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smsc_cdr\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, '');
|
REPLACE INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/operate_log\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/ims_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smf_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smsc_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_auth_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_sub_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_voip_auth\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_ims_user\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, '');
|
||||||
REPLACE INTO `sys_job` VALUES (16, 'job.exportSGWCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_sgwc\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.accessPointNameNI\')) as accessPointNameNI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedIMSI\')) as IMSI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedMSISDN\')) as MSISDN,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedPDPPDNAddress\')) as PdpAddress,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) as duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordOpeningTime\')) as recordOpeningTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) as chargingID,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRSDownlink\')) AS dataVolumeGPRSDownlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRsUplink\')) as dataVolumeGPRsUplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.tai.tac\')) as tac,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.ecgi.eutraCellId\')) as cellID\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/sgwc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
REPLACE INTO `sys_job` VALUES (16, 'job.exportSGWCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_sgwc\",\"columns\":\"id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.accessPointNameNI\')) as accessPointNameNI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedIMSI\')) as IMSI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedMSISDN\')) as MSISDN,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedPDPPDNAddress\')) as PdpAddress,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) as duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordOpeningTime\')) as recordOpeningTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) as chargingID,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRSDownlink\')) AS dataVolumeGPRSDownlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRsUplink\')) as dataVolumeGPRsUplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.tai.tac\')) as tac,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.ecgi.eutraCellId\')) as cellID\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/sgwc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, '');
|
||||||
|
REPLACE INTO `sys_job` VALUES (17, 'job.backup.ue.data', 'SYSTEM', 'exportUEData', '[{\"tableName\":\"u_auth_user\",\"columns\":\"imsi,ki,algo,amf,opc\",\"extras\":\"\",\"serviceName\":\"UDMAuthUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_auth_user\"},{\"tableName\":\"u_sub_user\",\"columns\":\"imsi,msisdn,ambr,nssai,arfb,sar,rat,cn_type,smf_sel,sm_data,eps_flag,eps_odb,hplmn_odb,ard,epstpl,context_id,apn_context,static_ip\",\"extras\":\"\",\"serviceName\":\"UDMSubUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_sub_user\"},{\"tableName\":\"u_voip_auth\",\"columns\":\"user_name,password\",\"extras\":\"\",\"serviceName\":\"UDMVoIPAuth\",\"orderBy\":\"user_name\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_voip_auth\"},{\"tableName\":\"u_ims_user\",\"columns\":\"imsi,msisdn,volte,vni\",\"extras\":\"\",\"serviceName\":\"UDMIMSUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_ims_user\"}]', '0 35 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1743479268652, '');
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
@@ -112,8 +112,8 @@ REPLACE INTO `sys_menu` VALUES (1055, 'menu.common.edit', 116, 5, '#', NULL, '1'
|
|||||||
REPLACE INTO `sys_menu` VALUES (1056, 'menu.common.export', 116, 6, '#', NULL, '1', '1', 'B', '1', '1', 'monitor:job:export', '#', 'supervisor', 1700000000000, NULL, 0, NULL);
|
REPLACE INTO `sys_menu` VALUES (1056, 'menu.common.export', 116, 6, '#', NULL, '1', '1', 'B', '1', '1', 'monitor:job:export', '#', 'supervisor', 1700000000000, NULL, 0, NULL);
|
||||||
REPLACE INTO `sys_menu` VALUES (2009, 'menu.ueUser.authUDM', 5, 1, 'auth', 'neUser/auth/index', '1', '1', 'M', '1', '1', 'neUser:auth:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.authUDMRemark');
|
REPLACE INTO `sys_menu` VALUES (2009, 'menu.ueUser.authUDM', 5, 1, 'auth', 'neUser/auth/index', '1', '1', 'M', '1', '1', 'neUser:auth:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.authUDMRemark');
|
||||||
REPLACE INTO `sys_menu` VALUES (2010, 'menu.ueUser.subUDM', 5, 2, 'sub', 'neUser/sub/index', '1', '1', 'M', '1', '1', 'neUser:sub:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.subUDMRemark');
|
REPLACE INTO `sys_menu` VALUES (2010, 'menu.ueUser.subUDM', 5, 2, 'sub', 'neUser/sub/index', '1', '1', 'M', '1', '1', 'neUser:sub:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.subUDMRemark');
|
||||||
REPLACE INTO `sys_menu` VALUES (2011, 'menu.ueUser.imsUDM', 5, 3, 'imsUDM', 'neUser/imsUDM/index', '1', '1', 'M', '1', '1', 'neUser:imsUDM:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.imsUDMRemark');
|
REPLACE INTO `sys_menu` VALUES (2011, 'menu.ueUser.voipUDM', 5, 3, 'voip', 'neUser/voip/index', '1', '1', 'M', '1', '1', 'neUser:voip:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.voipUDMRemark');
|
||||||
REPLACE INTO `sys_menu` VALUES (2012, 'menu.ueUser.voipUDM', 5, 4, 'voip', 'neUser/voip/index', '1', '1', 'M', '1', '1', 'neUser:voip:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.voipUDMRemark');
|
REPLACE INTO `sys_menu` VALUES (2012, 'menu.ueUser.imsUDM', 5, 4, 'imsUDM', 'neUser/imsUDM/index', '1', '1', 'M', '1', '1', 'neUser:imsUDM:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.imsUDMRemark');
|
||||||
REPLACE INTO `sys_menu` VALUES (2079, 'menu.ueUser.exportFile', 5, 20, 'exportFile', 'neUser/exportFile/index', '1', '1', 'M', '1', '1', 'neUser:exportFile:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.exportFileRemark');
|
REPLACE INTO `sys_menu` VALUES (2079, 'menu.ueUser.exportFile', 5, 20, 'exportFile', 'neUser/exportFile/index', '1', '1', 'M', '1', '1', 'neUser:exportFile:index', 'icon-xiangmuchengyuan', 'supervisor', 1700000000000, NULL, 0, 'menu.ueUser.exportFileRemark');
|
||||||
-- REPLACE INTO `sys_menu` VALUES (2075, 'menu.config.neManage', 4, 1, 'neManage', 'configManage/neManage/index', '1', '0', 'M', '1', '0', 'configManage:neManage:index', 'icon-biaoqing', 'supervisor', 1700000000000, NULL, 0, 'menu.config.neManageRemark');
|
-- REPLACE INTO `sys_menu` VALUES (2075, 'menu.config.neManage', 4, 1, 'neManage', 'configManage/neManage/index', '1', '0', 'M', '1', '0', 'configManage:neManage:index', 'icon-biaoqing', 'supervisor', 1700000000000, NULL, 0, 'menu.config.neManageRemark');
|
||||||
-- REPLACE INTO `sys_menu` VALUES (2078, 'menu.config.backupManage', 4, 100, 'backupManage', 'configManage/backupManage/index', '1', '0', 'M', '1', '0', 'configManage:backupManage:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.config.backupManageRemark');
|
-- REPLACE INTO `sys_menu` VALUES (2078, 'menu.config.backupManage', 4, 100, 'backupManage', 'configManage/backupManage/index', '1', '0', 'M', '1', '0', 'configManage:backupManage:index', 'icon-soutubiao', 'supervisor', 1700000000000, NULL, 0, 'menu.config.backupManageRemark');
|
||||||
|
|||||||
35
database/upgrade/upg_u_ims_user.sql
Executable file
35
database/upgrade/upg_u_ims_user.sql
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
Navicat Premium Data Transfer
|
||||||
|
|
||||||
|
Source Server : omc@192.168.2.211
|
||||||
|
Source Server Type : MariaDB
|
||||||
|
Source Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2)
|
||||||
|
Source Host : 192.168.2.211:33066
|
||||||
|
Source Schema : tenants_db
|
||||||
|
|
||||||
|
Target Server Type : MariaDB
|
||||||
|
Target Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2)
|
||||||
|
File Encoding : 65001
|
||||||
|
|
||||||
|
Date: 09/04/2025 09:22:00
|
||||||
|
*/
|
||||||
|
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for u_ims_user
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `u_ims_user` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
`imsi` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'SIM/USIMID',
|
||||||
|
`msisdn` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
|
||||||
|
`volte` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
|
||||||
|
`vni` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
|
||||||
|
`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 `uk_imsi_ne`(`imsi`, `ne_id`) USING BTREE COMMENT 'imsi_neid'
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
33
database/upgrade/upg_u_voip_auth.sql
Executable file
33
database/upgrade/upg_u_voip_auth.sql
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Navicat Premium Data Transfer
|
||||||
|
|
||||||
|
Source Server : omc@192.168.2.211
|
||||||
|
Source Server Type : MariaDB
|
||||||
|
Source Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2)
|
||||||
|
Source Host : 192.168.2.211:33066
|
||||||
|
Source Schema : tenants_db
|
||||||
|
|
||||||
|
Target Server Type : MariaDB
|
||||||
|
Target Server Version : 100621 (10.6.21-MariaDB-0ubuntu0.22.04.2)
|
||||||
|
File Encoding : 65001
|
||||||
|
|
||||||
|
Date: 09/04/2025 09:26:56
|
||||||
|
*/
|
||||||
|
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for u_voip_auth
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `u_voip_auth` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`ne_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
`user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
`password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
|
||||||
|
`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,
|
||||||
|
INDEX `idx_user_name`(`user_name`) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 19570 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'UDM' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
25
features/ue/api.go
Normal file
25
features/ue/api.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// log management package
|
||||||
|
|
||||||
|
package ue
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "be.ems/features/ue/file_export"
|
||||||
|
// "be.ems/features/ue/ims_user"
|
||||||
|
"be.ems/features/ue/api"
|
||||||
|
"be.ems/lib/log"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitSubServiceRoute(r *gin.Engine) {
|
||||||
|
log.Info("======init UE management group gin.Engine")
|
||||||
|
|
||||||
|
ueGroup := r.Group("/ue")
|
||||||
|
// register sub modules routes
|
||||||
|
// file_export.Register(ueGroup)
|
||||||
|
// ims_user.Register(ueGroup)
|
||||||
|
api.UDMIMSUserRegister(ueGroup)
|
||||||
|
api.FileExportRegister(ueGroup)
|
||||||
|
api.VoIPAuthRegister(ueGroup)
|
||||||
|
// register other sub modules routes
|
||||||
|
}
|
||||||
|
|
||||||
40
features/ue/api/file_export.go
Normal file
40
features/ue/api/file_export.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"be.ems/src/framework/middleware"
|
||||||
|
"be.ems/features/ue/controller"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Register Routes for file_export
|
||||||
|
func FileExportRegister(r *gin.RouterGroup) {
|
||||||
|
|
||||||
|
ueTable := r.Group("/table")
|
||||||
|
{
|
||||||
|
var m *controller.FileSource
|
||||||
|
ueTable.GET("/list",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
m.GetFileExportTable,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ueFile := r.Group("/file")
|
||||||
|
{
|
||||||
|
var f *controller.FileExport
|
||||||
|
ueFile.GET("/list",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
f.GetFileList,
|
||||||
|
)
|
||||||
|
ueFile.GET("/total",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
f.Total,
|
||||||
|
)
|
||||||
|
ueFile.GET("/:fileName",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
f.DownloadHandler,
|
||||||
|
)
|
||||||
|
ueFile.DELETE("/:fileName",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
f.Delete,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
68
features/ue/api/ims_user.go
Normal file
68
features/ue/api/ims_user.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"be.ems/src/framework/middleware"
|
||||||
|
"be.ems/src/framework/middleware/collectlogs"
|
||||||
|
"be.ems/src/framework/middleware/repeat"
|
||||||
|
"be.ems/features/ue/controller"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Description Register Routes for ims_user
|
||||||
|
func UDMIMSUserRegister(r *gin.RouterGroup) {
|
||||||
|
|
||||||
|
udmIMSUserGroup := r.Group("/udm/imsuser")
|
||||||
|
{
|
||||||
|
udmIMSUserGroup.PUT("/resetData/:neId",
|
||||||
|
repeat.RepeatSubmit(5),
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmIMSUser", collectlogs.BUSINESS_TYPE_CLEAN)),
|
||||||
|
controller.NewIMSUserController.ResetData,
|
||||||
|
)
|
||||||
|
udmIMSUserGroup.GET("/list",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
controller.NewIMSUserController.List,
|
||||||
|
)
|
||||||
|
udmIMSUserGroup.GET("/:neId/:imsi",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
controller.NewIMSUserController.Info,
|
||||||
|
)
|
||||||
|
udmIMSUserGroup.POST("/:neId",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmIMSUser", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||||
|
controller.NewIMSUserController.Add,
|
||||||
|
)
|
||||||
|
udmIMSUserGroup.POST("/:neId/:num",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmIMSUser", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||||
|
controller.NewIMSUserController.Adds,
|
||||||
|
)
|
||||||
|
udmIMSUserGroup.PUT("/:neId",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmIMSUser", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||||
|
controller.NewIMSUserController.Edit,
|
||||||
|
)
|
||||||
|
udmIMSUserGroup.DELETE("/:neId/:imsi",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmIMSUser", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||||
|
controller.NewIMSUserController.Remove,
|
||||||
|
)
|
||||||
|
udmIMSUserGroup.DELETE("/:neId/:imsi/:num",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmIMSUser", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||||
|
controller.NewIMSUserController.Removes,
|
||||||
|
)
|
||||||
|
udmIMSUserGroup.POST("/export",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmIMSUser", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||||
|
controller.NewIMSUserController.Export,
|
||||||
|
)
|
||||||
|
udmIMSUserGroup.POST("/import",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.udmIMSUser", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||||
|
controller.NewIMSUserController.Import,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
68
features/ue/api/voip_auth.go
Normal file
68
features/ue/api/voip_auth.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"be.ems/src/framework/middleware"
|
||||||
|
"be.ems/src/framework/middleware/collectlogs"
|
||||||
|
"be.ems/src/framework/middleware/repeat"
|
||||||
|
"be.ems/features/ue/controller"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Description Register Routes for ims_user
|
||||||
|
func VoIPAuthRegister(r *gin.RouterGroup) {
|
||||||
|
|
||||||
|
voipAuthGroup := r.Group("/udm/voipauth")
|
||||||
|
{
|
||||||
|
voipAuthGroup.PUT("/resetData/:neId",
|
||||||
|
repeat.RepeatSubmit(5),
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.voipAuth", collectlogs.BUSINESS_TYPE_CLEAN)),
|
||||||
|
controller.NewVoIPAuthController.ResetData,
|
||||||
|
)
|
||||||
|
voipAuthGroup.GET("/list",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
controller.NewVoIPAuthController.List,
|
||||||
|
)
|
||||||
|
voipAuthGroup.GET("/:neId/:userName",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
controller.NewVoIPAuthController.Info,
|
||||||
|
)
|
||||||
|
voipAuthGroup.POST("/:neId",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.voipAuth", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||||
|
controller.NewVoIPAuthController.Add,
|
||||||
|
)
|
||||||
|
voipAuthGroup.POST("/:neId/:num",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.voipAuth", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||||
|
controller.NewVoIPAuthController.Adds,
|
||||||
|
)
|
||||||
|
voipAuthGroup.PUT("/:neId",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.voipAuth", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||||
|
controller.NewVoIPAuthController.Edit,
|
||||||
|
)
|
||||||
|
voipAuthGroup.DELETE("/:neId/:userName",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.voipAuth", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||||
|
controller.NewVoIPAuthController.Remove,
|
||||||
|
)
|
||||||
|
voipAuthGroup.DELETE("/:neId/:userName/:num",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.voipAuth", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||||
|
controller.NewVoIPAuthController.Removes,
|
||||||
|
)
|
||||||
|
voipAuthGroup.POST("/export",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.voipAuth", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||||
|
controller.NewVoIPAuthController.Export,
|
||||||
|
)
|
||||||
|
voipAuthGroup.POST("/import",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.voipAuth", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||||
|
controller.NewVoIPAuthController.Import,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
95
features/ue/controller/file_export.go
Normal file
95
features/ue/controller/file_export.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"be.ems/lib/file"
|
||||||
|
"be.ems/lib/log"
|
||||||
|
"be.ems/lib/services"
|
||||||
|
"be.ems/features/ue/model"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileExport struct {
|
||||||
|
file.FileInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FileExport) GetFileList(c *gin.Context) {
|
||||||
|
var querys model.FileExportQuery
|
||||||
|
|
||||||
|
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||||
|
c.JSON(http.StatusOK, services.ErrResp(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
files, err := file.GetFileInfo(querys.Path, querys.Suffix)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to GetFileInfo:", err)
|
||||||
|
c.JSON(http.StatusOK, services.ErrResp(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// split files list
|
||||||
|
lenNum := int64(len(files))
|
||||||
|
start := (querys.PageNum - 1) * querys.PageSize
|
||||||
|
end := start + querys.PageSize
|
||||||
|
var splitList []file.FileInfo
|
||||||
|
if start >= lenNum {
|
||||||
|
splitList = []file.FileInfo{}
|
||||||
|
} else if end >= lenNum {
|
||||||
|
splitList = files[start:]
|
||||||
|
} else {
|
||||||
|
splitList = files[start:end]
|
||||||
|
}
|
||||||
|
total := len(files)
|
||||||
|
c.JSON(http.StatusOK, services.TotalDataResp(splitList, total))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FileExport) Total(c *gin.Context) {
|
||||||
|
dir := c.Query("path")
|
||||||
|
|
||||||
|
fileCount, dirCount, err := file.GetFileAndDirCount(dir)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to GetFileAndDirCount:", err)
|
||||||
|
c.JSON(http.StatusOK, services.ErrResp(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total := fileCount + dirCount
|
||||||
|
c.JSON(http.StatusOK, services.TotalResp(int64(total)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FileExport) DownloadHandler(c *gin.Context) {
|
||||||
|
dir := c.Query("path")
|
||||||
|
fileName := c.Param("fileName")
|
||||||
|
filePath := filepath.Join(dir, fileName)
|
||||||
|
|
||||||
|
file, err := os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, services.ErrResp(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||||
|
c.JSON(http.StatusOK, services.ErrResp(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Header("Content-Disposition", "attachment; filename="+fileName)
|
||||||
|
c.Header("Content-Type", "application/octet-stream")
|
||||||
|
c.File(filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FileExport) Delete(c *gin.Context) {
|
||||||
|
fileName := c.Param("fileName")
|
||||||
|
dir := c.Query("path")
|
||||||
|
filePath := filepath.Join(dir, fileName)
|
||||||
|
|
||||||
|
if err := os.Remove(filePath); err != nil {
|
||||||
|
c.JSON(http.StatusOK, services.ErrResp(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusNoContent, nil) // 204 No Content
|
||||||
|
}
|
||||||
57
features/ue/controller/file_source.go
Normal file
57
features/ue/controller/file_source.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"be.ems/lib/services"
|
||||||
|
"be.ems/src/framework/datasource"
|
||||||
|
"be.ems/src/framework/i18n"
|
||||||
|
"be.ems/src/framework/utils/ctx"
|
||||||
|
"be.ems/src/modules/crontask/processor/exportUEData"
|
||||||
|
"be.ems/features/ue/model"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileSource struct {
|
||||||
|
SysJob model.SysJob
|
||||||
|
TableName string `json:"tableName"`
|
||||||
|
TableDisplay string `json:"tableDisplay"`
|
||||||
|
FilePath string `json:"filePath"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFileExportTable 获取文件导出任务列表
|
||||||
|
func (m *FileSource) GetFileExportTable(c *gin.Context) {
|
||||||
|
var results []model.SysJob
|
||||||
|
|
||||||
|
err := datasource.DefaultDB().Table(m.SysJob.TableName()).
|
||||||
|
Where("invoke_target=? and status=1", model.INVOKE_FILE_EXPORT).
|
||||||
|
Find(&results).Error
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, services.ErrResp(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
var response []FileSource
|
||||||
|
for _, job := range results {
|
||||||
|
params := make([]exportUEData.BarParams, 0)
|
||||||
|
if err := json.Unmarshal([]byte(job.TargetParams), ¶ms); err != nil {
|
||||||
|
c.JSON(http.StatusOK, services.ErrResp(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, param := range params {
|
||||||
|
TableDisplay := i18n.TKey(language, "table."+param.TableName)
|
||||||
|
if TableDisplay == "" {
|
||||||
|
TableDisplay = param.TableName
|
||||||
|
}
|
||||||
|
response = append(response, FileSource{
|
||||||
|
SysJob: job,
|
||||||
|
TableName: param.TableName,
|
||||||
|
TableDisplay: TableDisplay,
|
||||||
|
FilePath: param.FilePath,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, services.DataResp(response))
|
||||||
|
}
|
||||||
|
|
||||||
488
features/ue/controller/ims_user.go
Normal file
488
features/ue/controller/ims_user.go
Normal file
@@ -0,0 +1,488 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"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/vo/result"
|
||||||
|
neService "be.ems/src/modules/network_element/service"
|
||||||
|
"be.ems/features/ue/service"
|
||||||
|
"be.ems/features/ue/model"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化控制层 IMSUserController 结构体
|
||||||
|
var NewIMSUserController = &IMSUserController{
|
||||||
|
imsUserService: service.NewIMSUserService,
|
||||||
|
neInfoService: neService.NewNeInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMS用户信息 控制层处理
|
||||||
|
//
|
||||||
|
// @Description IMS用户信息 控制层处理
|
||||||
|
type IMSUserController struct {
|
||||||
|
imsUserService *service.IMSUserService // IMS User信息服务
|
||||||
|
neInfoService *neService.NeInfo // 网元信息服务
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IMSUserController) ResetData(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := s.imsUserService.ResetData(neId)
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (s *IMSUserController) List(c *gin.Context) {
|
||||||
|
querys := ctx.QueryMap(c)
|
||||||
|
// querys["userName"] = ctx.LoginUserToUserName(c)
|
||||||
|
// 判断租户角色
|
||||||
|
loginUser, _ := ctx.LoginUser(c)
|
||||||
|
if len(loginUser.User.Roles) > 0 {
|
||||||
|
for _, v := range loginUser.User.Roles {
|
||||||
|
if v.RoleKey == "tenant" {
|
||||||
|
querys["tenantName"] = loginUser.User.UserName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data := s.imsUserService.SelectPage(querys)
|
||||||
|
c.JSON(200, result.Ok(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IMSUserController) Info(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
imsi := c.Param("imsi")
|
||||||
|
if neId == "" || imsi == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("dsp imsuser:imsi=%s", imsi)
|
||||||
|
data, err := telnet.ConvertToMap(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) == 0 {
|
||||||
|
c.JSON(200, result.ErrMsg("Not found IMS User data"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析返回的数据
|
||||||
|
u := s.imsUserService.ParseInfo(imsi, neId, data)
|
||||||
|
s.imsUserService.Insert(neId, u)
|
||||||
|
c.JSON(200, result.OkData(u))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IMSUserController) Add(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body model.IMSUser
|
||||||
|
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||||
|
if err != nil || len(body.IMSI) < model.IMSI_MAX_LENGTH {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("add imsuser:imsi=%s,", body.IMSI)
|
||||||
|
cmd += s.imsUserService.ParseCommandParams(body)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
body.NeId = neId
|
||||||
|
s.imsUserService.Insert(neId, body)
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IMSUserController) Adds(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
num := c.Param("num")
|
||||||
|
if neId == "" || num == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body model.IMSUser
|
||||||
|
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||||
|
if err != nil || len(body.IMSI) < model.IMSI_MAX_LENGTH {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("baa imsuser:start_imsi=%s,start_msisdn=%s,sub_num=%s,", body.IMSI, body.MSISDN, num)
|
||||||
|
cmd += s.imsUserService.ParseCommandParams(body)
|
||||||
|
// 去除msisdn参数,避免重复
|
||||||
|
omemsisdn := fmt.Sprintf(",msisdn=%s,", body.MSISDN)
|
||||||
|
cmd = strings.Replace(cmd, omemsisdn, ",", 1)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IMSUserController) Edit(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body model.IMSUser
|
||||||
|
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||||
|
if err != nil || len(body.IMSI) < model.IMSI_MAX_LENGTH {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("mod imsuser:imsi=%s,", body.IMSI)
|
||||||
|
cmd += s.imsUserService.ParseCommandParams(body)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
body.NeId = neId
|
||||||
|
s.imsUserService.Insert(neId, body)
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IMSUserController) Remove(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
imsi := c.Param("imsi")
|
||||||
|
if neId == "" || len(imsi) < model.IMSI_MAX_LENGTH {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理字符转id数组后去重
|
||||||
|
imsiArr := strings.Split(imsi, ",")
|
||||||
|
uniqueIDs := parse.RemoveDuplicates(imsiArr)
|
||||||
|
if len(uniqueIDs) <= 0 {
|
||||||
|
c.JSON(200, result.Err(nil))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
resultData := map[string]string{}
|
||||||
|
for _, imsi := range uniqueIDs {
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("del imsuser:imsi=%s", imsi)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
resultData[imsi] = err.Error()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
s.imsUserService.Delete(neId, imsi)
|
||||||
|
}
|
||||||
|
resultData[imsi] = data
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, result.OkData(resultData))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IMSUserController) Removes(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
imsi := c.Param("imsi")
|
||||||
|
num := c.Param("num")
|
||||||
|
if neId == "" || len(imsi) < model.IMSI_MAX_LENGTH || num == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("bde imsuser:start_imsi=%s,sub_num=%s", imsi, num)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
s.imsUserService.LoadData(neId, imsi, num)
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IMSUserController) Export(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
// 查询结果,根据查询条件结果,单页最大值限制
|
||||||
|
querys := ctx.BodyJSONMap(c)
|
||||||
|
neId := querys["neId"].(string)
|
||||||
|
fileType := querys["type"].(string)
|
||||||
|
if neId == "" || fileType == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !(fileType == "csv" || fileType == "txt") {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断租户角色
|
||||||
|
loginUser, _ := ctx.LoginUser(c)
|
||||||
|
if len(loginUser.User.Roles) > 0 {
|
||||||
|
for _, v := range loginUser.User.Roles {
|
||||||
|
if v.RoleKey == "tenant" {
|
||||||
|
querys["tenantName"] = loginUser.User.UserName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
querys["pageNum"] = 1
|
||||||
|
querys["pageSize"] = 10000
|
||||||
|
data := s.imsUserService.SelectPage(querys)
|
||||||
|
if parse.Number(data["total"]) == 0 {
|
||||||
|
// 导出数据记录为空
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rows := data["rows"].([]model.IMSUser)
|
||||||
|
|
||||||
|
// rows := s.imsUserService.SelectList(model.IMSUser{NeId: neId})
|
||||||
|
if len(rows) <= 0 {
|
||||||
|
// 导出数据记录为空
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件名
|
||||||
|
fileName := fmt.Sprintf("udm_volte_user_export_%s_%d.%s", neId, time.Now().UnixMilli(), fileType)
|
||||||
|
filePath := filepath.Join(file.ParseUploadFileDir(uploadsubpath.EXPORT), fileName)
|
||||||
|
|
||||||
|
if fileType == "csv" {
|
||||||
|
// 转换数据
|
||||||
|
data := [][]string{}
|
||||||
|
data = append(data, []string{"IMSI", "MSISDN", "VoLTE", "VNI"})
|
||||||
|
for _, v := range rows {
|
||||||
|
data = append(data, []string{v.IMSI, v.MSISDN, v.VoLTE, v.VNI})
|
||||||
|
}
|
||||||
|
// 输出到文件
|
||||||
|
if err := file.WriterFileCSV(data, filePath); err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileType == "txt" {
|
||||||
|
// 转换数据
|
||||||
|
data := [][]string{}
|
||||||
|
for _, v := range rows {
|
||||||
|
data = append(data, []string{v.IMSI, v.MSISDN, v.VoLTE, v.VNI})
|
||||||
|
}
|
||||||
|
// 输出到文件
|
||||||
|
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.FileAttachment(filePath, fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *IMSUserController) Import(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
var body struct {
|
||||||
|
NeId string `json:"neId" binding:"required"`
|
||||||
|
UploadPath string `json:"uploadPath" binding:"required"`
|
||||||
|
}
|
||||||
|
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断文件名
|
||||||
|
if !(strings.HasSuffix(body.UploadPath, ".csv") || strings.HasSuffix(body.UploadPath, ".txt")) {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", body.NeId)
|
||||||
|
if neInfo.NeId != body.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()
|
||||||
|
|
||||||
|
// 本地文件
|
||||||
|
localFilePath := file.ParseUploadFilePath(body.UploadPath)
|
||||||
|
neFilePath := fmt.Sprintf("/tmp/%s", filepath.Base(localFilePath))
|
||||||
|
// 复制到远程
|
||||||
|
if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg("error uploading file"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.NeType, neInfo.NeId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("import imsuser:path=%s", neFilePath)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
if strings.HasSuffix(body.UploadPath, ".csv") {
|
||||||
|
data := file.ReadFileCSV(localFilePath)
|
||||||
|
go s.imsUserService.InsertData(neInfo.NeId, "csv", data)
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(body.UploadPath, ".txt") {
|
||||||
|
data := file.ReadFileTXT(",", localFilePath)
|
||||||
|
go s.imsUserService.InsertData(neInfo.NeId, "txt", data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkMsg(data))
|
||||||
|
}
|
||||||
486
features/ue/controller/voip_auth.go
Normal file
486
features/ue/controller/voip_auth.go
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"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/vo/result"
|
||||||
|
neService "be.ems/src/modules/network_element/service"
|
||||||
|
"be.ems/features/ue/service"
|
||||||
|
"be.ems/features/ue/model"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化控制层 VoIPAuthController 结构体
|
||||||
|
var NewVoIPAuthController = &VoIPAuthController{
|
||||||
|
voipAuthService: service.NewVoIPAuthService,
|
||||||
|
neInfoService: neService.NewNeInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMS用户信息 控制层处理
|
||||||
|
//
|
||||||
|
// @Description IMS用户信息 控制层处理
|
||||||
|
type VoIPAuthController struct {
|
||||||
|
voipAuthService *service.VoIPAuthService // VoIP Auth信息服务
|
||||||
|
neInfoService *neService.NeInfo // 网元信息服务
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) ResetData(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := s.voipAuthService.ResetData(neId)
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) List(c *gin.Context) {
|
||||||
|
querys := ctx.QueryMap(c)
|
||||||
|
// querys["userName"] = ctx.LoginUserToUserName(c)
|
||||||
|
// 判断租户角色
|
||||||
|
loginUser, _ := ctx.LoginUser(c)
|
||||||
|
if len(loginUser.User.Roles) > 0 {
|
||||||
|
for _, v := range loginUser.User.Roles {
|
||||||
|
if v.RoleKey == "tenant" {
|
||||||
|
querys["tenantName"] = loginUser.User.UserName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data := s.voipAuthService.SelectPage(querys)
|
||||||
|
c.JSON(200, result.Ok(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) Info(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
userName := c.Param("userName")
|
||||||
|
if neId == "" || userName == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("dsp voip:username=%s", userName)
|
||||||
|
data, err := telnet.ConvertToMap(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) == 0 {
|
||||||
|
c.JSON(200, result.ErrMsg("Not found VoIP Auth data"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析返回的数据
|
||||||
|
u := s.voipAuthService.ParseInfo(userName, neId, data)
|
||||||
|
s.voipAuthService.Insert(neId, u)
|
||||||
|
c.JSON(200, result.OkData(u))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) Add(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body model.VoIPAuth
|
||||||
|
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("add voip:username=%s,", body.UserName)
|
||||||
|
cmd += s.voipAuthService.ParseCommandParams(body)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
body.NeId = neId
|
||||||
|
s.voipAuthService.Insert(neId, body)
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) Adds(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
num := c.Param("num")
|
||||||
|
if neId == "" || num == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body model.VoIPAuth
|
||||||
|
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("baa voip:start_username=%s,password=%s,sub_num=%s,",
|
||||||
|
body.UserName, body.Password, num)
|
||||||
|
cmd += s.voipAuthService.ParseCommandParams(body)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) Edit(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body model.VoIPAuth
|
||||||
|
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("mod voip:username=%s,", body.UserName)
|
||||||
|
cmd += s.voipAuthService.ParseCommandParams(body)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
body.NeId = neId
|
||||||
|
s.voipAuthService.Insert(neId, body)
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) Remove(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
userName := c.Param("userName")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理字符转id数组后去重
|
||||||
|
userNameArr := strings.Split(userName, ",")
|
||||||
|
uniqueIDs := parse.RemoveDuplicates(userNameArr)
|
||||||
|
if len(uniqueIDs) <= 0 {
|
||||||
|
c.JSON(200, result.Err(nil))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
resultData := map[string]string{}
|
||||||
|
for _, userName := range uniqueIDs {
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("del voip:username=%s", userName)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
resultData[userName] = err.Error()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
s.voipAuthService.Delete(neId, userName)
|
||||||
|
}
|
||||||
|
resultData[userName] = data
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, result.OkData(resultData))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) Removes(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
userName := c.Param("userName")
|
||||||
|
num := c.Param("num")
|
||||||
|
if neId == "" || num == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("bde voip:start_username=%s,sub_num=%s", userName, num)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
s.voipAuthService.LoadData(neId, userName, num)
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) Export(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
// 查询结果,根据查询条件结果,单页最大值限制
|
||||||
|
querys := ctx.BodyJSONMap(c)
|
||||||
|
neId := querys["neId"].(string)
|
||||||
|
fileType := querys["type"].(string)
|
||||||
|
if neId == "" || fileType == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !(fileType == "csv" || fileType == "txt") {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断租户角色
|
||||||
|
loginUser, _ := ctx.LoginUser(c)
|
||||||
|
if len(loginUser.User.Roles) > 0 {
|
||||||
|
for _, v := range loginUser.User.Roles {
|
||||||
|
if v.RoleKey == "tenant" {
|
||||||
|
querys["tenantName"] = loginUser.User.UserName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
querys["pageNum"] = 1
|
||||||
|
querys["pageSize"] = 10000
|
||||||
|
data := s.voipAuthService.SelectPage(querys)
|
||||||
|
if parse.Number(data["total"]) == 0 {
|
||||||
|
// 导出数据记录为空
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rows := data["rows"].([]model.VoIPAuth)
|
||||||
|
|
||||||
|
// rows := s.voipAuthService.SelectList(model.VoIPAuth{NeId: neId})
|
||||||
|
if len(rows) <= 0 {
|
||||||
|
// 导出数据记录为空
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件名
|
||||||
|
fileName := fmt.Sprintf("u_voip_auth_export_%s_%d.%s", neId, time.Now().UnixMilli(), fileType)
|
||||||
|
filePath := filepath.Join(file.ParseUploadFileDir(uploadsubpath.EXPORT), fileName)
|
||||||
|
|
||||||
|
if fileType == "csv" {
|
||||||
|
// 转换数据
|
||||||
|
data := [][]string{}
|
||||||
|
data = append(data, []string{"UserName", "Password"})
|
||||||
|
for _, v := range rows {
|
||||||
|
data = append(data, []string{v.UserName, v.Password})
|
||||||
|
}
|
||||||
|
// 输出到文件
|
||||||
|
if err := file.WriterFileCSV(data, filePath); err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileType == "txt" {
|
||||||
|
// 转换数据
|
||||||
|
data := [][]string{}
|
||||||
|
for _, v := range rows {
|
||||||
|
data = append(data, []string{v.UserName, v.Password})
|
||||||
|
}
|
||||||
|
// 输出到文件
|
||||||
|
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.FileAttachment(filePath, fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *VoIPAuthController) Import(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
var body struct {
|
||||||
|
NeId string `json:"neId" binding:"required"`
|
||||||
|
UploadPath string `json:"uploadPath" binding:"required"`
|
||||||
|
}
|
||||||
|
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断文件名
|
||||||
|
if !(strings.HasSuffix(body.UploadPath, ".csv") || strings.HasSuffix(body.UploadPath, ".txt")) {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", body.NeId)
|
||||||
|
if neInfo.NeId != body.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()
|
||||||
|
|
||||||
|
// 本地文件
|
||||||
|
localFilePath := file.ParseUploadFilePath(body.UploadPath)
|
||||||
|
neFilePath := fmt.Sprintf("/tmp/%s", filepath.Base(localFilePath))
|
||||||
|
// 复制到远程
|
||||||
|
if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg("error uploading file"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.NeType, neInfo.NeId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("import voip:path=%s", neFilePath)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
if strings.HasSuffix(body.UploadPath, ".csv") {
|
||||||
|
data := file.ReadFileCSV(localFilePath)
|
||||||
|
go s.voipAuthService.InsertData(neInfo.NeId, "csv", data)
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(body.UploadPath, ".txt") {
|
||||||
|
data := file.ReadFileTXT(",", localFilePath)
|
||||||
|
go s.voipAuthService.InsertData(neInfo.NeId, "txt", data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkMsg(data))
|
||||||
|
}
|
||||||
486
features/ue/ims_user/controller.go
Normal file
486
features/ue/ims_user/controller.go
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
package ims_user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"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/vo/result"
|
||||||
|
neService "be.ems/src/modules/network_element/service"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化控制层 Controller 结构体
|
||||||
|
var NewController = &Controller{
|
||||||
|
volteUserService: NewVoLTEService,
|
||||||
|
neInfoService: neService.NewNeInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMS用户信息 控制层处理
|
||||||
|
//
|
||||||
|
// @Description IMS用户信息 控制层处理
|
||||||
|
type Controller struct {
|
||||||
|
volteUserService *Service // IMS User信息服务
|
||||||
|
neInfoService *neService.NeInfo // 网元信息服务
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Controller) ResetData(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := s.volteUserService.ResetData(neId)
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (s *Controller) List(c *gin.Context) {
|
||||||
|
querys := ctx.QueryMap(c)
|
||||||
|
// querys["userName"] = ctx.LoginUserToUserName(c)
|
||||||
|
// 判断租户角色
|
||||||
|
loginUser, _ := ctx.LoginUser(c)
|
||||||
|
if len(loginUser.User.Roles) > 0 {
|
||||||
|
for _, v := range loginUser.User.Roles {
|
||||||
|
if v.RoleKey == "tenant" {
|
||||||
|
querys["tenantName"] = loginUser.User.UserName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data := s.volteUserService.SelectPage(querys)
|
||||||
|
c.JSON(200, result.Ok(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Controller) Info(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
imsi := c.Param("imsi")
|
||||||
|
if neId == "" || imsi == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("dsp imsuser:imsi=%s", imsi)
|
||||||
|
data, err := telnet.ConvertToMap(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) == 0 {
|
||||||
|
c.JSON(200, result.ErrMsg("Not found VoLTE user data"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析返回的数据
|
||||||
|
u := s.volteUserService.ParseInfo(imsi, neId, data)
|
||||||
|
s.volteUserService.Insert(neId, u)
|
||||||
|
c.JSON(200, result.OkData(u))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Controller) Add(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body VoLTEUser
|
||||||
|
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||||
|
if err != nil || len(body.IMSI) < IMSI_MAX_LENGTH {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("add imsuser:imsi=%s,", body.IMSI)
|
||||||
|
cmd += s.volteUserService.ParseCommandParams(body)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
body.NeId = neId
|
||||||
|
s.volteUserService.Insert(neId, body)
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Controller) Adds(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
num := c.Param("num")
|
||||||
|
if neId == "" || num == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body VoLTEUser
|
||||||
|
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||||
|
if err != nil || len(body.IMSI) < IMSI_MAX_LENGTH {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("baa imsuser:start_imsi=%s,start_msisdn=%s,sub_num=%s,", body.IMSI, body.MSISDN, num)
|
||||||
|
cmd += s.volteUserService.ParseCommandParams(body)
|
||||||
|
// 去除msisdn参数,避免重复
|
||||||
|
omemsisdn := fmt.Sprintf(",msisdn=%s,", body.MSISDN)
|
||||||
|
cmd = strings.Replace(cmd, omemsisdn, ",", 1)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Controller) Edit(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
if neId == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body VoLTEUser
|
||||||
|
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||||
|
if err != nil || len(body.IMSI) < IMSI_MAX_LENGTH {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("mod imsuser:imsi=%s,", body.IMSI)
|
||||||
|
cmd += s.volteUserService.ParseCommandParams(body)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
body.NeId = neId
|
||||||
|
s.volteUserService.Insert(neId, body)
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Controller) Remove(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
imsi := c.Param("imsi")
|
||||||
|
if neId == "" || len(imsi) < IMSI_MAX_LENGTH {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理字符转id数组后去重
|
||||||
|
imsiArr := strings.Split(imsi, ",")
|
||||||
|
uniqueIDs := parse.RemoveDuplicates(imsiArr)
|
||||||
|
if len(uniqueIDs) <= 0 {
|
||||||
|
c.JSON(200, result.Err(nil))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
resultData := map[string]string{}
|
||||||
|
for _, imsi := range uniqueIDs {
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("del imsuser:imsi=%s", imsi)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
resultData[imsi] = err.Error()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
s.volteUserService.Delete(neId, imsi)
|
||||||
|
}
|
||||||
|
resultData[imsi] = data
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, result.OkData(resultData))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Controller) Removes(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
neId := c.Param("neId")
|
||||||
|
imsi := c.Param("imsi")
|
||||||
|
num := c.Param("num")
|
||||||
|
if neId == "" || len(imsi) < IMSI_MAX_LENGTH || num == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient("UDM", neId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("bde imsuser:start_imsi=%s,sub_num=%s", imsi, num)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
s.volteUserService.LoadData(neId, imsi, num)
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Controller) Export(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
// 查询结果,根据查询条件结果,单页最大值限制
|
||||||
|
querys := ctx.BodyJSONMap(c)
|
||||||
|
neId := querys["neId"].(string)
|
||||||
|
fileType := querys["type"].(string)
|
||||||
|
if neId == "" || fileType == "" {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !(fileType == "csv" || fileType == "txt") {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断租户角色
|
||||||
|
loginUser, _ := ctx.LoginUser(c)
|
||||||
|
if len(loginUser.User.Roles) > 0 {
|
||||||
|
for _, v := range loginUser.User.Roles {
|
||||||
|
if v.RoleKey == "tenant" {
|
||||||
|
querys["tenantName"] = loginUser.User.UserName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
querys["pageNum"] = 1
|
||||||
|
querys["pageSize"] = 10000
|
||||||
|
data := s.volteUserService.SelectPage(querys)
|
||||||
|
if parse.Number(data["total"]) == 0 {
|
||||||
|
// 导出数据记录为空
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rows := data["rows"].([]VoLTEUser)
|
||||||
|
|
||||||
|
// rows := s.volteUserService.SelectList(VoLTEUser{NeId: neId})
|
||||||
|
if len(rows) <= 0 {
|
||||||
|
// 导出数据记录为空
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件名
|
||||||
|
fileName := fmt.Sprintf("udm_volte_user_export_%s_%d.%s", neId, time.Now().UnixMilli(), fileType)
|
||||||
|
filePath := filepath.Join(file.ParseUploadFileDir(uploadsubpath.EXPORT), fileName)
|
||||||
|
|
||||||
|
if fileType == "csv" {
|
||||||
|
// 转换数据
|
||||||
|
data := [][]string{}
|
||||||
|
data = append(data, []string{"IMSI", "MSISDN", "VoLTE", "VNI"})
|
||||||
|
for _, v := range rows {
|
||||||
|
data = append(data, []string{v.IMSI, v.MSISDN, v.VoLTE, v.VNI})
|
||||||
|
}
|
||||||
|
// 输出到文件
|
||||||
|
if err := file.WriterFileCSV(data, filePath); err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileType == "txt" {
|
||||||
|
// 转换数据
|
||||||
|
data := [][]string{}
|
||||||
|
for _, v := range rows {
|
||||||
|
data = append(data, []string{v.IMSI, v.MSISDN, v.VoLTE, v.VNI})
|
||||||
|
}
|
||||||
|
// 输出到文件
|
||||||
|
if err := file.WriterFileTXT(data, ",", filePath); err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.FileAttachment(filePath, fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Controller) Import(c *gin.Context) {
|
||||||
|
language := ctx.AcceptLanguage(c)
|
||||||
|
var body struct {
|
||||||
|
NeId string `json:"neId" binding:"required"`
|
||||||
|
UploadPath string `json:"uploadPath" binding:"required"`
|
||||||
|
}
|
||||||
|
if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
|
||||||
|
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断文件名
|
||||||
|
if !(strings.HasSuffix(body.UploadPath, ".csv") || strings.HasSuffix(body.UploadPath, ".txt")) {
|
||||||
|
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询网元获取IP
|
||||||
|
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", body.NeId)
|
||||||
|
if neInfo.NeId != body.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()
|
||||||
|
|
||||||
|
// 本地文件
|
||||||
|
localFilePath := file.ParseUploadFilePath(body.UploadPath)
|
||||||
|
neFilePath := fmt.Sprintf("/tmp/%s", filepath.Base(localFilePath))
|
||||||
|
// 复制到远程
|
||||||
|
if err = sftpClient.CopyFileLocalToRemote(localFilePath, neFilePath); err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg("error uploading file"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 网元主机的Telnet客户端
|
||||||
|
telnetClient, err := s.neInfoService.NeRunTelnetClient(neInfo.NeType, neInfo.NeId, 1)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer telnetClient.Close()
|
||||||
|
|
||||||
|
// 发送MML
|
||||||
|
cmd := fmt.Sprintf("import imsuser:path=%s", neFilePath)
|
||||||
|
data, err := telnet.ConvertToStr(telnetClient, cmd)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令ok时
|
||||||
|
if strings.Contains(data, "ok") {
|
||||||
|
if strings.HasSuffix(body.UploadPath, ".csv") {
|
||||||
|
data := file.ReadFileCSV(localFilePath)
|
||||||
|
go s.volteUserService.InsertData(neInfo.NeId, "csv", data)
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(body.UploadPath, ".txt") {
|
||||||
|
data := file.ReadFileTXT(",", localFilePath)
|
||||||
|
go s.volteUserService.InsertData(neInfo.NeId, "txt", data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.JSON(200, result.OkMsg(data))
|
||||||
|
}
|
||||||
26
features/ue/ims_user/model.go
Normal file
26
features/ue/ims_user/model.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package ims_user
|
||||||
|
|
||||||
|
const (
|
||||||
|
// IMSI 号码长度
|
||||||
|
IMSI_MAX_LENGTH = 15
|
||||||
|
// MSISDN 号码长度
|
||||||
|
MSISDN_MAX_LENGTH = 15
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Description VoLTE用户信息
|
||||||
|
type VoLTEUser struct {
|
||||||
|
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键
|
||||||
|
NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识
|
||||||
|
IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID
|
||||||
|
MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码
|
||||||
|
VoLTE string `json:"volte" gorm:"column:volte"` // VoLTE
|
||||||
|
VNI string `json:"vni" gorm:"column:vni"` // VNI
|
||||||
|
|
||||||
|
TenantID string `json:"tenantID" gorm:"column:tenant_id"`
|
||||||
|
TenantName string `json:"tenantName" gorm:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName 表名称
|
||||||
|
func (*VoLTEUser) TableName() string {
|
||||||
|
return "u_ims_user"
|
||||||
|
}
|
||||||
272
features/ue/ims_user/repository.go
Normal file
272
features/ue/ims_user/repository.go
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
package ims_user
|
||||||
|
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化数据层 Repository 结构体
|
||||||
|
var NewVoLTERepository = &Repository{
|
||||||
|
selectSql: `select
|
||||||
|
s.id, s.ne_id, s.imsi, s.msisdn, s.volte, s.vni,
|
||||||
|
t.tenant_id, t.tenant_name
|
||||||
|
from u_ims_user s
|
||||||
|
left join sys_tenant t on t.tenant_id = s.tenant_id and t.status = 1`,
|
||||||
|
|
||||||
|
resultMap: map[string]string{
|
||||||
|
"id": "ID",
|
||||||
|
"ne_id": "NeId",
|
||||||
|
"imsi": "IMSI",
|
||||||
|
"msisdn": "MSISDN",
|
||||||
|
"volte": "VoLTE",
|
||||||
|
"vni": "VNI",
|
||||||
|
|
||||||
|
"tenant_id": "TenantID",
|
||||||
|
"tenant_name": "TenantName", // Tenant name for multi-tenancy
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repository UDM签约信息表 数据层处理
|
||||||
|
type Repository struct {
|
||||||
|
// 查询视图对象SQL
|
||||||
|
selectSql string
|
||||||
|
// 结果字段与实体映射
|
||||||
|
resultMap map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertResultRows 将结果记录转实体结果组
|
||||||
|
func (r *Repository) convertResultRows(rows []map[string]any) []VoLTEUser {
|
||||||
|
arr := make([]VoLTEUser, 0)
|
||||||
|
for _, row := range rows {
|
||||||
|
item := VoLTEUser{}
|
||||||
|
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 *Repository) ClearAndInsert(neId string, u []VoLTEUser) int64 {
|
||||||
|
// 不指定neID时,用 TRUNCATE 清空表快
|
||||||
|
// _, err := datasource.ExecDB("", "TRUNCATE TABLE u_ims_user", nil)
|
||||||
|
_, err := datasource.ExecDB("", "DELETE FROM u_ims_user WHERE ne_id = ?", []any{neId})
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("TRUNCATE err => %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.Inserts(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectPage 根据条件分页查询字典类型
|
||||||
|
func (r *Repository) 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["msisdn"]; ok && v != "" {
|
||||||
|
conditions = append(conditions, "msisdn like concat(concat('%', ?), '%')")
|
||||||
|
params = append(params, strings.Trim(v.(string), " "))
|
||||||
|
}
|
||||||
|
if v, ok := query["imsis"]; ok && v != "" {
|
||||||
|
placeholder := repo.KeyPlaceholderByQuery(len(v.([]any)))
|
||||||
|
conditions = append(conditions, fmt.Sprintf("imsi in (%s)", placeholder))
|
||||||
|
for _, v := range v.([]any) {
|
||||||
|
params = append(params, v.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for multi-tenancy solution
|
||||||
|
if v, ok := query["tenantName"]; ok && v != "" {
|
||||||
|
var tenantID []string
|
||||||
|
err := dborm.DefaultDB().Table("sys_tenant").
|
||||||
|
Where("tenant_name=? and status=1", 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)
|
||||||
|
query["neId"] = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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": []VoLTEUser{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询数量 长度为0直接返回
|
||||||
|
totalSql := "select count(1) as 'total' from u_ims_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 *Repository) SelectList(u VoLTEUser) []VoLTEUser {
|
||||||
|
// 查询条件拼接
|
||||||
|
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 *Repository) SelectByIMSIAndNeID(imsi, neId string) VoLTEUser {
|
||||||
|
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 VoLTEUser{}
|
||||||
|
}
|
||||||
|
// 转换实体
|
||||||
|
rows := r.convertResultRows(results)
|
||||||
|
if len(rows) > 0 {
|
||||||
|
return rows[0]
|
||||||
|
}
|
||||||
|
return VoLTEUser{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 批量添加
|
||||||
|
func (r *Repository) Inserts(uArr []VoLTEUser) 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 *Repository) Delete(imsi, neId string) int64 {
|
||||||
|
tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&Repository{})
|
||||||
|
if err := tx.Error; err != nil {
|
||||||
|
logger.Errorf("Delete err => %v", err)
|
||||||
|
}
|
||||||
|
return tx.RowsAffected
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePrefixByIMSI 删除前缀匹配的实体
|
||||||
|
func (r *Repository) DeletePrefixByIMSI(imsiPrefix, neId string) int64 {
|
||||||
|
tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsiPrefix, neId).Delete(&Repository{})
|
||||||
|
if err := tx.Error; err != nil {
|
||||||
|
logger.Errorf("DeletePrefixByIMSI err => %v", err)
|
||||||
|
}
|
||||||
|
return tx.RowsAffected
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) SetTenantID(subArr *[]VoLTEUser) {
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
67
features/ue/ims_user/router.go
Normal file
67
features/ue/ims_user/router.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package ims_user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"be.ems/src/framework/middleware"
|
||||||
|
"be.ems/src/framework/middleware/collectlogs"
|
||||||
|
"be.ems/src/framework/middleware/repeat"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Description Register Routes for ims_user
|
||||||
|
func Register(r *gin.RouterGroup) {
|
||||||
|
|
||||||
|
volteUserGroup := r.Group("/volte/user")
|
||||||
|
{
|
||||||
|
volteUserGroup.PUT("/resetData/:neId",
|
||||||
|
repeat.RepeatSubmit(5),
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.volteUser", collectlogs.BUSINESS_TYPE_CLEAN)),
|
||||||
|
NewController.ResetData,
|
||||||
|
)
|
||||||
|
volteUserGroup.GET("/list",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
NewController.List,
|
||||||
|
)
|
||||||
|
volteUserGroup.GET("/:neId/:imsi",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
NewController.Info,
|
||||||
|
)
|
||||||
|
volteUserGroup.POST("/:neId",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.volteUser", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||||
|
NewController.Add,
|
||||||
|
)
|
||||||
|
volteUserGroup.POST("/:neId/:num",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.volteUser", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||||
|
NewController.Adds,
|
||||||
|
)
|
||||||
|
volteUserGroup.PUT("/:neId",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.volteUser", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||||
|
NewController.Edit,
|
||||||
|
)
|
||||||
|
volteUserGroup.DELETE("/:neId/:imsi",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.volteUser", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||||
|
NewController.Remove,
|
||||||
|
)
|
||||||
|
volteUserGroup.DELETE("/:neId/:imsi/:num",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.volteUser", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||||
|
NewController.Removes,
|
||||||
|
)
|
||||||
|
volteUserGroup.POST("/export",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.volteUser", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||||
|
NewController.Export,
|
||||||
|
)
|
||||||
|
volteUserGroup.POST("/import",
|
||||||
|
middleware.PreAuthorize(nil),
|
||||||
|
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.volteUser", collectlogs.BUSINESS_TYPE_IMPORT)),
|
||||||
|
NewController.Import,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
209
features/ue/ims_user/service.go
Normal file
209
features/ue/ims_user/service.go
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
package ims_user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"be.ems/src/framework/redis"
|
||||||
|
neService "be.ems/src/modules/network_element/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化服务层 Service 结构体
|
||||||
|
var NewVoLTEService = &Service{
|
||||||
|
volteRepository: NewVoLTERepository,
|
||||||
|
}
|
||||||
|
|
||||||
|
// VoLTE用户信息 服务层处理
|
||||||
|
type Service struct {
|
||||||
|
volteRepository *Repository // VoLTE用户信息数据信息
|
||||||
|
}
|
||||||
|
|
||||||
|
// dataByRedis UDM签约用户 db:0 中 volte:*
|
||||||
|
func (r *Service) dataByRedis(imsi, neId string) []VoLTEUser {
|
||||||
|
arr := []VoLTEUser{}
|
||||||
|
key := fmt.Sprintf("volte:%s", imsi)
|
||||||
|
source := fmt.Sprintf("UDM_%s", neId)
|
||||||
|
|
||||||
|
// 网元主机的Redis客户端
|
||||||
|
redisClient, err := neService.NewNeInfo.NeRunRedisClient("UDM", neId)
|
||||||
|
if err != nil {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
redisClient.Close()
|
||||||
|
redis.ConnectPush(source, nil)
|
||||||
|
}()
|
||||||
|
redis.ConnectPush(source, redisClient.Client)
|
||||||
|
|
||||||
|
udmsdArr, err := redis.GetKeys(source, key)
|
||||||
|
if err != nil {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
mkv, err := redis.GetHashBatch(source, udmsdArr)
|
||||||
|
if err != nil {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, m := range mkv {
|
||||||
|
var imsi, msisdn string
|
||||||
|
KeyParts := strings.Split(k, ":")
|
||||||
|
switch len(KeyParts) {
|
||||||
|
case 0, 1:
|
||||||
|
// 处理单个部分的情况
|
||||||
|
continue
|
||||||
|
case 2:
|
||||||
|
// 处理两个部分的情况
|
||||||
|
imsi = KeyParts[1]
|
||||||
|
msisdn = "-"
|
||||||
|
case 3:
|
||||||
|
// 处理三个部分的情况
|
||||||
|
imsi = KeyParts[1]
|
||||||
|
msisdn = KeyParts[2]
|
||||||
|
default:
|
||||||
|
// 处理更多部分的情况
|
||||||
|
imsi = KeyParts[1]
|
||||||
|
msisdn = KeyParts[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
var vni string = "-"
|
||||||
|
impiParts := strings.Split(m["impi"], "@")
|
||||||
|
if len(impiParts) > 1 {
|
||||||
|
vni = impiParts[1] // 输出: ims.mnc001.mcc110.3gppnetwork.org
|
||||||
|
}
|
||||||
|
a := VoLTEUser{
|
||||||
|
NeId: neId,
|
||||||
|
IMSI: imsi, // volte:360000100000130:8612300000130
|
||||||
|
MSISDN: msisdn, // 8612300000130
|
||||||
|
VoLTE: m["tag"], // volte = tag
|
||||||
|
VNI: vni, // ims.mnc001.mcc110.3gppnetwork.org
|
||||||
|
}
|
||||||
|
arr = append(arr, a)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据
|
||||||
|
func (r *Service) ResetData(neId string) int64 {
|
||||||
|
subArr := r.dataByRedis("*", neId)
|
||||||
|
// 数据清空后添加
|
||||||
|
go r.volteRepository.ClearAndInsert(neId, subArr)
|
||||||
|
return int64(len(subArr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseInfo 解析单个用户imsi签约信息 data从命令MML得到的结果
|
||||||
|
func (r *Service) ParseInfo(imsi, neId string, data map[string]string) VoLTEUser {
|
||||||
|
u := r.volteRepository.SelectByIMSIAndNeID(imsi, neId)
|
||||||
|
|
||||||
|
msisdn := data["MSISDN"]
|
||||||
|
if imsMsisdnLen := strings.Index(msisdn, ","); imsMsisdnLen != -1 {
|
||||||
|
msisdn = msisdn[:imsMsisdnLen]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用于更新
|
||||||
|
u.NeId = neId
|
||||||
|
u.IMSI = imsi
|
||||||
|
u.MSISDN = msisdn
|
||||||
|
u.VoLTE = data["VoLTE"]
|
||||||
|
u.VNI = data["VNI"]
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectPage 分页查询数据库
|
||||||
|
func (r *Service) SelectPage(query map[string]any) map[string]any {
|
||||||
|
return r.volteRepository.SelectPage(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectList 查询数据库
|
||||||
|
func (r *Service) SelectList(u VoLTEUser) []VoLTEUser {
|
||||||
|
return r.volteRepository.SelectList(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 从数据中读取后删除imsi再存入数据库
|
||||||
|
// imsi长度15,ki长度32,opc长度0或者32
|
||||||
|
func (r *Service) Insert(neId string, u VoLTEUser) int64 {
|
||||||
|
uArr := r.dataByRedis(u.IMSI, neId)
|
||||||
|
if len(uArr) > 0 {
|
||||||
|
r.volteRepository.Delete(u.IMSI, neId)
|
||||||
|
return r.volteRepository.Inserts(uArr)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertData 导入文件数据 dataType目前两种:txt/csv
|
||||||
|
func (r *Service) 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 volte:4600001000004*
|
||||||
|
arr := r.dataByRedis(prefix+"*", neId)
|
||||||
|
if len(arr) > 0 {
|
||||||
|
r.volteRepository.DeletePrefixByIMSI(prefix, neId)
|
||||||
|
num += r.volteRepository.Inserts(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 删除单个不重新加载
|
||||||
|
func (r *Service) Delete(neId, imsi string) int64 {
|
||||||
|
return r.volteRepository.Delete(imsi, neId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadData 重新加载从imsi开始num的数据
|
||||||
|
func (r *Service) 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.volteRepository.Delete(keyIMSI, neId)
|
||||||
|
arr := r.dataByRedis(keyIMSI, neId)
|
||||||
|
if len(arr) < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
r.volteRepository.Inserts(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseCommandParams 解析数据组成命令参数 msisdn=xx,xx=xx,...
|
||||||
|
func (r *Service) ParseCommandParams(item VoLTEUser) string {
|
||||||
|
var conditions []string
|
||||||
|
if item.MSISDN != "" {
|
||||||
|
conditions = append(conditions, fmt.Sprintf("msisdn=%s", item.MSISDN))
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.VoLTE != "" {
|
||||||
|
conditions = append(conditions, fmt.Sprintf("volte=%s", item.VoLTE))
|
||||||
|
}
|
||||||
|
if item.VNI != "" {
|
||||||
|
conditions = append(conditions, fmt.Sprintf("vni=%s", item.VNI))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(conditions, ",")
|
||||||
|
}
|
||||||
26
features/ue/model/file_export.go
Normal file
26
features/ue/model/file_export.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
INVOKE_FILE_EXPORT = "exportUEData" // 调用目标字符串
|
||||||
|
)
|
||||||
|
|
||||||
|
type SysJob struct {
|
||||||
|
JobID int64 `gorm:"column:job_id;primary_key;auto_increment" json:"job_id"` //任务ID
|
||||||
|
InvokeTarget string `gorm:"column:invoke_target" json:"invoke_target"` //调用目标字符串
|
||||||
|
TargetParams string `gorm:"column:target_params;type:json" json:"target_params,omitempty"` //调用目标传入参数
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *SysJob) TableName() string {
|
||||||
|
return "sys_job"
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileExportQuery struct {
|
||||||
|
Path string `form:"path" binding:"required"`
|
||||||
|
Suffix string `form:"suffix"`
|
||||||
|
PageNum int64 `form:"pageNum" binding:"required"`
|
||||||
|
PageSize int64 `form:"pageSize" binding:"required"`
|
||||||
|
}
|
||||||
26
features/ue/model/ims_user.go
Normal file
26
features/ue/model/ims_user.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
const (
|
||||||
|
// IMSI 号码长度
|
||||||
|
IMSI_MAX_LENGTH = 15
|
||||||
|
// MSISDN 号码长度
|
||||||
|
MSISDN_MAX_LENGTH = 15
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Description VoLTE用户信息
|
||||||
|
type IMSUser struct {
|
||||||
|
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键
|
||||||
|
NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识
|
||||||
|
IMSI string `json:"imsi" gorm:"column:imsi"` // SIM卡/USIM卡ID
|
||||||
|
MSISDN string `json:"msisdn" gorm:"column:msisdn"` // 用户电话号码
|
||||||
|
VoLTE string `json:"volte" gorm:"column:volte"` // VoLTE
|
||||||
|
VNI string `json:"vni" gorm:"column:vni"` // VNI
|
||||||
|
|
||||||
|
TenantID string `json:"tenantID" gorm:"column:tenant_id"`
|
||||||
|
TenantName string `json:"tenantName" gorm:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName 表名称
|
||||||
|
func (*IMSUser) TableName() string {
|
||||||
|
return "u_ims_user"
|
||||||
|
}
|
||||||
17
features/ue/model/voip_auth.go
Normal file
17
features/ue/model/voip_auth.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
// @Description VoLTE用户信息
|
||||||
|
type VoIPAuth struct {
|
||||||
|
ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 主键
|
||||||
|
NeId string `json:"neId" gorm:"column:ne_id"` // UDM网元标识
|
||||||
|
UserName string `json:"userName" gorm:"column:user_name"` // SIM卡/USIM卡ID
|
||||||
|
Password string `json:"password" gorm:"column:password"` // 用户电话号码
|
||||||
|
|
||||||
|
TenantID string `json:"tenantID" gorm:"column:tenant_id"`
|
||||||
|
TenantName string `json:"tenantName" gorm:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName 表名称
|
||||||
|
func (*VoIPAuth) TableName() string {
|
||||||
|
return "u_voip_auth"
|
||||||
|
}
|
||||||
273
features/ue/repository/ims_user.go
Normal file
273
features/ue/repository/ims_user.go
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
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/features/ue/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化数据层 IMSUserRepository 结构体
|
||||||
|
var NewIMSUserRepository = &IMSUserRepository{
|
||||||
|
selectSql: `select
|
||||||
|
s.id, s.ne_id, s.imsi, s.msisdn, s.volte, s.vni,
|
||||||
|
t.tenant_id, t.tenant_name
|
||||||
|
from u_ims_user s
|
||||||
|
left join sys_tenant t on t.tenant_id = s.tenant_id and t.status = 1`,
|
||||||
|
|
||||||
|
resultMap: map[string]string{
|
||||||
|
"id": "ID",
|
||||||
|
"ne_id": "NeId",
|
||||||
|
"imsi": "IMSI",
|
||||||
|
"msisdn": "MSISDN",
|
||||||
|
"volte": "VoLTE",
|
||||||
|
"vni": "VNI",
|
||||||
|
|
||||||
|
"tenant_id": "TenantID",
|
||||||
|
"tenant_name": "TenantName", // Tenant name for multi-tenancy
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMSUserRepository UDM签约信息表 数据层处理
|
||||||
|
type IMSUserRepository struct {
|
||||||
|
// 查询视图对象SQL
|
||||||
|
selectSql string
|
||||||
|
// 结果字段与实体映射
|
||||||
|
resultMap map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertResultRows 将结果记录转实体结果组
|
||||||
|
func (r *IMSUserRepository) convertResultRows(rows []map[string]any) []model.IMSUser {
|
||||||
|
arr := make([]model.IMSUser, 0)
|
||||||
|
for _, row := range rows {
|
||||||
|
item := model.IMSUser{}
|
||||||
|
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 *IMSUserRepository) ClearAndInsert(neId string, u []model.IMSUser) int64 {
|
||||||
|
// 不指定neID时,用 TRUNCATE 清空表快
|
||||||
|
// _, err := datasource.ExecDB("", "TRUNCATE TABLE u_ims_user", nil)
|
||||||
|
_, err := datasource.ExecDB("", "DELETE FROM u_ims_user WHERE ne_id = ?", []any{neId})
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("TRUNCATE err => %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.Inserts(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectPage 根据条件分页查询字典类型
|
||||||
|
func (r *IMSUserRepository) 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["msisdn"]; ok && v != "" {
|
||||||
|
conditions = append(conditions, "msisdn like concat(concat('%', ?), '%')")
|
||||||
|
params = append(params, strings.Trim(v.(string), " "))
|
||||||
|
}
|
||||||
|
if v, ok := query["imsis"]; ok && v != "" {
|
||||||
|
placeholder := repo.KeyPlaceholderByQuery(len(v.([]any)))
|
||||||
|
conditions = append(conditions, fmt.Sprintf("imsi in (%s)", placeholder))
|
||||||
|
for _, v := range v.([]any) {
|
||||||
|
params = append(params, v.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for multi-tenancy solution
|
||||||
|
if v, ok := query["tenantName"]; ok && v != "" {
|
||||||
|
var tenantID []string
|
||||||
|
err := dborm.DefaultDB().Table("sys_tenant").
|
||||||
|
Where("tenant_name=? and status=1", 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)
|
||||||
|
query["neId"] = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.IMSUser{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询数量 长度为0直接返回
|
||||||
|
totalSql := "select count(1) as 'total' from u_ims_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 *IMSUserRepository) SelectList(u model.IMSUser) []model.IMSUser {
|
||||||
|
// 查询条件拼接
|
||||||
|
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 *IMSUserRepository) SelectByIMSIAndNeID(imsi, neId string) model.IMSUser {
|
||||||
|
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.IMSUser{}
|
||||||
|
}
|
||||||
|
// 转换实体
|
||||||
|
rows := r.convertResultRows(results)
|
||||||
|
if len(rows) > 0 {
|
||||||
|
return rows[0]
|
||||||
|
}
|
||||||
|
return model.IMSUser{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 批量添加
|
||||||
|
func (r *IMSUserRepository) Inserts(uArr []model.IMSUser) 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 *IMSUserRepository) Delete(imsi, neId string) int64 {
|
||||||
|
tx := datasource.DefaultDB().Where("imsi = ? and ne_id = ?", imsi, neId).Delete(&IMSUserRepository{})
|
||||||
|
if err := tx.Error; err != nil {
|
||||||
|
logger.Errorf("Delete err => %v", err)
|
||||||
|
}
|
||||||
|
return tx.RowsAffected
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePrefixByIMSI 删除前缀匹配的实体
|
||||||
|
func (r *IMSUserRepository) DeletePrefixByIMSI(imsiPrefix, neId string) int64 {
|
||||||
|
tx := datasource.DefaultDB().Where("imsi like concat(?, '%') and ne_id = ?", imsiPrefix, neId).Delete(&IMSUserRepository{})
|
||||||
|
if err := tx.Error; err != nil {
|
||||||
|
logger.Errorf("DeletePrefixByIMSI err => %v", err)
|
||||||
|
}
|
||||||
|
return tx.RowsAffected
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *IMSUserRepository) SetTenantID(subArr *[]model.IMSUser) {
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
268
features/ue/repository/voip_auth.go
Normal file
268
features/ue/repository/voip_auth.go
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
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/features/ue/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化数据层 VoIPAuthRepository 结构体
|
||||||
|
var NewVoIPAuthRepository = &VoIPAuthRepository{
|
||||||
|
selectSql: `select
|
||||||
|
s.id, s.ne_id, s.user_name, s.password,
|
||||||
|
t.tenant_id, t.tenant_name
|
||||||
|
from u_voip_auth s
|
||||||
|
left join sys_tenant t on t.tenant_id = s.tenant_id and t.status = 1`,
|
||||||
|
|
||||||
|
resultMap: map[string]string{
|
||||||
|
"id": "ID",
|
||||||
|
"ne_id": "NeId",
|
||||||
|
"user_name": "UserName",
|
||||||
|
"password": "Password",
|
||||||
|
|
||||||
|
|
||||||
|
"tenant_id": "TenantID",
|
||||||
|
"tenant_name": "TenantName", // Tenant name for multi-tenancy
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// VoIPAuthRepository UDM签约信息表 数据层处理
|
||||||
|
type VoIPAuthRepository struct {
|
||||||
|
// 查询视图对象SQL
|
||||||
|
selectSql string
|
||||||
|
// 结果字段与实体映射
|
||||||
|
resultMap map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertResultRows 将结果记录转实体结果组
|
||||||
|
func (r *VoIPAuthRepository) convertResultRows(rows []map[string]any) []model.VoIPAuth {
|
||||||
|
arr := make([]model.VoIPAuth, 0)
|
||||||
|
for _, row := range rows {
|
||||||
|
item := model.VoIPAuth{}
|
||||||
|
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 *VoIPAuthRepository) ClearAndInsert(neId string, u []model.VoIPAuth) int64 {
|
||||||
|
// 不指定neID时,用 TRUNCATE 清空表快
|
||||||
|
// _, err := datasource.ExecDB("", "TRUNCATE TABLE u_voip_auth", nil)
|
||||||
|
_, err := datasource.ExecDB("", "DELETE FROM u_voip_auth WHERE ne_id = ?", []any{neId})
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("TRUNCATE err => %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.Inserts(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectPage 根据条件分页查询字典类型
|
||||||
|
func (r *VoIPAuthRepository) SelectPage(query map[string]any) map[string]any {
|
||||||
|
// 查询条件拼接
|
||||||
|
var conditions []string
|
||||||
|
var params []any
|
||||||
|
if v, ok := query["userName"]; ok && v != "" {
|
||||||
|
conditions = append(conditions, "user_name like concat(concat('%', ?), '%')")
|
||||||
|
params = append(params, strings.Trim(v.(string), " "))
|
||||||
|
}
|
||||||
|
if v, ok := query["userNames"]; ok && v != "" {
|
||||||
|
placeholder := repo.KeyPlaceholderByQuery(len(v.([]any)))
|
||||||
|
conditions = append(conditions, fmt.Sprintf("user_name in (%s)", placeholder))
|
||||||
|
for _, v := range v.([]any) {
|
||||||
|
params = append(params, v.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for multi-tenancy solution
|
||||||
|
if v, ok := query["tenantName"]; ok && v != "" {
|
||||||
|
var tenantID []string
|
||||||
|
err := dborm.DefaultDB().Table("sys_tenant").
|
||||||
|
Where("tenant_name=? and status=1", 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)
|
||||||
|
query["neId"] = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.VoIPAuth{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询数量 长度为0直接返回
|
||||||
|
totalSql := "select count(1) as 'total' from u_voip_auth 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 *VoIPAuthRepository) SelectList(u model.VoIPAuth) []model.VoIPAuth {
|
||||||
|
// 查询条件拼接
|
||||||
|
var conditions []string
|
||||||
|
var params []any
|
||||||
|
if u.UserName != "" {
|
||||||
|
conditions = append(conditions, "user_name = ?")
|
||||||
|
params = append(params, u.UserName)
|
||||||
|
}
|
||||||
|
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 user_name asc "
|
||||||
|
results, err := datasource.RawDB("", querySql, params)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("query err => %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换实体
|
||||||
|
return r.convertResultRows(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectByUserNameAndNeID 根据用户名和网元ID查询
|
||||||
|
func (r *VoIPAuthRepository) SelectByUserNameAndNeID(userName, neId string) model.VoIPAuth {
|
||||||
|
querySql := r.selectSql + " where user_name = ? and ne_id = ?"
|
||||||
|
results, err := datasource.RawDB("", querySql, []any{userName, neId})
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("query err => %v", err)
|
||||||
|
return model.VoIPAuth{}
|
||||||
|
}
|
||||||
|
// 转换实体
|
||||||
|
rows := r.convertResultRows(results)
|
||||||
|
if len(rows) > 0 {
|
||||||
|
return rows[0]
|
||||||
|
}
|
||||||
|
return model.VoIPAuth{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 批量添加
|
||||||
|
func (r *VoIPAuthRepository) Inserts(uArr []model.VoIPAuth) 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 *VoIPAuthRepository) Delete(userName, neId string) int64 {
|
||||||
|
tx := datasource.DefaultDB().Where("user_name = ? and ne_id = ?", userName, neId).Delete(&VoIPAuthRepository{})
|
||||||
|
if err := tx.Error; err != nil {
|
||||||
|
logger.Errorf("Delete err => %v", err)
|
||||||
|
}
|
||||||
|
return tx.RowsAffected
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePrefixByUserName 删除以指定前缀的用户名
|
||||||
|
func (r *VoIPAuthRepository) DeletePrefixByUserName(userNamePrefix, neId string) int64 {
|
||||||
|
tx := datasource.DefaultDB().Where("user_name like concat(?, '%') and ne_id = ?", userNamePrefix, neId).Delete(&VoIPAuthRepository{})
|
||||||
|
if err := tx.Error; err != nil {
|
||||||
|
logger.Errorf("DeletePrefixByUserName err => %v", err)
|
||||||
|
}
|
||||||
|
return tx.RowsAffected
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *VoIPAuthRepository) SetTenantID(subArr *[]model.VoIPAuth) {
|
||||||
|
for s := 0; s < len(*subArr); s++ {
|
||||||
|
var tenantID []string
|
||||||
|
err := dborm.DefaultDB().Table("sys_tenant").
|
||||||
|
Where("status='1' and tenancy_type='MSISDN' and ? like tenancy_key", (*subArr)[s].UserName).
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
// log management package
|
|
||||||
|
|
||||||
package ue
|
|
||||||
|
|
||||||
import (
|
|
||||||
"be.ems/features/ue/file_export"
|
|
||||||
"be.ems/lib/log"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func InitSubServiceRoute(r *gin.Engine) {
|
|
||||||
log.Info("======init UE management group gin.Engine")
|
|
||||||
|
|
||||||
ueGroup := r.Group("/ue")
|
|
||||||
// register sub modules routes
|
|
||||||
file_export.Register(ueGroup)
|
|
||||||
}
|
|
||||||
211
features/ue/service/ims_user.go
Normal file
211
features/ue/service/ims_user.go
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"be.ems/src/framework/redis"
|
||||||
|
neService "be.ems/src/modules/network_element/service"
|
||||||
|
"be.ems/features/ue/model"
|
||||||
|
"be.ems/features/ue/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化服务层 IMSUserService 结构体
|
||||||
|
var NewIMSUserService = &IMSUserService{
|
||||||
|
imsUserRepository: repository.NewIMSUserRepository,
|
||||||
|
}
|
||||||
|
|
||||||
|
// VoLTE用户信息 服务层处理
|
||||||
|
type IMSUserService struct {
|
||||||
|
imsUserRepository *repository.IMSUserRepository // VoLTE用户信息数据信息
|
||||||
|
}
|
||||||
|
|
||||||
|
// dataByRedis UDM签约用户 db:0 中 volte:*
|
||||||
|
func (r *IMSUserService) dataByRedis(imsi, neId string) []model.IMSUser {
|
||||||
|
arr := []model.IMSUser{}
|
||||||
|
key := fmt.Sprintf("volte:%s", imsi)
|
||||||
|
source := fmt.Sprintf("UDM_%s", neId)
|
||||||
|
|
||||||
|
// 网元主机的Redis客户端
|
||||||
|
redisClient, err := neService.NewNeInfo.NeRunRedisClient("UDM", neId)
|
||||||
|
if err != nil {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
redisClient.Close()
|
||||||
|
redis.ConnectPush(source, nil)
|
||||||
|
}()
|
||||||
|
redis.ConnectPush(source, redisClient.Client)
|
||||||
|
|
||||||
|
udmsdArr, err := redis.GetKeys(source, key)
|
||||||
|
if err != nil {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
mkv, err := redis.GetHashBatch(source, udmsdArr)
|
||||||
|
if err != nil {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, m := range mkv {
|
||||||
|
var imsi, msisdn string
|
||||||
|
KeyParts := strings.Split(k, ":")
|
||||||
|
switch len(KeyParts) {
|
||||||
|
case 0, 1:
|
||||||
|
// 处理单个部分的情况
|
||||||
|
continue
|
||||||
|
case 2:
|
||||||
|
// 处理两个部分的情况
|
||||||
|
imsi = KeyParts[1]
|
||||||
|
msisdn = "-"
|
||||||
|
case 3:
|
||||||
|
// 处理三个部分的情况
|
||||||
|
imsi = KeyParts[1]
|
||||||
|
msisdn = KeyParts[2]
|
||||||
|
default:
|
||||||
|
// 处理更多部分的情况
|
||||||
|
imsi = KeyParts[1]
|
||||||
|
msisdn = KeyParts[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
var vni string = "-"
|
||||||
|
impiParts := strings.Split(m["impi"], "@")
|
||||||
|
if len(impiParts) > 1 {
|
||||||
|
vni = impiParts[1] // 输出: ims.mnc001.mcc110.3gppnetwork.org
|
||||||
|
}
|
||||||
|
a := model.IMSUser{
|
||||||
|
NeId: neId,
|
||||||
|
IMSI: imsi, // volte:360000100000130:8612300000130
|
||||||
|
MSISDN: msisdn, // 8612300000130
|
||||||
|
VoLTE: m["tag"], // volte = tag
|
||||||
|
VNI: vni, // ims.mnc001.mcc110.3gppnetwork.org
|
||||||
|
}
|
||||||
|
arr = append(arr, a)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据
|
||||||
|
func (r *IMSUserService) ResetData(neId string) int64 {
|
||||||
|
subArr := r.dataByRedis("*", neId)
|
||||||
|
// 数据清空后添加
|
||||||
|
go r.imsUserRepository.ClearAndInsert(neId, subArr)
|
||||||
|
return int64(len(subArr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseInfo 解析单个用户imsi签约信息 data从命令MML得到的结果
|
||||||
|
func (r *IMSUserService) ParseInfo(imsi, neId string, data map[string]string) model.IMSUser {
|
||||||
|
u := r.imsUserRepository.SelectByIMSIAndNeID(imsi, neId)
|
||||||
|
|
||||||
|
msisdn := data["MSISDN"]
|
||||||
|
if imsMsisdnLen := strings.Index(msisdn, ","); imsMsisdnLen != -1 {
|
||||||
|
msisdn = msisdn[:imsMsisdnLen]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用于更新
|
||||||
|
u.NeId = neId
|
||||||
|
u.IMSI = imsi
|
||||||
|
u.MSISDN = msisdn
|
||||||
|
u.VoLTE = data["VoLTE"]
|
||||||
|
u.VNI = data["VNI"]
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectPage 分页查询数据库
|
||||||
|
func (r *IMSUserService) SelectPage(query map[string]any) map[string]any {
|
||||||
|
return r.imsUserRepository.SelectPage(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectList 查询数据库
|
||||||
|
func (r *IMSUserService) SelectList(u model.IMSUser) []model.IMSUser {
|
||||||
|
return r.imsUserRepository.SelectList(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 从数据中读取后删除imsi再存入数据库
|
||||||
|
// imsi长度15,ki长度32,opc长度0或者32
|
||||||
|
func (r *IMSUserService) Insert(neId string, u model.IMSUser) int64 {
|
||||||
|
uArr := r.dataByRedis(u.IMSI, neId)
|
||||||
|
if len(uArr) > 0 {
|
||||||
|
r.imsUserRepository.Delete(u.IMSI, neId)
|
||||||
|
return r.imsUserRepository.Inserts(uArr)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertData 导入文件数据 dataType目前两种:txt/csv
|
||||||
|
func (r *IMSUserService) 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 volte:4600001000004*
|
||||||
|
arr := r.dataByRedis(prefix+"*", neId)
|
||||||
|
if len(arr) > 0 {
|
||||||
|
r.imsUserRepository.DeletePrefixByIMSI(prefix, neId)
|
||||||
|
num += r.imsUserRepository.Inserts(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 删除单个不重新加载
|
||||||
|
func (r *IMSUserService) Delete(neId, imsi string) int64 {
|
||||||
|
return r.imsUserRepository.Delete(imsi, neId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadData 重新加载从imsi开始num的数据
|
||||||
|
func (r *IMSUserService) 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.imsUserRepository.Delete(keyIMSI, neId)
|
||||||
|
arr := r.dataByRedis(keyIMSI, neId)
|
||||||
|
if len(arr) < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
r.imsUserRepository.Inserts(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseCommandParams 解析数据组成命令参数 msisdn=xx,xx=xx,...
|
||||||
|
func (r *IMSUserService) ParseCommandParams(item model.IMSUser) string {
|
||||||
|
var conditions []string
|
||||||
|
if item.MSISDN != "" {
|
||||||
|
conditions = append(conditions, fmt.Sprintf("msisdn=%s", item.MSISDN))
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.VoLTE != "" {
|
||||||
|
conditions = append(conditions, fmt.Sprintf("volte=%s", item.VoLTE))
|
||||||
|
}
|
||||||
|
if item.VNI != "" {
|
||||||
|
conditions = append(conditions, fmt.Sprintf("vni=%s", item.VNI))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(conditions, ",")
|
||||||
|
}
|
||||||
170
features/ue/service/voip_auth.go
Normal file
170
features/ue/service/voip_auth.go
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"be.ems/src/framework/redis"
|
||||||
|
neService "be.ems/src/modules/network_element/service"
|
||||||
|
"be.ems/features/ue/model"
|
||||||
|
"be.ems/features/ue/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化服务层 VoIPAuthService 结构体
|
||||||
|
var NewVoIPAuthService = &VoIPAuthService{
|
||||||
|
voipAuthRepository: repository.NewVoIPAuthRepository,
|
||||||
|
}
|
||||||
|
|
||||||
|
// VoLTE用户信息 服务层处理
|
||||||
|
type VoIPAuthService struct {
|
||||||
|
voipAuthRepository *repository.VoIPAuthRepository // VoLTE用户信息数据信息
|
||||||
|
}
|
||||||
|
|
||||||
|
// dataByRedis UDM签约用户 db:0 中 volte:*
|
||||||
|
func (r *VoIPAuthService) dataByRedis(userName, neId string) []model.VoIPAuth {
|
||||||
|
arr := []model.VoIPAuth{}
|
||||||
|
key := fmt.Sprintf("voip:%s", userName)
|
||||||
|
source := fmt.Sprintf("UDM_%s", neId)
|
||||||
|
|
||||||
|
// 网元主机的Redis客户端
|
||||||
|
redisClient, err := neService.NewNeInfo.NeRunRedisClient("UDM", neId)
|
||||||
|
if err != nil {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
redisClient.Close()
|
||||||
|
redis.ConnectPush(source, nil)
|
||||||
|
}()
|
||||||
|
redis.ConnectPush(source, redisClient.Client)
|
||||||
|
|
||||||
|
udmsdArr, err := redis.GetKeys(source, key)
|
||||||
|
if err != nil {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
mkv, err := redis.GetHashBatch(source, udmsdArr)
|
||||||
|
if err != nil {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, m := range mkv {
|
||||||
|
var userName string
|
||||||
|
KeyParts := strings.Split(k, ":")
|
||||||
|
if len(KeyParts) > 1 {
|
||||||
|
userName = KeyParts[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
a := model.VoIPAuth{
|
||||||
|
NeId: neId,
|
||||||
|
UserName: userName, // userName
|
||||||
|
Password: m["password"], //
|
||||||
|
}
|
||||||
|
arr = append(arr, a)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetData 重置鉴权用户数据,清空数据库重新同步Redis数据
|
||||||
|
func (r *VoIPAuthService) ResetData(neId string) int64 {
|
||||||
|
subArr := r.dataByRedis("*", neId)
|
||||||
|
// 数据清空后添加
|
||||||
|
go r.voipAuthRepository.ClearAndInsert(neId, subArr)
|
||||||
|
return int64(len(subArr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseInfo 解析单个用户userName信息 data从命令MML得到的结果
|
||||||
|
func (r *VoIPAuthService) ParseInfo(userName, neId string, data map[string]string) model.VoIPAuth {
|
||||||
|
u := r.voipAuthRepository.SelectByUserNameAndNeID(userName, neId)
|
||||||
|
password := data["password"]
|
||||||
|
|
||||||
|
// 用于更新
|
||||||
|
u.NeId = neId
|
||||||
|
u.UserName = userName
|
||||||
|
u.Password = password
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectPage 分页查询数据库
|
||||||
|
func (r *VoIPAuthService) SelectPage(query map[string]any) map[string]any {
|
||||||
|
return r.voipAuthRepository.SelectPage(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectList 查询数据库
|
||||||
|
func (r *VoIPAuthService) SelectList(u model.VoIPAuth) []model.VoIPAuth {
|
||||||
|
return r.voipAuthRepository.SelectList(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 从数据中读取后删除userName再存入数据库
|
||||||
|
func (r *VoIPAuthService) Insert(neId string, u model.VoIPAuth) int64 {
|
||||||
|
uArr := r.dataByRedis(u.UserName, neId)
|
||||||
|
if len(uArr) > 0 {
|
||||||
|
r.voipAuthRepository.Delete(u.UserName, neId)
|
||||||
|
return r.voipAuthRepository.Inserts(uArr)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertData 导入文件数据 dataType目前两种:txt/csv
|
||||||
|
func (r *VoIPAuthService) InsertData(neId, dataType string, data any) int64 {
|
||||||
|
// userName截取前缀,重新获取部分数据
|
||||||
|
prefixes := make(map[string]struct{})
|
||||||
|
|
||||||
|
if dataType == "csv" {
|
||||||
|
for _, v := range data.([]map[string]string) {
|
||||||
|
userName := v["userName"]
|
||||||
|
prefix := userName[:len(userName)-4]
|
||||||
|
prefixes[prefix] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if dataType == "txt" {
|
||||||
|
for _, v := range data.([][]string) {
|
||||||
|
userName := v[0]
|
||||||
|
prefix := userName[:len(userName)-4]
|
||||||
|
prefixes[prefix] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据前缀重新加载插入
|
||||||
|
var num int64 = 0
|
||||||
|
for prefix := range prefixes {
|
||||||
|
// keys volte:4600001000004*
|
||||||
|
arr := r.dataByRedis(prefix+"*", neId)
|
||||||
|
if len(arr) > 0 {
|
||||||
|
r.voipAuthRepository.DeletePrefixByUserName(prefix, neId)
|
||||||
|
num += r.voipAuthRepository.Inserts(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 删除单个不重新加载
|
||||||
|
func (r *VoIPAuthService) Delete(neId, userName string) int64 {
|
||||||
|
return r.voipAuthRepository.Delete(userName, neId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadData 重新加载从userName开始num的数据
|
||||||
|
func (r *VoIPAuthService) LoadData(neId, userName, num string) {
|
||||||
|
startUserName, _ := strconv.ParseInt(userName, 10, 64)
|
||||||
|
subNum, _ := strconv.ParseInt(num, 10, 64)
|
||||||
|
var i int64
|
||||||
|
for i = 0; i < subNum; i++ {
|
||||||
|
keyUserName := fmt.Sprintf("%d", startUserName+i)
|
||||||
|
// 删除原数据
|
||||||
|
r.voipAuthRepository.Delete(keyUserName, neId)
|
||||||
|
arr := r.dataByRedis(keyUserName, neId)
|
||||||
|
if len(arr) < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
r.voipAuthRepository.Inserts(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseCommandParams 解析数据组成命令参数 msisdn=xx,xx=xx,...
|
||||||
|
func (r *VoIPAuthService) ParseCommandParams(item model.VoIPAuth) string {
|
||||||
|
var conditions []string
|
||||||
|
if item.Password != "" {
|
||||||
|
conditions = append(conditions, fmt.Sprintf("password=%s", item.Password))
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(conditions, ",")
|
||||||
|
}
|
||||||
@@ -13,7 +13,8 @@ import (
|
|||||||
"be.ems/lib/dborm"
|
"be.ems/lib/dborm"
|
||||||
"be.ems/lib/log"
|
"be.ems/lib/log"
|
||||||
"be.ems/src/framework/cron"
|
"be.ems/src/framework/cron"
|
||||||
networkdata "be.ems/src/modules/network_data"
|
ueService "be.ems/features/ue/service"
|
||||||
|
neService "be.ems/src/modules/network_data/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
var NewProcessor = &BarProcessor{
|
var NewProcessor = &BarProcessor{
|
||||||
@@ -103,7 +104,7 @@ func (s *BarProcessor) exportUEData(param BarParams) (map[string]any, error) {
|
|||||||
for _, neID := range neIDs {
|
for _, neID := range neIDs {
|
||||||
log.Trace("ne_id:", neID)
|
log.Trace("ne_id:", neID)
|
||||||
// 1. 加载最新数据, 如果数据服务存在,则重新加载数据
|
// 1. 加载最新数据, 如果数据服务存在,则重新加载数据
|
||||||
dataService, err := networkdata.GetService(param.ServiceName)
|
dataService, err := GetService(param.ServiceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("failed to get data service:", err)
|
log.Warn("failed to get data service:", err)
|
||||||
} else if dataService != nil {
|
} else if dataService != nil {
|
||||||
@@ -224,3 +225,33 @@ func (s *BarProcessor) exportData(query, filePath string, fileType string) (int6
|
|||||||
|
|
||||||
return affected, nil
|
return affected, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResettableService 接口定义
|
||||||
|
type ResettableService interface {
|
||||||
|
ResetData(neID string) int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// 服务注册表
|
||||||
|
var serviceRegistry = make(map[string]ResettableService)
|
||||||
|
func RegisterService(name string, service ResettableService) {
|
||||||
|
serviceRegistry[name] = service
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取服务
|
||||||
|
func GetService(name string) (ResettableService, error) {
|
||||||
|
service, exists := serviceRegistry[name]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("service %s not found", name)
|
||||||
|
}
|
||||||
|
return service, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化注册表
|
||||||
|
func init() {
|
||||||
|
RegisterService("UDMAuthUser", neService.NewUDMAuthUser)
|
||||||
|
RegisterService("UDMSubUser", neService.NewUDMAuthUser)
|
||||||
|
RegisterService("UDMVoIPAuth", ueService.NewVoIPAuthService)
|
||||||
|
RegisterService("UDMIMSUser", ueService.NewIMSUserService)
|
||||||
|
|
||||||
|
// 这里注册更多服务
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
"be.ems/src/modules/network_data/service"
|
"be.ems/src/modules/network_data/service"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 模块路由注册
|
// 模块路由注册
|
||||||
@@ -324,34 +323,6 @@ func Setup(router *gin.Engine) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResettableService 接口定义
|
|
||||||
type ResettableService interface {
|
|
||||||
ResetData(neID string) int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// 服务注册表
|
|
||||||
var serviceRegistry = make(map[string]ResettableService)
|
|
||||||
func RegisterService(name string, service ResettableService) {
|
|
||||||
serviceRegistry[name] = service
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取服务
|
|
||||||
func GetService(name string) (ResettableService, error) {
|
|
||||||
service, exists := serviceRegistry[name]
|
|
||||||
if !exists {
|
|
||||||
return nil, fmt.Errorf("service %s not found", name)
|
|
||||||
}
|
|
||||||
return service, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化注册表
|
|
||||||
func init() {
|
|
||||||
RegisterService("UDMAuthUser", service.NewUDMAuthUser)
|
|
||||||
RegisterService("UDMSubUser", service.NewUDMSubUser)
|
|
||||||
|
|
||||||
// 这里注册更多服务
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitLoad 初始参数
|
// InitLoad 初始参数
|
||||||
func InitLoad() {
|
func InitLoad() {
|
||||||
// 启动时,加载UPF上下行流量
|
// 启动时,加载UPF上下行流量
|
||||||
|
|||||||
Reference in New Issue
Block a user