diff --git a/src/api/neData/sgwc.ts b/src/api/neData/sgwc.ts new file mode 100644 index 00000000..8b383256 --- /dev/null +++ b/src/api/neData/sgwc.ts @@ -0,0 +1,42 @@ +import { request } from '@/plugins/http-fetch'; + +/** + * 查询SGWC-CDR会话事件 + * @param query 查询参数 + * @returns object + */ +export function listSGWCDataCDR(query: Record) { + return request({ + url: '/neData/sgwc/cdr/list', + method: 'get', + params: query, + }); +} + +/** + * SGWC-CDR会话删除 + * @param id 信息ID + * @returns object + */ +export function delSGWCDataCDR(cdrIds: string | number) { + return request({ + url: `/neData/sgwc/cdr/${cdrIds}`, + method: 'delete', + timeout: 60_000, + }); +} + +/** + * SGWC-CDR会话列表导出 + * @param data 查询列表条件 + * @returns object + */ +export function exportSGWCDataCDR(data: Record) { + return request({ + url: '/neData/sgwc/cdr/export', + method: 'post', + data, + responseType: 'blob', + timeout: 60_000, + }); +} diff --git a/src/api/neData/smf.ts b/src/api/neData/smf.ts index 02b20e2f..a7d8c3c0 100644 --- a/src/api/neData/smf.ts +++ b/src/api/neData/smf.ts @@ -41,14 +41,27 @@ export function exportSMFDataCDR(data: Record) { }); } +/** + * SMF-在线订阅用户数量 + * @param query 查询参数 + * @returns object + */ +export function listSMFSubNum(neId: string) { + return request({ + url: '/neData/smf/sub/num', + method: 'get', + params: { neId }, + }); +} + /** * SMF-在线订阅用户列表信息 * @param query 查询参数 * @returns object */ -export function listSMFSubscribers(query: Record) { +export function listSMFSubList(query: Record) { return request({ - url: '/neData/smf/subscribers', + url: '/neData/smf/sub/list', method: 'get', params: query, }); diff --git a/src/constants/ne-constants.ts b/src/constants/ne-constants.ts index ec2282c9..cdf6b689 100644 --- a/src/constants/ne-constants.ts +++ b/src/constants/ne-constants.ts @@ -4,6 +4,7 @@ export const NE_TYPE_LIST = [ 'IMS', 'AMF', 'AUSF', + 'UDR', 'UDM', 'SMF', 'PCF', @@ -19,6 +20,8 @@ export const NE_TYPE_LIST = [ 'SMSF', 'CBC', 'CHF', + 'HLR', + 'SGWC', ]; /** diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index 5566b4da..0cdcc16d 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -222,12 +222,11 @@ export default { capability: 'Capability', serialNum: 'Serial Number', expiryDate: 'Expiry Date', - neStatus: 'NE status is abnormal', - runStatus:'Running Status', - mark:'Brief Information', + neStatus: 'Status Abnormal', + runStatus:'Status', + mark:'Information', object:'Object', versionNum:'Version', - systemStatus:'Status', realNeStatus:'Status', reloadTime:'Refresh Time', Critical:'Critical', @@ -351,163 +350,6 @@ export default { description: "No data yet, try refreshing", }, }, - configManage: { - neManage: { - addNe:'Add Network Element', - delSure:'Confirm deleting the data item with network element name {msg}', - editNe:'Edit Network Element', - exportSure:'Confirm exporting the configuration information with the network element name {msg}', - exportTip:'Export successful, please go to backup management for download', - getInfo:'Failed to get network element information', - neType:'NE Type', - neTypePlease: 'Select network element type', - neId:'NE ID', - neName:'NE Name', - neTypeTip:'Fill in the type of network element created, such as:SMF', - uid:'RM UID', - uidTip:'Please enter a unique resource identifier', - ip:'IP Address', - mac:'NE MAC address', - macTip:'Able to locate the physical address (MAC) of the network element', - port:'Port', - portTip:'Maximum range 0~65535', - pvflag:'PV Flag', - pnf:'Physical Network Element', - vnf:'Virtual Network Element', - province:'Region', - vendorName:'Vendor Name', - dn:'Network Identification', - reload: 'Reload', - restart: 'Restart', - totalSure:'Confirm the network element with {operator} network element name {msg}', - stop: 'Stop', - start: 'Start', - log: 'Logs', - export: 'Export', - import: 'Import', - fileForm:'File Source', - selectPlease:'Please select the source of the import file', - server:'Server File', - local:'Local File', - fileSelect:'Please select the current import file', - sync:'Synchronize to NE', - open:'Open', - close:'Close', - addFail:'Add failed', - operFail:'Operation Failed' - }, - backupManage: { - setBackupTask: 'Set automatic backup time', - neTypePlease: 'Query network element type', - neType: 'NE Type', - neID: 'NE ID', - fileName: 'File Name', - createAt: 'Create at', - remark:'Remark', - edit:'Edit Backup File', - totalSure:'Confirm that {oper} records item number {id}?', - }, - softwareManage: { - sendBtn: 'Distribute', - runBtn: 'Activate', - backBtn: 'Rollback', - historyBtn: 'Distribution Record', - neTypePlease: 'Select network element type', - neType: 'NE Type', - fileName: 'File Name', - version: 'Version', - versionPlease: 'Version number cannot be empty', - updateTime: 'Uploaded Time', - description: 'Description', - deleteTip: 'Are you sure to delete the data item with software [{fileName}]?', - downloadTip: 'Are you sure to download the data item with software [{fileName}]?', - updateComment: 'Comment', - updateCommentPlease: 'Please enter the software description', - updateFile: 'Software File', - updateFilePlease: 'Please upload the updated software file', - verifyFile: 'Verify File', - selectFile: 'SELECT FILE', - sendTitle: 'Distribute software version', - sendContent: 'Are you sure to send the file with the software package [{fileName}] to the corresponding network element?', - runTitle: 'Activate software version', - runContent: 'Are you sure to activate the software version of [{fileName}] that has been issued to the corresponding network element?', - backTitle: 'Fallback software version', - backContent: 'Confirm that the software version of [{fileName}] has been issued for the corresponding network element rollback?', - neId: 'Corresponding network element', - neIdPlease: 'Please select the corresponding network element', - versions:'Version', - upVersions:'Version before upgrade', - backVersions:'Version before rollback', - status:'Status', - letUpTime:'Activation time', - createTime:'Creation time', - onlyAble:'Only upload file format {fileText} is supported', - nullVersion:'There is no rollback version for the current network element.', - }, - license: { - neTypePlease: 'Select network element type', - neType: 'NE Type', - serialNum: 'Serial Num', - createTime: 'Time', - comment: 'Description', - updateComment: 'License Description', - updateCommentPlease: 'Please enter a license description', - updateFile: 'License File', - updateFilePlease: 'Please upload and update the License file', - selectFile: 'SELECT FILE', - neId: 'NE ID', - neIdPlease: 'Please select the corresponding network element', - }, - configParam:{ - dataNull:'No configuration item data yet', - editSuss:'Modification successful', - editFail:'Edit failed', - Unable:'Illegal operation of attribute value', - delSure:'Confirm to delete the data item with Index [{value}]?', - addSuss:'Add successfully', - addFail:'Add failed', - delArraySure:'Confirm to delete the data item with {arrayChildTitle} Index as [{value}]?', - parUnable:'The parameter value is not within the reasonable range', - ipv4Tip:'Not a legal IPV4 address', - ipv6Tip:'Not a legal IPV6 address', - enumTip:'Not a reasonable enumeration value', - boolTip:'Not a reasonable Boolean value', - default:'The input value is of unknown type', - reloadSuss:'Network element reloading completed', - reloadFail:'Network element reloading failed', - neNUll:'No network element list data yet', - reload:'Reload', - post:'Submit', - editSure:'Are you sure you want to update this attribute value? ', - arraryEdit:'Are you sure to submit the record whose updated Index is [{value}]? ', - addSure:'Are you sure to submit the new record of Index: [{value}]? ' - }, - configParamForm: { - treeTitle: "Navigation Configuration", - treeSelectTip: "Select configuration item information in the left configuration navigation!", - neType: 'NE Type', - neTypePleace: "Please select the network element type", - noConfigData: "No data on configuration items", - updateValue: "[ {num} ] parameter value modified successfully.", - updateValueErr: "Attribute value modification failure", - updateItem: "Modify Index to {num}.", - updateItemErr: "Record modification failure", - delItemOk: "Deleting Index as {num} succeeded", - addItemOk: "Add Index as {num} Record Succeeded", - addItemErr: "Record addition failure", - requireUn: "[ {display} ] input value is of unknown type", - requireString: "[ {display} ] parameter value is invalid.", - requireInt: "[ {display} ] parameter value not in reasonable range {filter}", - requireIpv4: "[ {display} ] not a legitimate IPV4 address", - requireIpv6: "[ {display} ] not a legitimate IPV6 address.", - requireEnum: "[ {display} ] is not a reasonable enumeration value.", - requireBool: "[ {display} ] is not a reasonable boolean value.", - editOkTip: "Confirm updating the value of this [ {num} ] attribute?", - updateItemTip: "Confirm updating the data item with Index [{num}]?", - delItemTip: "Confirm deleting the data item with Index [{num}]?", - arrayMore: "Expand", - }, - }, dashboard: { overview:{ title: "Core Network Dashboard", @@ -579,14 +421,18 @@ export default { resultFail: "Fail", delTip: "Confirm deletion of the data item numbered [{msg}]?", exportTip: "Do you confirm to export the current query conditions of the CDR data? (Maximum 10,000 items can be exported.)", - smfChargingID: 'Charging ID', + chargingID: 'Charging ID', smfSubscriptionIDData: 'Subscription ID Data', smfSubscriptionIDType: 'Subscription ID Type', smfDataVolumeUplink: 'Data Volume Uplink', smfDataVolumeDownlink: 'Data Volume Downlink', smfDataTotalVolume: 'Data Total Volume', - smfDuration: 'Duration', - smfInvocationTime: 'Invocation Time', + durationTime: 'Duration', + invocationTime: 'Invocation Time', + sgwcServedIMSI: 'IMSI', + sgwcServedMSISDN: 'MSISDN', + sgwcVolumeGPRSUplink: 'GPRS Uplink', + sgwcVolumeGPRSDownlink: 'GPRS Downlink', }, ue: { eventType: "Event Type", @@ -784,7 +630,9 @@ export default { treeSelectTip: "Select configuration item information in the left configuration navigation!", neType: 'NE Type', neTypePleace: "Please select the network element type", + neIdSyncPleace: "Please select the synchronized network element", noConfigData: "No data on configuration items", + noConfigdDisabled: "The configuration item is not normal", updateValue: "[ {num} ] parameter value modified successfully.", updateValueErr: "Attribute value modification failure", updateItem: "Modify Index to {num}.", diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 5a77cb6b..4966eec9 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -222,13 +222,12 @@ export default { capability: '用户容量', serialNum: '序列号', expiryDate: '许可证到期日期', - neStatus:'网元状态异常', + neStatus:'状态异常', runStatus:'运行状态', - mark:'简略信息', + mark:'信息', object:'对象', versionNum:'版本号', - systemStatus:'系统状态', - realNeStatus:'网元状态', + realNeStatus:'状态', reloadTime:'刷新时间', Critical:'严重告警', Major:'主要告警', @@ -351,163 +350,6 @@ export default { description: "暂无数据,尝试刷新看看", }, }, - configManage: { - neManage: { - addNe:'添加网元', - delSure:'确认删除网元名称为{msg}的数据项 ', - editNe:'修改网元', - exportSure:'确认导出网元名称为 {msg} 的配置信息', - exportTip:'导出成功,请到备份管理进行下载', - getInfo:'获取网元信息失败', - neType:'网元类型', - neTypePlease: '请输入网元类型', - neId:'网元内部标识', - neName:'网元名称', - neTypeTip:'填写创建的网元类型,如:SMF', - uid:'资源唯一标识', - uidTip:'请输入资源唯一标识', - ip:'IP地址', - mac:'网元物理地址', - macTip:'能够定位网元的物理地址(MAC)', - port:'端口', - portTip:'最大范围0~65535', - pvflag:'网元虚拟化标识', - pnf:'物理网元', - vnf:'虚拟网元', - province:'网元服务省份', - vendorName:'厂商名称', - dn:'网络标识', - reload: '重载', - restart: '重启', - totalSure:'确认{oper}网元名称为 {msg} 的网元', - stop: '停止', - start: '启动', - log: '日志', - export: '导出', - import: '导入', - fileForm:'文件来源', - selectPlease:'请选择导入文件来源', - server:'服务器文件', - local:'本地文件', - fileSelect:'请选择当前导入文件', - sync:'同步到网元', - open:'开', - close:'关', - addFail:'新增失败', - operFail:'操作失败' - }, - backupManage: { - setBackupTask: '设置自动备份时间', - neTypePlease: '查询网元类型', - neType: '网元类型', - neID: '网元内部标识', - fileName: '文件名', - createAt: '创建时间', - remark:'备份说明', - edit:'编辑备份文件', - totalSure:'确认{oper}记录编号为 {id} 的数据项?', - }, - softwareManage: { - sendBtn: '下发', - runBtn: '激活', - backBtn: '回退', - historyBtn: '下发记录', - neTypePlease: '选择网元类型', - neType: '网元类型', - fileName: '文件名', - version: '版本号', - versionPlease: '版本号不能为空', - updateTime: '上传时间', - description: '功能描述', - deleteTip: '确认删除 【{fileName}】 的软件数据项?', - downloadTip: '确认下载 【{fileName}】 的软件数据项?', - updateComment: '软件说明', - updateCommentPlease: '请输入软件说明', - updateFile: '软件文件', - updateFilePlease: '请上传更新软件文件', - verifyFile: '校验文件', - selectFile: '选择文件', - sendTitle: '下发软件版本', - sendContent: '确认下发软件包为【{fileName}】的文件到对应网元?', - runTitle: '激活软件版本', - runContent: '确认在对应网元激活已下发【{fileName}】的软件版本?', - backTitle: '回退软件版本', - backContent: '确认在对应网元回退已下发【{fileName}】的软件版本?', - neId: '对应网元', - neIdPlease: '请选择对应网元', - versions:'版本', - upVersions:'升级前版本', - backVersions:'回退前版本', - status:'状态', - letUpTime:'激活时间', - createTime:'创建时间', - onlyAble:'只支持上传文件格式 {fileText}', - nullVersion:'当前网元无可回退版本', - }, - license: { - neTypePlease: '选择网元类型', - neType: '网元类型', - serialNum: '序列号', - createTime: '时间', - comment: '说明', - updateComment: 'License说明', - updateCommentPlease: '请输入License说明', - updateFile: 'License文件', - updateFilePlease: '请上传更新License文件', - selectFile: '选择文件', - neId: '网元内部标识', - neIdPlease: '请选择对应网元', - }, - configParam:{ - dataNull:'暂无配置项数据', - editSuss:'修改成功', - editFail:'修改失败', - unable:'非法操作属性值', - delSure:'确认删除Index为 【{value}】 的数据项?', - addSuss:'新增成功', - addFail:'新增失败', - delArraySure:'确认删除{arrayChildTitle} Index 为 【{value}】 的数据项?', - parUnable:'参数值不在合理范围', - ipv4Tip:'不是合法的IPV4地址', - ipv6Tip:'不是合法的IPV6地址', - enumTip:'不是合理的枚举值', - boolTip:'不是合理的布尔类型的值', - default:'输入值是未知类型', - reloadSuss:'网元重新加载完成', - reloadFail:'网元重新加载失败', - neNUll:'暂无网元列表数据', - reload:'重载', - post:'提交', - editSure:'确认更新该属性值吗?', - arraryEdit:'确认提交更新 Index 为 【{value}】 的记录吗?', - addSure:'确认提交新增 Index :【{value}】 的记录吗?', - }, - configParamForm: { - treeTitle: "配置导航", - treeSelectTip: "左侧配置导航中选择配置项信息!", - neType: "网元类型", - neTypePleace: "请选择网元类型", - noConfigData: "暂无配置项数据", - updateValue: "【 {num} 】 属性值修改成功", - updateValueErr: "属性值修改失败", - updateItem: "修改 Index 为 {num} 记录成功", - updateItemErr: "记录修改失败", - delItemOk: "删除 Index 为 {num} 记录成功", - addItemOk: "新增 Index 为 {num} 记录成功", - addItemErr: "记录新增失败", - requireUn: "【 {display} 】输入值是未知类型", - requireString: "【 {display} 】参数值不合理", - requireInt: "【 {display} 】参数值不在合理范围 {filter}", - requireIpv4: "【 {display} 】不是合法的IPV4地址", - requireIpv6: "【 {display} 】不是合法的IPV6地址", - requireEnum: "【 {display} 】不是合理的枚举值", - requireBool: "【 {display} 】不是合理的布尔类型的值", - editOkTip: "确认更新该【 {num} 】属性值吗?", - updateItemTip: "确认更新Index为 【{num}】 的数据项?", - delItemTip: "确认删除Index为 【{num}】 的数据项?", - arrayMore: "展开", - }, - }, dashboard: { overview:{ title: "核心网系统看板", @@ -579,14 +421,18 @@ export default { resultFail: "失败", delTip: "确认删除编号为【{msg}】的数据项?", exportTip: "确认导出当前查询条件的话单数据吗?(导出最大支持一万条)", - smfChargingID: '计费ID', + chargingID: '计费ID', smfSubscriptionIDData: '订阅 ID 数据', smfSubscriptionIDType: '订阅 ID 类型', smfDataVolumeUplink: '数据量上行链路', smfDataVolumeDownlink: '数据量下行链路', smfDataTotalVolume: '数据总量', - smfDuration: '持续时间', - smfInvocationTime: '调用时间', + durationTime: '持续时间', + invocationTime: '调用时间', + sgwcServedIMSI: 'IMSI', + sgwcServedMSISDN: 'MSISDN', + sgwcVolumeGPRSUplink: 'GPRS 上行链路', + sgwcVolumeGPRSDownlink: 'GPRS 下行链路', }, ue: { eventType: "事件类型", @@ -784,7 +630,9 @@ export default { treeSelectTip: "左侧配置导航中选择配置项信息!", neType: "网元类型", neTypePleace: "请选择网元类型", + neIdSyncPleace: "请选择同步网元", noConfigData: "暂无配置项数据", + noConfigdDisabled: "配置项网元未正常服务", updateValue: "【 {num} 】 属性值修改成功", updateValueErr: "属性值修改失败", updateItem: "修改 Index 为 {num} 记录成功", diff --git a/src/utils/parse-tree-utils.ts b/src/utils/parse-tree-utils.ts index 0698054c..0791f050 100644 --- a/src/utils/parse-tree-utils.ts +++ b/src/utils/parse-tree-utils.ts @@ -126,7 +126,7 @@ export function parseDataToTreeExclude( } /** - * 解析树结构数据转出一维id数组 + * 解析树结构数据转出所有一维id数组 * * @param data 数组数据 * @param fieldId 读取节点字段 默认 'id' @@ -158,7 +158,7 @@ export function parseTreeKeys( } /** - * 解析树结构数据转出含子节点的一维id数组 + * 解析树结构数据转出根节点的一维id数组 * * @param data 数组数据 * @param fieldId 读取节点字段 默认 'id' @@ -221,3 +221,43 @@ export function parseDataToOptions( return options; } + +/** + * 解析树结构数据转出子节点关联根节点的一维id数组 + * + * @param data 数组数据 + * @param checkedKeys 子节点数组数据 + * @param fieldId 读取节点字段 默认 'id' + * @param fieldChildren 读取子节点字段 默认 'children' + * @returns 层级数组 + */ +export function parseTreeNodeKeysByChecked( + data: Record[], + checkedKeys: (string | number)[], + fieldId: string = 'id', + fieldChildren: string = 'children' +) { + // 节点id + let treeIds: (string | number)[] = []; + componet(data); + /**闭包递归函数 */ + function componet(data: Record[]) { + if (data.length <= 0) return false; + let hasKey = false; + for (const iterator of data) { + const key = iterator[fieldId]; + if (checkedKeys.includes(key)) { + hasKey = true; + } + let nodes = iterator[fieldChildren]; + if (Array.isArray(nodes) && nodes.length > 0) { + if (componet(nodes)) { + treeIds.push(key); + hasKey = true; + } + } + } + return hasKey; + } + return treeIds; +} diff --git a/src/views/configManage/neManage/index.vue b/src/views/configManage/neManage/index.vue deleted file mode 100644 index de374d4a..00000000 --- a/src/views/configManage/neManage/index.vue +++ /dev/null @@ -1,1275 +0,0 @@ - - - - - diff --git a/src/views/configManage/neOverview/index.vue b/src/views/configManage/neOverview/index.vue index a2492040..aa2e49c6 100644 --- a/src/views/configManage/neOverview/index.vue +++ b/src/views/configManage/neOverview/index.vue @@ -49,7 +49,6 @@ let indexColor = ref([ ]); /**表格字段列 */ -//customRender(){} ----单元格处理 let tableColumns: ColumnsType = [ { title: t('views.index.object'), @@ -67,7 +66,9 @@ let tableColumns: ColumnsType = [ dataIndex: 'serverState', align: 'left', customRender(opt) { - if (opt.value?.refreshTime) return parseDateToStr(opt.value?.refreshTime); + if (opt.value?.refreshTime) { + return parseDateToStr(opt.value?.refreshTime, 'HH:mm:ss'); + } return '-'; }, }, @@ -104,12 +105,13 @@ let tableColumns: ColumnsType = [ }, }, ]; + /**表格状态类型 */ type TabeStateType = { /**加载等待 */ loading: boolean; /**记录数据 */ - data: object[]; + data: Record[]; /**勾选记录 */ selectedRowKeys: (string | number)[]; }; @@ -121,105 +123,75 @@ let tableState: TabeStateType = reactive({ selectedRowKeys: [], }); -/**表格状态 */ -let nfInfo: any = reactive({ - obj: 'OMC', - version: appStore.version, - status: t('views.index.normal'), - outTimeDate: '', - serialNum: appStore.serialNum, -}); - -/**表格状态类型 */ -type nfStateType = { - /**主机名 */ - hostName: string; - /**操作系统信息 */ - osInfo: string; - /**IP地址 */ - ipAddress: string; - /**版本 */ - version: string; - /**CPU利用率 */ - cpuUse: string; - /**内存使用 */ - memoryUse: string; - /**用户容量 */ - capability: number; - /**序列号 */ - serialNum: string; - /**许可证到期日期 */ - /* selectedRowKeys: (string | number)[];*/ - expiryDate: string; -}; -/**网元详细信息 */ -let pronInfo: nfStateType = reactive({ - hostName: '5gc', - osInfo: 'Linux 5gc 4.15.0-112-generic 2020 x86_64 GNU/Linux', - ipAddress: '-', - version: '-', - cpuUse: '-', - memoryUse: '-', - capability: 0, - serialNum: '-', - expiryDate: '-', -}); +/**状态 */ +let serverState: any = ref({}); /**查询网元状态列表 */ function fnGetList(one: boolean) { if (tableState.loading) return; - one && (tableState.loading = true); - listAllNeInfo({ bandStatus: true }).then(res => { - tableState.data = res.data; - tableState.loading = false; - var rightNum = 0; - var errorNum = 0; - res.data.forEach((item: any) => { - if (item.serverState.online) { - rightNum++; + if (one) { + tableState.loading = true; + } + listAllNeInfo({ bandStatus: true }) + .then(res => { + tableState.data = res.data; + tableState.loading = false; + if (one && res.data.length > 0) { + const id = res.data[0].id; + fnTableSelectedRowKeys([id]); } else { - errorNum++; + fnTableSelectedRowKeys(tableState.selectedRowKeys); } - }); - const optionData: any = { - title: { - text: '', - subtext: '', - left: 'center', - }, - tooltip: { - trigger: 'item', - }, - legend: { - orient: 'vertical', - left: 'left', - }, - color: indexColor.value.map(item => item.tagClass), - series: [ - { - name: t('views.index.realNeStatus'), - type: 'pie', - radius: '70%', - center: ['50%', '50%'], - data: [ - { value: rightNum, name: t('views.index.normal') }, - { value: errorNum, name: t('views.index.abnormal') }, - ], - emphasis: { - itemStyle: { - shadowBlur: 10, - shadowOffsetX: 0, - shadowColor: 'rgba(0, 0, 0, 0.5)', - }, - }, - - label: {}, + }) + .finally(() => { + var rightNum = 0; + var errorNum = 0; + for (const v of tableState.data) { + if (v?.serverState?.online) { + rightNum++; + } else { + errorNum++; + } + } + /// 图表数据 + const optionData: any = { + title: { + text: '', + subtext: '', + left: 'center', }, - ], - }; + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + left: 'left', + }, + color: indexColor.value.map(item => item.tagClass), + series: [ + { + name: t('views.index.realNeStatus'), + type: 'pie', + radius: '70%', + center: ['50%', '50%'], + data: [ + { value: rightNum, name: t('views.index.normal') }, + { value: errorNum, name: t('views.index.abnormal') }, + ], + emphasis: { + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)', + }, + }, - fnDesign(statusBar.value, optionData); - }); + label: {}, + }, + ], + }; + fnDesign(statusBar.value, optionData); + }); } function fnDesign(container: HTMLElement | undefined, option: any) { @@ -240,66 +212,43 @@ function fnDesign(container: HTMLElement | undefined, option: any) { observer.observe(container); } -/**抽屉 网元详细信息 */ -const open = ref(false); -const closeDrawer = () => { - open.value = false; -}; -/**抽屉 网元详细信息 */ +/**表格多选 */ +function fnTableSelectedRowKeys(keys: (string | number)[]) { + if (keys.length <= 0) return; + const id = keys[0]; + const row: any = tableState.data.find((item: any) => item.id === id); + if (!row) { + message.error(t('views.index.neStatus'), 2); + return; + } + const neState = row.serverState; + if (!neState?.online) { + message.error(t('views.index.neStatus'), 2); + return; + } + tableState.selectedRowKeys = keys; + // Mem 将KB转换为MB + const totalMemInKB = neState.mem?.totalMem; + const nfUsedMemInKB = neState.mem?.nfUsedMem; + const sysMemUsageInKB = neState.mem?.sysMemUsage; + const totalMemInMB = Math.round((totalMemInKB / 1024) * 100) / 100; + const nfUsedMemInMB = Math.round((nfUsedMemInKB / 1024) * 100) / 100; + const sysMemUsageInMB = Math.round((sysMemUsageInKB / 1024) * 100) / 100; -/**监听表格行事件*/ -function rowClick(record: any, index: any) { - return { - onClick: (event: any) => { - let pronData = JSON.parse(JSON.stringify(record.serverState)); - if (!pronData.online) { - message.error(t('views.index.neStatus'), 2); - return false; - } else { - const totalMemInKB = pronData.mem?.totalMem; - const nfUsedMemInKB = pronData.mem?.nfUsedMem; - const sysMemUsageInKB = pronData.mem?.sysMemUsage; + // CPU + const nfCpu = neState.cpu?.nfCpuUsage; + const sysCpu = neState.cpu?.sysCpuUsage; + const nfCpuP = Math.round(nfCpu) / 100; + const sysCpuP = Math.round(sysCpu) / 100; - // 将KB转换为MB - const totalMemInMB = Math.round((totalMemInKB / 1024) * 100) / 100; - const nfUsedMemInMB = Math.round((nfUsedMemInKB / 1024) * 100) / 100; - const sysMemUsageInMB = - Math.round((sysMemUsageInKB / 1024) * 100) / 100; - - //渲染详细信息 - pronInfo = { - hostName: pronData.hostname, - osInfo: pronData.os, - ipAddress: pronData.neIP, - version: pronData.version, - cpuUse: - pronData.neName + - ':' + - pronData.cpu?.nfCpuUsage / 100 + - '%; ' + - 'SYS:' + - pronData.cpu?.sysCpuUsage / 100 + - '%', - memoryUse: - 'Total:' + - totalMemInMB + - 'MB; ' + - pronData.name + - ':' + - nfUsedMemInMB + - 'MB; SYS:' + - sysMemUsageInMB + - 'MB', - capability: pronData.capability, - serialNum: pronData.sn, - expiryDate: pronData.expire, - }; - } - open.value = true; + serverState.value = Object.assign( + { + cpuUse: `NE:${nfCpuP}%; SYS:${sysCpuP}%`, + memoryUse: `Total: ${totalMemInMB}MB; NE: ${nfUsedMemInMB}MB; SYS: ${sysMemUsageInMB}MB`, }, - }; + neState + ); } -let timer: any; /** * 国际化翻译转换 @@ -312,6 +261,7 @@ function fnLocale() { appStore.setTitle(title); } +let timer: any; onMounted(() => { getDict('index_status') .then(res => { @@ -322,12 +272,11 @@ onMounted(() => { .finally(() => { fnLocale(); fnGetList(true); - timer = setInterval(() => fnGetList(false), 10000); // 每隔10秒执行一次 + timer = setInterval(() => fnGetList(false), 10_000); // 每隔10秒执行一次 }); }); // 在组件卸载之前清除定时器 - onBeforeUnmount(() => { clearInterval(timer); }); @@ -335,40 +284,6 @@ onBeforeUnmount(() => { diff --git a/src/views/dashboard/overview/components/UserActivity/index.vue b/src/views/dashboard/overview/components/UserActivity/index.vue index 1a2af1eb..1cb9d6c9 100644 --- a/src/views/dashboard/overview/components/UserActivity/index.vue +++ b/src/views/dashboard/overview/components/UserActivity/index.vue @@ -77,8 +77,12 @@ onMounted(() => {
{{ t('views.dashboard.overview.userActivity.time') }}:  - - {{ parseDateToStr(item.data.releaseTime * 1000) }} + + {{ + typeof item.data.releaseTime === 'number' + ? parseDateToStr(+item.data.releaseTime * 1000) + : item.data.releaseTime + }}
@@ -203,7 +207,11 @@ onMounted(() => {
{{ t('views.dashboard.overview.userActivity.time') }}: - {{ parseDateToStr(+item.data?.timestamp * 1000) }} + {{ + typeof item.data?.timestamp === 'number' + ? parseDateToStr(+item.data?.timestamp * 1000) + : item.data?.timestamp + }}
diff --git a/src/views/dashboard/overview/index.vue b/src/views/dashboard/overview/index.vue index 94c8e8de..e9fde2ac 100644 --- a/src/views/dashboard/overview/index.vue +++ b/src/views/dashboard/overview/index.vue @@ -102,7 +102,7 @@ function fnGetNeState() { /**获取概览信息 */ async function fnGetSkim() { - console.log(neCascaderOptions.value); + // console.log(neCascaderOptions.value); // const resArr = await Promise.allSettled([ // listUDMSub({ // neid: '001', @@ -234,7 +234,7 @@ function loadData() { clearInterval(interval10s.value); interval10s.value = setInterval(() => { - if (!interval10s.value) return + if (!interval10s.value) return; if (upfTFActive.value === '0') { upfTFSend('7'); upfTFActive.value = '7'; @@ -249,7 +249,7 @@ function loadData() { clearInterval(interval5s.value); interval5s.value = setInterval(() => { - if (!interval5s.value) return + if (!interval5s.value) return; fnGetSkim(); // 获取概览信息 fnGetNeState(); // 获取网元状态 }, 5_000); diff --git a/src/views/dashboard/sgwcCDR/index.vue b/src/views/dashboard/sgwcCDR/index.vue new file mode 100644 index 00000000..a57d62e0 --- /dev/null +++ b/src/views/dashboard/sgwcCDR/index.vue @@ -0,0 +1,815 @@ + + + + + diff --git a/src/views/dashboard/smfCDR/index.vue b/src/views/dashboard/smfCDR/index.vue index b5b226e3..f4951320 100644 --- a/src/views/dashboard/smfCDR/index.vue +++ b/src/views/dashboard/smfCDR/index.vue @@ -19,6 +19,8 @@ import { import { OptionsType, WS } from '@/plugins/ws-websocket'; import PQueue from 'p-queue'; import saveAs from 'file-saver'; +import { useClipboard } from '@vueuse/core'; +const { copy } = useClipboard({ legacy: true }); const { t } = useI18n(); const ws = new WS(); const queue = new PQueue({ concurrency: 1, autoStart: true }); @@ -94,7 +96,7 @@ let tableColumns: ColumnsType = [ width: 100, }, { - title: t('views.dashboard.cdr.smfChargingID'), // 计费ID + title: t('views.dashboard.cdr.chargingID'), // 计费ID dataIndex: 'cdrJSON', align: 'left', width: 100, @@ -137,11 +139,15 @@ let tableColumns: ColumnsType = [ ) { return 0; } - const usedUnitContainer = listOfMultipleUnitUsage[0].usedUnitContainer; - if (!Array.isArray(usedUnitContainer) || usedUnitContainer.length < 1) { - return 0; + let dataVolumeUplink = 0; + for (const v of listOfMultipleUnitUsage) { + if (Array.isArray(v.usedUnitContainer)) { + for (const used of v.usedUnitContainer) { + dataVolumeUplink += +used.dataVolumeUplink; + } + } } - return usedUnitContainer[0].dataVolumeUplink; + return dataVolumeUplink; }, }, { @@ -158,11 +164,15 @@ let tableColumns: ColumnsType = [ ) { return 0; } - const usedUnitContainer = listOfMultipleUnitUsage[0].usedUnitContainer; - if (!Array.isArray(usedUnitContainer) || usedUnitContainer.length < 1) { - return 0; + let dataVolumeDownlink = 0; + for (const v of listOfMultipleUnitUsage) { + if (Array.isArray(v.usedUnitContainer)) { + for (const used of v.usedUnitContainer) { + dataVolumeDownlink += +used.dataVolumeDownlink; + } + } } - return usedUnitContainer[0].dataVolumeDownlink; + return dataVolumeDownlink; }, }, { @@ -179,15 +189,19 @@ let tableColumns: ColumnsType = [ ) { return 0; } - const usedUnitContainer = listOfMultipleUnitUsage[0].usedUnitContainer; - if (!Array.isArray(usedUnitContainer) || usedUnitContainer.length < 1) { - return 0; + let dataTotalVolume = 0; + for (const v of listOfMultipleUnitUsage) { + if (Array.isArray(v.usedUnitContainer)) { + for (const used of v.usedUnitContainer) { + dataTotalVolume += +used.dataTotalVolume; + } + } } - return usedUnitContainer[0].dataTotalVolume; + return dataTotalVolume; }, }, { - title: t('views.dashboard.cdr.smfDuration'), // 持续时间 + title: t('views.dashboard.cdr.durationTime'), // 持续时间 dataIndex: 'cdrJSON', align: 'left', width: 100, @@ -197,7 +211,7 @@ let tableColumns: ColumnsType = [ }, }, { - title: t('views.dashboard.cdr.smfInvocationTime'), // 调用时间 + title: t('views.dashboard.cdr.invocationTime'), // 调用时间 dataIndex: 'cdrJSON', align: 'left', width: 200, @@ -306,6 +320,18 @@ function fnRecordDelete(id: string) { }); } +/** + * 复制CDR + * @param jsonStr JSON字符串 + */ +function fnRecordCopy(jsonStr: string) { + if (!jsonStr) return; + const text = JSON.stringify(jsonStr, null, 2); + copy(text).then(() => { + message.success(t('common.copyOk'), 3); + }); +} + /**查询列表, pageNum初始页数 */ function fnGetList(pageNum?: number) { if (tableState.loading) return; @@ -406,7 +432,9 @@ function fnRealTime() { subGroupID: `1006_${queryParams.neId}`, }, onmessage: wsMessage, - onerror: wsError, + onerror: (ev: any) => { + console.error(ev); + }, }; ws.connect(options); } else { @@ -416,12 +444,6 @@ function fnRealTime() { } } -/**接收数据后回调 */ -function wsError(ev: any) { - // 接收数据后回调 - console.error(ev); -} - /**接收数据后回调 */ function wsMessage(res: Record) { const { code, requestId, data } = res; @@ -510,6 +532,7 @@ onBeforeUnmount(() => { v-model:value="queryParams.neId" :options="neOtions" :placeholder="t('common.selectPlease')" + @change="fnQueryReset()" /> @@ -669,6 +692,17 @@ onBeforeUnmount(() => { diff --git a/src/views/monitor/topologyArchitecture/index.vue b/src/views/monitor/topologyArchitecture/index.vue index 289a4ba1..b7f25f9b 100644 --- a/src/views/monitor/topologyArchitecture/index.vue +++ b/src/views/monitor/topologyArchitecture/index.vue @@ -92,13 +92,13 @@ const graphNodeMenu = new Menu({ ${neState.neName ?? '--'}
- > ${t('views.configManage.neManage.restart')} + > ${t('views.ne.common.restart')}
- > ${t('views.configManage.neManage.stop')} + > ${t('views.ne.common.stop')}
- > ${t('views.configManage.neManage.log')} + > ${t('views.ne.common.log')}
`; diff --git a/src/views/ne/neConfig/hooks/useConfigArray.ts b/src/views/ne/neConfig/hooks/useConfigArray.ts index b0823043..ea093048 100644 --- a/src/views/ne/neConfig/hooks/useConfigArray.ts +++ b/src/views/ne/neConfig/hooks/useConfigArray.ts @@ -4,19 +4,20 @@ import { editNeConfigData, } from '@/api/ne/neConfig'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; -import { Modal,message } from 'ant-design-vue/es'; +import { Modal, message } from 'ant-design-vue/es'; import { SizeType } from 'ant-design-vue/es/config-provider'; import { reactive, watch } from 'vue'; /** * 参数配置array类型 - * @param param 父级传入 { t, treeState, neTypeSelect, fnActiveConfigNode, ruleVerification, modalState, fnModalCancel} + * @param param 父级传入 { t, treeState, neTypeSelect, neIdSelect, fnActiveConfigNode, ruleVerification, modalState, fnModalCancel} * @returns */ export default function useConfigArray({ t, treeState, neTypeSelect, + neIdSelect, fnActiveConfigNode, ruleVerification, modalState, @@ -130,29 +131,61 @@ export default function useConfigArray({ data[key] = from[key]['value']; } - // 发送 + // 请求 + const reqArr = []; + if (neTypeSelect.value[1].startsWith('SYNC')) { + for (const neId of neIdSelect.value) { + reqArr.push( + editNeConfigData({ + neType: neTypeSelect.value[0], + neId: neId, + paramName: treeState.selectNode.paramName, + paramData: data, + loc: loc, + }) + ); + } + } else { + reqArr.push( + editNeConfigData({ + neType: neTypeSelect.value[0], + neId: neTypeSelect.value[1], + paramName: treeState.selectNode.paramName, + paramData: data, + loc: loc, + }) + ); + } + // 无请求提示 + if (reqArr.length === 0) { + message.warning({ + content: t('views.ne.neConfig.neIdSyncPleace'), + duration: 3, + }); + arrayEditClose(); + return; + } + const hide = message.loading(t('common.loading'), 0); - editNeConfigData({ - neType: neTypeSelect.value[0], - neId: neTypeSelect.value[1], - paramName: treeState.selectNode.paramName, - paramData: data, - loc: loc, - }) - .then(res => { - if (res.code === RESULT_CODE_SUCCESS) { + Promise.allSettled(reqArr) + .then(resArr => { + const rejected = resArr.find(res => res.status === 'rejected'); + if (rejected) { + message.warning({ + content: t('views.ne.neConfig.updateItemErr'), + duration: 3, + }); + } else { message.success({ content: t('views.ne.neConfig.updateItem', { num: modalState.title, }), duration: 3, }); + } + const fulfilled = resArr.find(res => res.status === 'fulfilled'); + if (fulfilled) { fnActiveConfigNode('#'); - } else { - message.warning({ - content: t('views.ne.neConfig.updateItemErr'), - duration: 3, - }); } }) .finally(() => { @@ -172,28 +205,65 @@ export default function useConfigArray({ num: title, }), onOk() { - delNeConfigData({ - neType: neTypeSelect.value[0], - neId: neTypeSelect.value[1], - paramName: treeState.selectNode.paramName, - loc: loc, - }).then(res => { - if (res.code === RESULT_CODE_SUCCESS) { - message.success({ - content: t('views.ne.neConfig.delItemOk', { - num: title, - }), - duration: 2, - }); - arrayEditClose(); - fnActiveConfigNode('#'); - } else { - message.error({ - content: `${res.msg}`, - duration: 2, - }); + // 请求 + const reqArr = []; + if (neTypeSelect.value[1].startsWith('SYNC')) { + for (const neId of neIdSelect.value) { + reqArr.push( + delNeConfigData({ + neType: neTypeSelect.value[0], + neId: neId, + paramName: treeState.selectNode.paramName, + loc: loc, + }) + ); } - }); + } else { + reqArr.push( + delNeConfigData({ + neType: neTypeSelect.value[0], + neId: neTypeSelect.value[1], + paramName: treeState.selectNode.paramName, + loc: loc, + }) + ); + } + // 无请求提示 + if (reqArr.length === 0) { + message.warning({ + content: t('views.ne.neConfig.neIdSyncPleace'), + duration: 3, + }); + arrayEditClose(); + return; + } + + const hide = message.loading(t('common.loading'), 0); + Promise.allSettled(reqArr) + .then(resArr => { + const rejected = resArr.find(res => res.status === 'rejected'); + if (rejected) { + message.error({ + content: `${rejected.reason}`, + duration: 2, + }); + } else { + message.success({ + content: t('views.ne.neConfig.delItemOk', { + num: title, + }), + duration: 2, + }); + } + const fulfilled = resArr.find(res => res.status === 'fulfilled'); + if (fulfilled) { + fnActiveConfigNode('#'); + } + }) + .finally(() => { + hide(); + arrayEditClose(); + }); }, }); } @@ -264,29 +334,61 @@ export default function useConfigArray({ data[key] = from[key]['value']; } - // 发送 + // 请求 + const reqArr = []; + if (neTypeSelect.value[1].startsWith('SYNC')) { + for (const neId of neIdSelect.value) { + reqArr.push( + addNeConfigData({ + neType: neTypeSelect.value[0], + neId: neId, + paramName: treeState.selectNode.paramName, + paramData: data, + loc: `${from['index']['value']}`, + }) + ); + } + } else { + reqArr.push( + addNeConfigData({ + neType: neTypeSelect.value[0], + neId: neTypeSelect.value[1], + paramName: treeState.selectNode.paramName, + paramData: data, + loc: `${from['index']['value']}`, + }) + ); + } + // 无请求提示 + if (reqArr.length === 0) { + message.warning({ + content: t('views.ne.neConfig.neIdSyncPleace'), + duration: 3, + }); + arrayEditClose(); + return; + } + const hide = message.loading(t('common.loading'), 0); - addNeConfigData({ - neType: neTypeSelect.value[0], - neId: neTypeSelect.value[1], - paramName: treeState.selectNode.paramName, - paramData: data, - loc: `${from['index']['value']}`, - }) - .then(res => { - if (res.code === RESULT_CODE_SUCCESS) { + Promise.allSettled(reqArr) + .then(resArr => { + const rejected = resArr.find(res => res.status === 'rejected'); + if (rejected) { + message.warning({ + content: t('views.ne.neConfig.addItemErr'), + duration: 3, + }); + } else { message.success({ content: t('views.ne.neConfig.addItemOk', { num: modalState.title, }), duration: 3, }); + } + const fulfilled = resArr.find(res => res.status === 'fulfilled'); + if (fulfilled) { fnActiveConfigNode('#'); - } else { - message.warning({ - content: t('views.ne.neConfig.addItemErr'), - duration: 3, - }); } }) .finally(() => { diff --git a/src/views/ne/neConfig/hooks/useConfigArrayChild.ts b/src/views/ne/neConfig/hooks/useConfigArrayChild.ts index ee58b178..851e2df4 100644 --- a/src/views/ne/neConfig/hooks/useConfigArrayChild.ts +++ b/src/views/ne/neConfig/hooks/useConfigArrayChild.ts @@ -10,13 +10,14 @@ import { nextTick, reactive } from 'vue'; /** * 参数配置array类型的嵌套array - * @param param 父级传入 { t, treeState, neTypeSelect, fnActiveConfigNode, ruleVerification, modalState, arrayState, arrayInitEdit, arrayInitAdd, arrayEditClose} + * @param param 父级传入 { t, treeState, neTypeSelect, neIdSelect, fnActiveConfigNode, ruleVerification, modalState, arrayState, arrayInitEdit, arrayInitAdd, arrayEditClose} * @returns */ export default function useConfigArrayChild({ t, treeState, neTypeSelect, + neIdSelect, fnActiveConfigNode, ruleVerification, modalState, @@ -198,29 +199,61 @@ export default function useConfigArrayChild({ data[key] = from[key]['value']; } - // 发送 + // 请求 + const reqArr = []; + if (neTypeSelect.value[1].startsWith('SYNC')) { + for (const neId of neIdSelect.value) { + reqArr.push( + editNeConfigData({ + neType: neTypeSelect.value[0], + neId: neId, + paramName: treeState.selectNode.paramName, + paramData: data, + loc, + }) + ); + } + } else { + reqArr.push( + editNeConfigData({ + neType: neTypeSelect.value[0], + neId: neTypeSelect.value[1], + paramName: treeState.selectNode.paramName, + paramData: data, + loc, + }) + ); + } + // 无请求提示 + if (reqArr.length === 0) { + message.warning({ + content: t('views.ne.neConfig.neIdSyncPleace'), + duration: 3, + }); + arrayEditClose(); + return; + } + const hide = message.loading(t('common.loading'), 0); - editNeConfigData({ - neType: neTypeSelect.value[0], - neId: neTypeSelect.value[1], - paramName: treeState.selectNode.paramName, - paramData: data, - loc, - }) - .then(res => { - if (res.code === RESULT_CODE_SUCCESS) { + Promise.allSettled(reqArr) + .then(resArr => { + const rejected = resArr.find(res => res.status === 'rejected'); + if (rejected) { + message.warning({ + content: t('views.ne.neConfig.updateItemErr'), + duration: 3, + }); + } else { message.success({ content: t('views.ne.neConfig.updateItem', { num: modalState.title, }), duration: 3, }); + } + const fulfilled = resArr.find(res => res.status === 'fulfilled'); + if (fulfilled) { fnActiveConfigNode('#'); - } else { - message.warning({ - content: t('views.ne.neConfig.updateItemErr'), - duration: 3, - }); } }) .finally(() => { @@ -241,28 +274,65 @@ export default function useConfigArrayChild({ num: title, }), onOk() { - delNeConfigData({ - neType: neTypeSelect.value[0], - neId: neTypeSelect.value[1], - paramName: treeState.selectNode.paramName, - loc, - }).then(res => { - if (res.code === RESULT_CODE_SUCCESS) { - message.success({ - content: t('views.ne.neConfig.delItemOk', { - num: title, - }), - duration: 2, - }); - arrayEditClose(); - fnActiveConfigNode('#'); - } else { - message.error({ - content: `${res.msg}`, - duration: 2, - }); + // 请求 + const reqArr = []; + if (neTypeSelect.value[1].startsWith('SYNC')) { + for (const neId of neIdSelect.value) { + reqArr.push( + delNeConfigData({ + neType: neTypeSelect.value[0], + neId: neId, + paramName: treeState.selectNode.paramName, + loc, + }) + ); } - }); + } else { + reqArr.push( + delNeConfigData({ + neType: neTypeSelect.value[0], + neId: neTypeSelect.value[1], + paramName: treeState.selectNode.paramName, + loc, + }) + ); + } + // 无请求提示 + if (reqArr.length === 0) { + message.warning({ + content: t('views.ne.neConfig.neIdSyncPleace'), + duration: 3, + }); + arrayEditClose(); + return; + } + + const hide = message.loading(t('common.loading'), 0); + Promise.allSettled(reqArr) + .then(resArr => { + const rejected = resArr.find(res => res.status === 'rejected'); + if (rejected) { + message.error({ + content: `${rejected.reason}`, + duration: 2, + }); + } else { + message.success({ + content: t('views.ne.neConfig.delItemOk', { + num: title, + }), + duration: 2, + }); + } + const fulfilled = resArr.find(res => res.status === 'fulfilled'); + if (fulfilled) { + fnActiveConfigNode('#'); + } + }) + .finally(() => { + hide(); + arrayEditClose(); + }); }, }); } @@ -309,29 +379,61 @@ export default function useConfigArrayChild({ data[key] = from[key]['value']; } - // 发送 + // 请求 + const reqArr = []; + if (neTypeSelect.value[1].startsWith('SYNC')) { + for (const neId of neIdSelect.value) { + reqArr.push( + addNeConfigData({ + neType: neTypeSelect.value[0], + neId: neId, + paramName: treeState.selectNode.paramName, + paramData: data, + loc, + }) + ); + } + } else { + reqArr.push( + addNeConfigData({ + neType: neTypeSelect.value[0], + neId: neTypeSelect.value[1], + paramName: treeState.selectNode.paramName, + paramData: data, + loc, + }) + ); + } + // 无请求提示 + if (reqArr.length === 0) { + message.warning({ + content: t('views.ne.neConfig.neIdSyncPleace'), + duration: 3, + }); + arrayEditClose(); + return; + } + const hide = message.loading(t('common.loading'), 0); - addNeConfigData({ - neType: neTypeSelect.value[0], - neId: neTypeSelect.value[1], - paramName: treeState.selectNode.paramName, - paramData: data, - loc, - }) - .then(res => { - if (res.code === RESULT_CODE_SUCCESS) { + Promise.allSettled(reqArr) + .then(resArr => { + const rejected = resArr.find(res => res.status === 'rejected'); + if (rejected) { + message.warning({ + content: t('views.ne.neConfig.addItemErr'), + duration: 3, + }); + } else { message.success({ content: t('views.ne.neConfig.addItemOk', { num: modalState.title, }), duration: 3, }); + } + const fulfilled = resArr.find(res => res.status === 'fulfilled'); + if (fulfilled) { fnActiveConfigNode('#'); - } else { - message.warning({ - content: t('views.ne.neConfig.addItemErr'), - duration: 3, - }); } }) .finally(() => { diff --git a/src/views/ne/neConfig/hooks/useConfigList.ts b/src/views/ne/neConfig/hooks/useConfigList.ts index 37ed3aee..52a57627 100644 --- a/src/views/ne/neConfig/hooks/useConfigList.ts +++ b/src/views/ne/neConfig/hooks/useConfigList.ts @@ -6,13 +6,14 @@ import { reactive, toRaw } from 'vue'; /** * list类型参数处理 - * @param param 父级传入 {t, treeState, neTypeSelect, ruleVerification} + * @param param 父级传入 {t, treeState, neTypeSelect, neIdSelect, ruleVerification} * @returns */ export default function useConfigList({ t, treeState, neTypeSelect, + neIdSelect, ruleVerification, }: any) { /**单列表状态类型 */ @@ -83,25 +84,64 @@ export default function useConfigList({ return; } - // 发送 + // 请求 + const reqArr = []; + if (neTypeSelect.value[1].startsWith('SYNC')) { + for (const neId of neIdSelect.value) { + reqArr.push( + editNeConfigData({ + neType: neTypeSelect.value[0], + neId: neId, + paramName: treeState.selectNode.paramName, + paramData: { + [from['name']]: from['value'], + }, + }) + ); + } + } else { + reqArr.push( + editNeConfigData({ + neType: neTypeSelect.value[0], + neId: neTypeSelect.value[1], + paramName: treeState.selectNode.paramName, + paramData: { + [from['name']]: from['value'], + }, + }) + ); + } + // 无请求提示 + if (reqArr.length === 0) { + message.warning({ + content: t('views.ne.neConfig.neIdSyncPleace'), + duration: 3, + }); + listState.confirmLoading = false; + listState.editRecord = {}; + return; + } + listState.confirmLoading = true; const hide = message.loading(t('common.loading'), 0); - editNeConfigData({ - neType: neTypeSelect.value[0], - neId: neTypeSelect.value[1], - paramName: treeState.selectNode.paramName, - paramData: { - [from['name']]: from['value'], - }, - }) - .then(res => { - if (res.code === RESULT_CODE_SUCCESS) { + Promise.allSettled(reqArr) + .then(resArr => { + const rejected = resArr.find(res => res.status === 'rejected'); + if (rejected) { + message.warning({ + content: t('views.ne.neConfig.updateValueErr'), + duration: 3, + }); + } else { message.success({ content: t('views.ne.neConfig.updateValue', { num: from['display'], }), duration: 3, }); + } + const fulfilled = resArr.find(res => res.status === 'fulfilled'); + if (fulfilled) { // 改变表格数据 const item = listState.data.find( (item: Record) => from['name'] === item['name'] @@ -109,11 +149,6 @@ export default function useConfigList({ if (item) { Object.assign(item, listState.editRecord); } - } else { - message.warning({ - content: t('views.ne.neConfig.updateValueErr'), - duration: 3, - }); } }) .finally(() => { diff --git a/src/views/ne/neConfig/index.vue b/src/views/ne/neConfig/index.vue index 0c8b6bf0..224a2012 100644 --- a/src/views/ne/neConfig/index.vue +++ b/src/views/ne/neConfig/index.vue @@ -1,8 +1,8 @@ diff --git a/src/views/ne/neSoftware/components/EditModal.vue b/src/views/ne/neSoftware/components/EditModal.vue index b7439d8f..0afe1a5e 100644 --- a/src/views/ne/neSoftware/components/EditModal.vue +++ b/src/views/ne/neSoftware/components/EditModal.vue @@ -166,8 +166,8 @@ function fnBeforeUploadFile(file: FileType) { const suff = fileName.substring(fileName.lastIndexOf('.')); if (!['.deb', '.rpm'].includes(suff)) { message.error( - t('views.configManage.softwareManage.onlyAble', { - fileText: '(.deb、.rpm)', + t('views.ne.neSoftware.fileTypeNotEq', { + txt: '(.deb、.rpm)', }), 3 ); @@ -238,8 +238,8 @@ function fnBeforeUploadFileDep(file: FileType) { const suff = fileName.substring(fileName.lastIndexOf('.')); if (!['.deb', '.rpm'].includes(suff)) { message.error( - t('views.configManage.softwareManage.onlyAble', { - fileText: '(.deb、.rpm)', + t('views.ne.neSoftware.fileTypeNotEq', { + txt: '(.deb、.rpm)', }), 3 ); diff --git a/src/views/ne/neSoftware/components/UploadMoreFile.vue b/src/views/ne/neSoftware/components/UploadMoreFile.vue index ac55d5c8..f3fee8ec 100644 --- a/src/views/ne/neSoftware/components/UploadMoreFile.vue +++ b/src/views/ne/neSoftware/components/UploadMoreFile.vue @@ -171,8 +171,8 @@ function fnBeforeUploadFile(file: FileType) { const suff = fileName.substring(fileName.lastIndexOf('.')); if (!['.deb', '.rpm'].includes(suff)) { message.error( - t('views.configManage.softwareManage.onlyAble', { - fileText: '(.deb、.rpm)', + t('views.ne.neSoftware.fileTypeNotEq', { + txt: '(.deb、.rpm)', }), 3 ); @@ -286,8 +286,8 @@ function fnBeforeUploadFileDep(file: FileType) { const suff = fileName.substring(fileName.lastIndexOf('.')); if (!['.deb', '.rpm'].includes(suff)) { message.error( - t('views.configManage.softwareManage.onlyAble', { - fileText: '(.deb、.rpm)', + t('views.ne.neSoftware.fileTypeNotEq', { + txt: '(.deb、.rpm)', }), 3 ); diff --git a/src/views/neUser/ue/index.vue b/src/views/neUser/ue/index.vue index 29633e49..61918cfe 100644 --- a/src/views/neUser/ue/index.vue +++ b/src/views/neUser/ue/index.vue @@ -6,7 +6,7 @@ import { message } from 'ant-design-vue/es'; import { SizeType } from 'ant-design-vue/es/config-provider'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { ColumnsType } from 'ant-design-vue/es/table'; -import { listSMFSubscribers } from '@/api/neData/smf'; +import { listSMFSubList } from '@/api/neData/smf'; import useNeInfoStore from '@/store/modules/neinfo'; import useI18n from '@/hooks/useI18n'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; @@ -224,7 +224,7 @@ function fnGetList(pageNum?: number) { if (pageNum) { queryParams.pageNum = pageNum; } - listSMFSubscribers(toRaw(queryParams)).then(res => { + listSMFSubList(toRaw(queryParams)).then(res => { if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) { tablePagination.total = res.total; tableState.data = res.rows; diff --git a/src/views/perfManage/perfThreshold/index.vue b/src/views/perfManage/perfThreshold/index.vue index 898ef07f..30d13694 100644 --- a/src/views/perfManage/perfThreshold/index.vue +++ b/src/views/perfManage/perfThreshold/index.vue @@ -391,9 +391,7 @@ function fnRecordRun(row: Record) { threRun(row).then(res => { if (res.code === RESULT_CODE_SUCCESS) { message.success({ - content: t('common.msgSuccess', { - msg: t('views.configManage.softwareManage.runBtn'), - }), + content: 'Run', key, duration: 2, }); @@ -610,7 +608,7 @@ onMounted(() => { ) { taskRun(row).then(res => { if (res.code === RESULT_CODE_SUCCESS) { message.success({ - content: t('common.msgSuccess', { - msg: t('views.configManage.softwareManage.runBtn'), - }), + content: 'Run', key, duration: 2, }); @@ -861,7 +859,7 @@ onMounted(() => { > - {{ t('views.configManage.softwareManage.runBtn') }} + Run diff --git a/src/views/system/quick-start/components/NeInfoConfig.vue b/src/views/system/quick-start/components/NeInfoConfig.vue index b5cdd41c..d3457e23 100644 --- a/src/views/system/quick-start/components/NeInfoConfig.vue +++ b/src/views/system/quick-start/components/NeInfoConfig.vue @@ -230,7 +230,7 @@ function fnNeTypeChange(v: any, data: any) { function fnModalVisibleByEdit(record?: any) { if (!record) { //modalStateFrom.resetFields(); - modalState.title = t('views.configManage.neManage.addNe'); + modalState.title = t('views.ne.neInfo.addTitle'); const neId = `${new Date().getMilliseconds()}`.padStart(3, '0'); modalState.from = { id: undefined, @@ -287,7 +287,7 @@ function fnModalVisibleByEdit(record?: any) { hide(); if (res.code === RESULT_CODE_SUCCESS) { Object.assign(modalState.from, res.data); - modalState.title = t('views.configManage.neManage.editNe'); + modalState.title = t('views.ne.neInfo.editTitle'); modalState.openByEdit = true; } else { message.error(t('common.getInfoFail'), 2); diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 8faa1cc2..3f14810f 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -23,7 +23,11 @@ import { saveAs } from 'file-saver'; import { parseDateToStr } from '@/utils/date-utils'; import useDictStore from '@/store/modules/dict'; import { DataNode } from 'ant-design-vue/es/tree'; -import { parseTreeKeys, parseTreeNodeKeys } from '@/utils/parse-tree-utils'; +import { + parseTreeKeys, + parseTreeNodeKeys, + parseTreeNodeKeysByChecked, +} from '@/utils/parse-tree-utils'; import { hasPermissions } from '@/plugins/auth-user'; import { MENU_PATH_INLINE } from '@/constants/menu-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; @@ -328,7 +332,12 @@ function fnModalVisibleByVive(roleId: string | number) { menuTree.treeData = menus; modalState.menuTree.treeData = menus; modalState.menuTree.checkedKeys = checkedKeys; - modalState.from.menuIds = checkedKeys; + if (modalState.from.menuCheckStrictly === '1') { + const ids = parseTreeNodeKeysByChecked(menus, checkedKeys, 'id'); + modalState.from.menuIds = ids.concat(checkedKeys); + } else { + modalState.from.menuIds = checkedKeys; + } } modalState.title = t('views.system.role.roleInfo'); modalState.openByView = true; @@ -385,7 +394,12 @@ function fnModalVisibleByEdit(roleId?: string | number) { menuTree.treeData = menus; modalState.menuTree.treeData = menus; modalState.menuTree.checkedKeys = checkedKeys; - modalState.from.menuIds = checkedKeys; + if (modalState.from.menuCheckStrictly === '1') { + const ids = parseTreeNodeKeysByChecked(menus, checkedKeys, 'id'); + modalState.from.menuIds = ids.concat(checkedKeys); + } else { + modalState.from.menuIds = checkedKeys; + } } modalState.title = t('common.editText') + t('views.system.role.roleInfo'); @@ -567,7 +581,12 @@ function fnRecordDataScope(roleId: string | number) { deptTree.treeData = depts; modalState.deptTree.treeData = depts; modalState.deptTree.checkedKeys = checkedKeys; - modalState.from.deptIds = checkedKeys; + if (modalState.from.deptCheckStrictly === '1') { + const ids = parseTreeNodeKeysByChecked(depts, checkedKeys, 'id'); + modalState.from.deptIds = ids.concat(checkedKeys); + } else { + modalState.from.deptIds = checkedKeys; + } } modalState.title = t('views.system.role.distribute'); modalState.openByDataScope = true;