Compare commits

..
Author SHA1 Message Date
TsMask 33a8ce97d3 chore: 更新版本号 2.241102 2024-11-02 15:47:18 +08:00
TsMask 6ee9d464fb feat: PCF导出有取消操作 2024-11-02 15:46:26 +08:00
TsMask df5072bae7 fix: CDR-IMS显示呼叫-挂断时间 2024-11-02 15:46:05 +08:00
zhongzm e12dce1f0f feat:网元指标添加其他指标选项 优化样式 2024-10-31 18:35:26 +08:00
TsMask d0457fc285 fix: UDM鉴权签约用户勾选导出 2024-10-31 16:32:14 +08:00
zhongzm 63d32f0a39 feat:自定义网元指标概览 2024-10-31 10:30:16 +08:00
TsMask cf5d08aaab chore: 更新版本号 2.241028 2024-10-28 16:53:21 +08:00
TsMask 7ad566d74f fix: 网元总览接口变更 2024-10-28 16:52:41 +08:00
TsMask c312186d91 fix: UDM签约数据参数类型转换字符串参数 2024-10-28 16:52:05 +08:00
lai 72fd372fe0 增加关闭按钮 2024-10-24 10:40:54 +08:00
lai acdadcbb6f 增加Network Function IPv4地址 2024-10-24 10:40:20 +08:00
lai 7a49de71ea 修复 修改Event Type的label 2024-10-24 10:38:28 +08:00
zhongzm 56e4419e77 Revert "Revert "fix:中英提示修复""
This reverts commit 3abb4dd4bd.
2024-10-24 10:12:51 +08:00
zhongzm 3abb4dd4bd Revert "fix:中英提示修复"
This reverts commit a45243390b.
2024-10-24 10:12:09 +08:00
zhongzm 726a284ab5 Merge remote-tracking branch 'origin/main' 2024-10-24 10:11:28 +08:00
zhongzm a45243390b fix:中英提示修复 2024-10-24 10:11:08 +08:00
TsMask 1faed9bc3d style: 关键指标概览页面占位 2024-10-23 18:48:29 +08:00
TsMask 9bd700eeb7 feat: PCF补充增加online和offline字段 2024-10-23 10:44:15 +08:00
zhongzm 5cc3b9c8cf fix:css样式报错修复 2024-10-22 18:54:35 +08:00
zhongzm 208895c7d5 feat:快速布局功能以及ws连接修复 2024-10-22 16:01:53 +08:00
TsMask 46578ce97b feat: 快速开站SMSC的IP赋值 2024-10-18 20:16:06 +08:00
TsMask 0ff5bd5e20 style: UDM用户数据根据网元类型变更刷新列表 2024-10-18 11:42:21 +08:00
TsMask f08e637e69 fix: 版权信息文本长度128 2024-10-18 11:34:37 +08:00
TsMask a600e056b8 chore: 更新版本号 2.241018 2024-10-18 10:36:06 +08:00
zhongzm 671c80972e fix:多选改checkbox 2024-10-18 10:32:55 +08:00
TsMask d07230b582 Merge remote-tracking branch 'origin/main' into lichang 2024-10-18 10:20:54 +08:00
TsMask 35c24407ac Merge remote-tracking branch 'origin/lichang' 2024-10-18 10:18:48 +08:00
TsMask cf33756548 Merge remote-tracking branch 'origin/main' into lichang 2024-10-18 10:17:53 +08:00
TsMask 1ef98298bc style: 移除port/dbinfo/capability属性信息 2024-10-17 19:55:09 +08:00
zhongzm b1c2a95ec4 Merge remote-tracking branch 'origin/lichang' into lichang 2024-10-17 19:54:55 +08:00
zhongzm 147b2fad8d fix:网元响应式数组添加防抖 2024-10-17 19:54:40 +08:00
TsMask b629088406 Merge remote-tracking branch 'origin/lichang' 2024-10-17 19:51:43 +08:00
TsMask 430a067280 Merge remote-tracking branch 'origin/main' into lichang 2024-10-17 18:27:09 +08:00
TsMask 8a71e8f773 Merge remote-tracking branch 'origin/lichang' 2024-10-17 18:26:49 +08:00
lai ff556ce1ec 添加首页加载状态 2024-10-17 18:18:37 +08:00
zhongzm 9ed7aed4b4 feat:自定义布局保存,WS数据追加 2024-10-17 18:07:39 +08:00
TsMask 9e14297488 Merge remote-tracking branch 'origin/main' into lichang 2024-10-17 15:55:15 +08:00
TsMask 8e70706ed5 fix: 网元日志实时查看组件参数调整 2024-10-17 15:07:04 +08:00
TsMask 3e0529cf87 fix: 终端SSH视图组件调整参数配置外部地址 2024-10-17 15:06:34 +08:00
TsMask 91af2bed92 feat: 工具iperf/ping功能页面 2024-10-17 15:05:21 +08:00
lai 1ecefb91dc 增加导出时携带完整搜索条件 2024-10-17 14:51:55 +08:00
TsMask 72d9895902 fix: UDM用户数据按查询条件导出 2024-10-17 11:39:17 +08:00
lai 41fa214137 完善自定义首页设置 2024-10-17 10:30:21 +08:00
TsMask 1565f25a03 del: 移除debugger标记 2024-10-17 10:29:39 +08:00
lai c5c2926d99 修改告警导出异常 2024-10-17 10:29:22 +08:00
lai 55456f9220 自定义主页 2024-10-16 19:28:05 +08:00
TsMask cf1686c348 Merge branch 'lichang' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 into lichang 2024-10-16 16:47:01 +08:00
TsMask f7833bcd9f fix: UDM数据load失败无法重试 2024-10-16 16:46:57 +08:00
TsMask 5a621053a4 feat: 网元连接配置UDM支持Redis 2024-10-16 16:46:14 +08:00
lai 2a6451ef2a 更改首页代码文件路径 2024-10-16 15:11:26 +08:00
lai f1b440c8dd 补充 2024-10-16 14:50:47 +08:00
lai a67e54ca6e 补充 2024-10-16 14:23:32 +08:00
lai 53d9e63c36 新增自定义首页 2024-10-16 14:12:31 +08:00
zhongzm b4623d19e5 fix:关键指标界面拖拽块设为图标,优化样式 2024-10-15 18:26:02 +08:00
zhongzm 700bff6e38 fix:关键指标界面自定义布局功能 2024-10-15 17:48:35 +08:00
TsMask d77c4e43d4 feat: 信令跟踪保活续期 2024-10-15 15:14:38 +08:00
TsMask 6e11d2b16a feat: 网元日志文件获取查看,抓包单独查看 2024-10-15 14:55:41 +08:00
TsMask 405842bc0b fix: 看板用户事件AMF订阅编号无neId 2024-10-15 14:38:29 +08:00
zhongzm bf8d7f2124 fix:代码优化-方法封装-拖拽保存-大小自适应 2024-10-14 18:52:47 +08:00
TsMask ba98b37306 feat: 优化PCF参数可选请求数据处理 2024-10-12 19:10:52 +08:00
TsMask aa8ed65fd8 del: 删除旧License页面相关接口请求 2024-10-12 19:10:21 +08:00
TsMask 936a4410b3 del: 删除旧参数配置页面相关接口请求 2024-10-12 19:10:04 +08:00
TsMask 58ec76f9e5 Merge remote-tracking branch 'origin/main' into lichang 2024-10-12 15:43:09 +08:00
TsMask c1a77c8e48 chore: 更新版本号 241012 2024-10-12 15:42:29 +08:00
TsMask 477e8e4631 feat: 工具iperf/ping页面占位 2024-10-12 15:39:53 +08:00
TsMask 4f9d65a3a7 feat: UDM签约支持MICO和RAT修改 2024-10-12 15:07:06 +08:00
TsMask b1799d8ccb style: 首页-网元详细信息-删除数据库以及端口字段显示 2024-10-12 09:50:57 +08:00
TsMask 86833e7d6b feat: 关键指标报表页面 2024-10-11 18:48:46 +08:00
TsMask 59cf57898b Merge branch 'lichang' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 into lichang 2024-10-11 18:14:31 +08:00
zhongzm fb9382e3a0 Merge remote-tracking branch 'origin/lichang' into lichang 2024-10-11 18:05:32 +08:00
zhongzm dae4697cd2 feat:多图表网元指标界面实时数据连接修复和拖拽功能实现 2024-10-11 17:57:51 +08:00
TsMask 1b2e892f74 fix: 看板总流量24小时切换类型声明 2024-10-11 16:50:46 +08:00
TsMask c66c640f75 fix: 看板总流量24小时实时累加 2024-10-11 15:47:26 +08:00
TsMask 30849416b6 fix: 工具ps/net页面定时器清除 2024-10-11 14:12:57 +08:00
TsMask 5edcee8da5 style: 隐藏跳转主机添加页面 2024-10-11 14:12:08 +08:00
TsMask 311beed2a7 fix: UPF总量数据格式化单位问题 2024-10-11 14:11:18 +08:00
TsMask eb5fdfb635 fix: 修复工具ps/net资源列表 2024-10-11 09:53:13 +08:00
TsMask 78bcde9ef2 style: 信令跟踪根据状态隐藏操作 2024-10-10 21:06:56 +08:00
lai 630e2a16ad 限制自定义指标输入长度 2024-10-10 19:45:45 +08:00
TsMask e1fe031f25 Merge branch 'lichang' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 into lichang 2024-10-09 18:56:28 +08:00
zhongzm 855ba7dc9e feat:net界面修复:F12后的报错消除 2024-10-09 12:04:16 +08:00
TsMask 3a72e73d5d style: 拓扑图smsc图标 2024-10-09 10:53:47 +08:00
TsMask 4cb13a1419 feat: 网元快速安装添加SMSC的ip填充 2024-10-09 09:50:31 +08:00
TsMask 8dd84a5255 fix: 网元抓包loading状态禁止重复开始任务 2024-10-08 16:49:14 +08:00
TsMask c0e62f48b7 fix: wiregasm去除gz压缩文件 2024-10-01 14:10:22 +08:00
TsMask b992225e28 fix: 网元快速安装多语言识别 2024-10-01 13:02:06 +08:00
TsMask 2f04562a34 feat: 信令跟踪功能页面 2024-09-30 21:02:01 +08:00
TsMask d3a452cfd8 Merge remote-tracking branch 'origin/main' into lichang 2024-09-27 11:14:26 +08:00
TsMask d81b8cdf38 chore: 更新版本号 240927 2024-09-27 11:13:25 +08:00
TsMask 39a417368a docs: 更新说明 2024-09-27 11:11:54 +08:00
TsMask adfce5d2f7 style: SMSC-CDR结果带result,cause 2024-09-27 10:05:45 +08:00
TsMask 977286d6b3 fix: 驼峰和划线互转函数去除非对象转换 2024-09-26 17:31:57 +08:00
TsMask c33000045a fix: 消息进行wg关闭销毁 2024-09-26 17:23:24 +08:00
TsMask b995ac378a fix: 网元版本同版本号进行确认继续操作 2024-09-26 17:20:01 +08:00
TsMask 6bea64f345 style: 多语言views.traceManage.task取值变更views.ne.common 2024-09-24 10:53:33 +08:00
TsMask 94886e255e feat: 网元跟踪数据支持下载pcap文件 2024-09-24 10:52:28 +08:00
TsMask 45f66afe52 fix: 网元配置更新下发配置失败时不更新状态 2024-09-23 17:44:16 +08:00
TsMask b9105c1e77 style: 注释信息解析html请求 2024-09-23 17:25:26 +08:00
TsMask 909d306942 perf: wg优化代码封装hooks 2024-09-23 17:24:55 +08:00
TsMask f7273457e9 feat: 跟踪任务查看pcap内容信息 2024-09-23 17:24:02 +08:00
TsMask 2e5ad2f65d fix: 看板MME-CDR的ECM State 2024-09-21 15:52:54 +08:00
TsMask 776e9c5837 chore: 更新版本号 240920 2024-09-20 18:23:12 +08:00
TsMask 0d4979d3d9 style: 注释和代码格式化 2024-09-20 18:22:22 +08:00
TsMask 686c7dd273 fix: 驼峰和划线互转函数 2024-09-20 18:21:03 +08:00
TsMask d41b308c6d fix: 性能管理报表页面未开发 2024-09-20 18:20:34 +08:00
TsMask 84dac247d2 perf: 重构跟踪任务 2024-09-20 18:20:01 +08:00
TsMask f8439bb40a feat: HLR跟踪任务页面免登录/trace-task-hlr 2024-09-20 12:05:16 +08:00
TsMask d268d920e7 chore: 更新版本号 240919 2024-09-19 11:50:51 +08:00
TsMask f730ef1e3a style: 调整勾选按钮顺序 2024-09-19 11:50:06 +08:00
TsMask af1ce32063 feat: 调整SMF在线用户列表数据补充显示imsi备注标记 2024-09-19 11:49:30 +08:00
TsMask 678ff2d09d feat: UDM签约补充CAG参数和备注标记参数 2024-09-19 11:48:16 +08:00
TsMask 48f674b6ef Merge remote-tracking branch 'origin/main' into lichang 2024-09-13 09:59:13 +08:00
TsMask 02f0820a69 fix: telnet终端命令多‘号导致命令无效 2024-09-13 09:58:13 +08:00
TsMask ca8605fd6e fix: 跟踪任务HLR操作 2024-09-12 17:12:41 +08:00
TsMask 6d5e96421b style: 多语言zh去除行头 2024-09-12 17:12:13 +08:00
TsMask bcc29007bf fix: 4G的MME显示ECM 2024-09-12 17:11:10 +08:00
TsMask bdf904078d style: 多语言zh去除行头 2024-09-12 17:10:43 +08:00
TsMask e37cfa5066 Merge remote-tracking branch 'origin/main' into lichang 2024-09-10 09:42:40 +08:00
lai f1bff23bbc Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-09-09 19:25:26 +08:00
lai 53106ddb5c 调换位置 2024-09-09 19:25:22 +08:00
TsMask 3a04882fe5 Merge remote-tracking branch 'origin/main' into lichang 2024-09-09 19:14:04 +08:00
TsMask 19202a5e81 Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-09-09 19:11:37 +08:00
TsMask 7b311ff673 fix: SMSC添加CDR响应错误原因码 2024-09-09 19:11:34 +08:00
lai 9dba98e0ee 重新排版表单 2024-09-09 19:06:53 +08:00
lai 71338670f0 重新排版表单 2024-09-09 18:12:23 +08:00
lai 7dcdfabce2 增加单位显示的限制 2024-09-09 16:23:18 +08:00
lai ddfe1723c9 自定义指标 2024-09-09 15:01:04 +08:00
TsMask 57b5f76db7 fix: 重构tool的ps页面 2024-09-06 19:57:10 +08:00
lai 9ac3524877 自定义指标 2024-09-06 19:22:25 +08:00
lai ca82a0a74b 更改中英文 2024-09-06 19:21:57 +08:00
zhongzm 23007c3bf2 feat:ps界面和net界面 2024-09-06 17:27:38 +08:00
TsMask 5d69d7612a chore: 更新版本号 2.240906 2024-09-06 16:14:16 +08:00
TsMask ddd8930af4 feat: 跟踪任务功能详情文件页面 2024-09-06 16:12:33 +08:00
lai 757f2ec20a 导出文件管理 2024-09-06 10:15:20 +08:00
lai 30caa79424 Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-09-05 20:22:07 +08:00
TsMask e3f83a0b98 feat: 跟踪任务功能页面 2024-09-05 17:30:31 +08:00
TsMask 147a3ed77b style: 跟踪任务多语言翻译 2024-09-05 17:30:11 +08:00
TsMask 5d35d950b3 feat: 网元参数配置特殊SMF-upfid选择 2024-09-05 17:29:12 +08:00
lai 6874508d3f neType空时则获取全部基站信息 2024-09-05 16:42:43 +08:00
lai 33f468209a 告警根据中英文导出 2024-09-05 16:38:06 +08:00
lai e8ef2816df 增加IMSI,ki限制位数以及合并新增批量新增按钮 2024-09-05 16:36:05 +08:00
TsMask e38d7bbffa fix: 网元信息新增监听neType+neId拼接rmUID 2024-09-03 16:59:06 +08:00
TsMask 2f1265c47a fix: 编译类型缺失 2024-09-03 16:57:43 +08:00
TsMask 66b6b60505 fix: 右上角气泡提示活动告警 2024-09-03 11:28:41 +08:00
TsMask 249d14320d fix: 删除右上角系统用户手册 2024-09-03 11:22:56 +08:00
TsMask 313b90ad31 fix: MME事件类型cm显示改为ECM 2024-09-03 11:19:39 +08:00
TsMask 2ebc90e974 Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-09-03 11:06:50 +08:00
TsMask 640257dd55 feat: 信令抓包数据监控 2024-09-03 11:06:40 +08:00
TsMask c1a3ce8068 feat: 信令抓包tshark解析pcap 2024-09-03 11:05:58 +08:00
TsMask 0080e9c26e feat: 公共组件-虚拟滚动列表 2024-09-03 11:00:00 +08:00
TsMask 2ccafe622d feat: 插件新增-Web Workers 2024-09-03 10:59:05 +08:00
TsMask d7a515ed9a feat: 工具函数-格式化文件大小 2024-09-03 10:54:15 +08:00
simonzhangsz cd82b71b77 fix: remove OMC limit from parameter config NE list 2024-09-02 16:52:49 +08:00
TsMask 9d6a7dcd9c chore: 更新版本号 2.240831 2024-08-31 10:17:36 +08:00
TsMask 46c2affcc8 fix: 网元信息资源百分比 2024-08-30 19:50:12 +08:00
TsMask 3d00a80588 fix: 手工同步超时时间180s 2024-08-30 18:02:47 +08:00
TsMask a3c1fe154f chore: 更新版本号 2.240823 2024-08-23 19:06:32 +08:00
TsMask 07dce5a27e style: 暗黑模式下文字反色 2024-08-23 19:05:35 +08:00
TsMask 255cf026a6 style: 编译类型错误 2024-08-22 10:28:35 +08:00
TsMask 840ea56c42 chore: 更新版本号 2.240822 2024-08-22 10:20:45 +08:00
TsMask 09917cc9c9 feat: 补充CBC网元选择 2024-08-22 10:19:52 +08:00
TsMask 4c9fe192f2 feat: 历史抓包文件页面 2024-08-22 10:19:23 +08:00
TsMask 32ec55d44e feat: 网元文件下载支持删除临时缓存文件 2024-08-22 10:18:42 +08:00
TsMask 527cf89d1a fix: 避免get请求带body错误 2024-08-21 17:38:10 +08:00
TsMask ac7b57c0ae fix: 内嵌地址标识菜单展开高亮 2024-08-21 17:37:06 +08:00
TsMask 8be1a8968e fix: 标签名称修改导致全局标签 2024-08-21 17:36:04 +08:00
TsMask 999ccf64ad perf: 抓包功能优化 2024-08-20 15:49:03 +08:00
TsMask 03352f3aa8 style: 网元快速安装操作Nest放后面 2024-08-17 12:22:38 +08:00
lai 61a58fc661 默认neType为空时显示45G信息 2024-08-16 17:11:39 +08:00
TsMask 4268fa3198 fix: 网元IMS参数配置plmn禁止删除index0 2024-08-15 18:05:56 +08:00
TsMask f6b62c6c7e fix: 构建目标改为esnext,兼容pdf-js编译 2024-08-15 10:22:39 +08:00
TsMask b4cbc1c190 chore: 更新版本号 2.240815 2024-08-15 10:11:22 +08:00
TsMask 1871f6f656 chore: 新增crypto-js依赖库 2024-08-15 10:10:50 +08:00
TsMask 409f9836a6 fix: 对登录,网元信息新增更新数据加密 2024-08-15 10:10:09 +08:00
TsMask b3f40ee683 fix: 网元信息列表不带状态导致无法正常显示 2024-08-15 10:09:11 +08:00
TsMask aa07b51663 feat: 请求http工具支持接口加解密 2024-08-15 10:08:12 +08:00
TsMask 19b77ed005 style: 监控资源数据超时设为60s 2024-08-15 09:49:44 +08:00
TsMask 06503fd079 fix: 拓扑图组名变更 2024-08-09 19:46:20 +08:00
TsMask 2321dacd2a chore: 更新版本号 2.240809 2024-08-09 18:48:44 +08:00
TsMask a8b4e91b95 feat: 文本日志文件实时查看功能 2024-08-09 18:47:45 +08:00
TsMask a5075bef43 feat: SMSC功能接口补充 2024-08-08 20:58:47 +08:00
TsMask f4ffbc1c86 style: CDR数据页面格式优化 2024-08-08 20:58:06 +08:00
TsMask 6cafa284c7 feat: SMSC-CDR数据列表查询 2024-08-08 20:56:40 +08:00
TsMask 049c0e7a0f fix: 终端面板telnet内容行列数自适应调整 2024-08-08 10:40:19 +08:00
TsMask 377ffc6e10 fix: CDR/Event上报数据对应发网元 2024-08-06 16:56:37 +08:00
TsMask 858431e86e perf: 替换旧网元参数配置页面 2024-08-05 17:51:11 +08:00
TsMask 70fca5ca41 fix: 网元信息OAM配置支持修改omc ip,排除omc编辑OAM信息 2024-08-05 17:44:41 +08:00
lai e972d14a9a 调整表格字段列 2024-08-05 15:28:16 +08:00
172 changed files with 5559 additions and 5217 deletions

No files matched your search

+1 -1
View File
@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network OMC"
VITE_APP_CODE = "OMC"
# 应用版本
VITE_APP_VERSION = "2.241115"
VITE_APP_VERSION = "2.241102"
# 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api"
+1 -1
View File
@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network OMC"
VITE_APP_CODE = "OMC"
# 应用版本
VITE_APP_VERSION = "2.241115"
VITE_APP_VERSION = "2.241102"
# 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api"
+7
View File
@@ -5,6 +5,13 @@
- 图标来源 [@ant-design/icons-vue](https://ant.design/components/icon)
- 菜单图标使用自定义 iconfont `font_8d5l8fzk5b87iudi.js`图标文件
## 测试环境
```text
Nginx: http://192.168.2.166:3188/#/index
后端暴露端口: http://192.168.2.166:33030
```
## 程序命令
项目目录下 `.env.[环境]` 文件对应环境的一些配置,启动前请检查文件内是否配置正确。
+17 -17
View File
@@ -16,31 +16,31 @@
"@antv/g6": "~4.8.24",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-yaml": "^6.1.1",
"@codemirror/merge": "^6.7.2",
"@codemirror/merge": "^6.6.3",
"@codemirror/theme-one-dark": "^6.1.2",
"@tato30/vue-pdf": "^1.11.2",
"@vueuse/core": "11.2.0",
"@tato30/vue-pdf": "^1.10.0",
"@vueuse/core": "~10.10.1",
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"ant-design-vue": "^4.2.5",
"antdv-pro-layout": "^4.1.9",
"antdv-pro-modal": "^4.0.5",
"ant-design-vue": "^3.2.20",
"antdv-pro-layout": "~3.3.5",
"antdv-pro-modal": "^3.1.0",
"codemirror": "^6.0.1",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.11",
"echarts": "~5.5.0",
"file-saver": "^2.0.5",
"grid-layout-plus": "^1.0.5",
"intl-tel-input": "^24.6.0",
"intl-tel-input": "^23.8.1",
"js-base64": "^3.7.7",
"js-cookie": "^3.0.5",
"localforage": "^1.10.0",
"nprogress": "^0.2.0",
"p-queue": "~8.0.1",
"pinia": "2.2.6",
"vue": "^3.5.12",
"vue-i18n": "^10.0.4",
"vue-router": "^4.4.5",
"pinia": "^2.1.7",
"vue": "~3.3.13",
"vue-i18n": "^9.13.1",
"vue-router": "^4.4.0",
"vue3-smooth-dnd": "^0.0.6",
"xlsx": "~0.18.5"
},
@@ -48,14 +48,14 @@
"@types/crypto-js": "^4.2.2",
"@types/file-saver": "^2.0.7",
"@types/js-cookie": "^3.0.6",
"@types/node": "^22.7.7",
"@types/node": "^18.0.0",
"@types/nprogress": "^0.2.3",
"@vitejs/plugin-vue": "^5.1.4",
"@vitejs/plugin-vue": "^5.0.5",
"less": "^4.2.0",
"typescript": "^5.6.3",
"unplugin-vue-components": "^0.27.4",
"vite": "5.4.10",
"typescript": "~5.4.5",
"unplugin-vue-components": "~0.26.0",
"vite": "~5.3.1",
"vite-plugin-compression": "~0.5.1",
"vue-tsc": "^2.1.8"
"vue-tsc": "~2.0.22"
}
}
+4 -4
View File
@@ -1,7 +1,7 @@
// load the Wiregasm library
importScripts(
'wiregasm_new.js', // self-compilation es5
'wiregasm_load.js'
'/wiregasm/wiregasm_new.js', // self-compilation es5
'/wiregasm/wiregasm_load.js'
// 'https://cdn.jsdelivr.net/npm/@goodtools/wiregasm/dist/wiregasm.js'
);
@@ -16,11 +16,11 @@ const fetchPackages = async () => {
console.log('Fetching packages');
let [wasmBuffer, dataBuffer] = await Promise.all([
await inflateRemoteBuffer(
'wiregasm.wasm'
'/wiregasm/wiregasm.wasm'
// 'https://cdn.jsdelivr.net/npm/@goodtools/wiregasm/dist/wiregasm.wasm'
),
await inflateRemoteBuffer(
'wiregasm.data'
'/wiregasm/wiregasm.data'
// 'https://cdn.jsdelivr.net/npm/@goodtools/wiregasm/dist/wiregasm.data'
),
]);
+67 -52
View File
@@ -1,48 +1,22 @@
<script setup lang="ts">
import { onBeforeMount, ref, watch } from 'vue';
import { message } from 'ant-design-vue/es';
import zhCN from 'ant-design-vue/es/locale/zh_CN';
import enUS from 'ant-design-vue/es/locale/en_US';
import { usePrefersColorScheme, viewTransitionTheme } from 'antdv-pro-layout';
import { ConfigProvider } from 'ant-design-vue/lib';
import { usePrimaryColor } from '@/hooks/useTheme';
import zhCN from 'ant-design-vue/lib/locale/zh_CN';
import enUS from 'ant-design-vue/lib/locale/en_US';
import dayjs from 'dayjs';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import useLayoutStore from '@/store/modules/layout';
import 'dayjs/locale/zh-cn';
import { ref, watch } from 'vue';
import useAppStore from '@/store/modules/app';
import useI18n from '@/hooks/useI18n';
const { t, currentLocale } = useI18n();
const { themeConfig, initPrimaryColor, changeConf } = useLayoutStore();
const appStore = useAppStore();
dayjs.extend(advancedFormat);
// dayjs.locale('zh-cn'); // 默认中文
let locale = ref(enUS); // 国际化初始中文
dayjs.locale('zh-cn'); // 默认中文
usePrimaryColor(); // 载入用户自定义主题色
// 偏好设置
const colorScheme = usePrefersColorScheme();
watch(
() => colorScheme.value,
themeMode => {
viewTransitionTheme(() => {
changeConf('theme', themeMode);
});
}
);
onBeforeMount(() => {
// 全局message提示
message.config({
top: '100px', // 距离顶部位置100px
duration: 3,
maxCount: 15,
});
initPrimaryColor();
// 输出应用版本号
const appStore = useAppStore();
console.info(
`%c ${t('common.desc')} %c ${appStore.appCode} - ${appStore.appVersion} `,
'color: #fadfa3; background: #030307; padding: 4px 0;',
'color: #030307; background: #fadfa3; padding: 4px 0;'
);
});
let locale = ref(zhCN); // 国际化初始中文
// 国际化切换语言
function fnChangeLocale(v: string) {
@@ -63,18 +37,26 @@ fnChangeLocale(currentLocale.value);
watch(currentLocale, val => {
fnChangeLocale(val);
});
// 输出应用版本号
console.info(
`%c ${t('common.title')} %c ${appStore.appCode} - ${appStore.appVersion} `,
'color: #fadfa3; background: #030307; padding: 4px 0;',
'color: #030307; background: #fadfa3; padding: 4px 0;'
);
</script>
<template>
<a-config-provider :theme="themeConfig" :locale="locale">
<ConfigProvider :locale="locale">
<RouterView />
</a-config-provider>
</ConfigProvider>
</template>
<style lang="css">
#app {
height: 100%;
}
body .ant-pro-basicLayout {
display: flex;
flex-direction: column;
@@ -104,23 +86,56 @@ body .ant-pro-basicLayout {
transform: translate(-2em, 0);
}
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
/**强制改表格边距 */
.ant-table.ant-table-small .ant-table-tbody > tr > td,
.ant-table.ant-table-small .ant-table-thead > tr > th {
padding: 6px !important;
}
[data-theme='dark']::view-transition-old(root) {
z-index: 1;
}
[data-theme='dark']::view-transition-new(root) {
z-index: 999;
/** ==== 表格头按钮区域 S === **/
/* 默认 */
.button-container {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
}
::view-transition-old(root) {
z-index: 999;
.button-container > button,
.button-container > span {
margin-right: 12px;
margin-bottom: 12px;
}
::view-transition-new(root) {
z-index: 1;
.button-container > button:last-child,
.button-container > span:last-child {
margin-right: 0;
}
/* 平板端 */
@media (max-width: 992px) {
.button-container {
flex-direction: row;
align-items: flex-start;
align-items: left;
}
.button-container > button,
.button-container > span {
margin-right: 12px;
margin-bottom: 12px;
}
}
/* 手机端 */
@media (max-width: 576px) {
.button-container {
flex-direction: column;
align-items: flex-start;
align-items: left;
}
.button-container > button,
.button-container > span {
margin-right: 0px;
margin-bottom: 12px;
}
}
/** ==== 表格头按钮区域 E === **/
</style>
-1
View File
@@ -23,7 +23,6 @@ export function listUDMAuth(query: Record<string, any>) {
url: '/neData/udm/auth/list',
method: 'get',
params: query,
timeout: 30_000,
});
}
-1
View File
@@ -23,7 +23,6 @@ export function listUDMSub(query: Record<string, any>) {
url: '/neData/udm/sub/list',
method: 'get',
params: query,
timeout: 30_000,
});
}
File renamed without changes.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

-1
View File
@@ -1 +0,0 @@
<svg width="1em" height="1em" class="icon-dark" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg" style="vertical-align: -0.125em;color: rgba(255, 255, 255, 0.65);"><g id="Dark-\u9875\u9762-1" stroke="none" stroke-width="1px" fill="none" fill-rule="evenodd"><g id="Dark-\u9ED8\u8BA4" transform="translate(-9.000000, -49.500000)" fill="currentColor" fill-rule="nonzero"><g id="Dark-\u7F16\u7EC4-17" transform="translate(0.000000, 42.500000)"><g id="Dark-moon" transform="translate(9.268811, 7.500000)"><rect id="Dark-\u77E9\u5F62" opacity="0" x="0" y="0" width="16" height="16"></rect><path d="M8,1.33333333 C8.14933333,1.33333333 8.29688889,1.33844444 8.44266667,1.34866666 C8.14755556,1.98422221 8,2.64577777 8,3.33333333 C8,3.96533333 8.12333333,4.56955555 8.37,5.146 C8.61666667,5.72244445 8.94822222,6.21888889 9.36466667,6.63533333 C9.78111112,7.05177777 10.2775556,7.38333332 10.854,7.63 C11.4304444,7.87666668 12.0346667,8.00000001 12.6666667,8 C13.3542222,8 14.0157778,7.85244444 14.6513333,7.55733333 C14.6615556,7.70311111 14.6666667,7.85066667 14.6666667,8 C14.6666667,8.604 14.5868889,9.19422222 14.4273333,9.77066667 C14.2677778,10.3471111 14.0446667,10.8793333 13.758,11.3673333 C13.4713333,11.8553333 13.1233333,12.3042222 12.714,12.714 C12.3046667,13.1237778 11.8557778,13.4717778 11.3673333,13.758 C10.8788889,14.0442222 10.3466667,14.2673333 9.77066667,14.4273333 C9.19466667,14.5873333 8.60444445,14.6671111 8,14.6666685 C7.39555555,14.6662222 6.80533333,14.5864444 6.22933333,14.4273333 C5.65333333,14.2682222 5.1211111,14.0451111 4.63266666,13.758 C4.14422221,13.4708889 3.69533332,13.1228889 3.28599998,12.714 C2.87666665,12.3051111 2.52866665,11.8562222 2.24199998,11.3673333 C1.95533332,10.8784444 1.73222221,10.3462222 1.57266666,9.77066667 C1.4131111,9.19511112 1.33333333,8.6048889 1.33333333,8 C1.33333333,7.3951111 1.4131111,6.80488888 1.57266666,6.22933333 C1.73222221,5.65377778 1.95533332,5.12155555 2.24199998,4.63266666 C2.52866665,4.14377776 2.87666665,3.69488887 3.28599998,3.28599998 C3.69533332,2.8771111 4.14422221,2.5291111 4.63266666,2.24199998 C5.1211111,1.95488887 5.65333333,1.73177776 6.22933333,1.57266666 C6.80533333,1.41355555 7.39555555,1.33377778 8,1.33333333 Z M6.68733333,2.828 C6.11444444,2.97377778 5.58066667,3.20977778 5.086,3.536 C4.59133333,3.86222222 4.166,4.24933333 3.81,4.69733333 C3.454,5.14533333 3.17444444,5.65488889 2.97133333,6.226 C2.76822221,6.79711111 2.66666666,7.38822222 2.66666666,7.99933333 C2.66666666,8.72155555 2.80733332,9.41155555 3.08866666,10.0693333 C3.36999999,10.7271111 3.74933332,11.2948889 4.22666666,11.7726667 C4.70399999,12.2504444 5.27177777,12.6297778 5.92999998,12.9106667 C6.5882222,13.1915556 7.2782222,13.3322222 7.99999998,13.3326667 C8.6111111,13.3326667 9.20222221,13.2311111 9.77333331,13.028 C10.3444444,12.8248889 10.854,12.5453333 11.302,12.1893333 C11.75,11.8333333 12.1371111,11.408 12.4633333,10.9133333 C12.7895555,10.4186666 13.0255555,9.88488887 13.1713333,9.31199998 C13.022,9.32577777 12.8535555,9.33266666 12.666,9.33266666 C11.8535555,9.33266666 11.0775555,9.17377777 10.338,8.85599998 C9.59844443,8.5382222 8.96044443,8.11111109 8.42399998,7.57466666 C7.88755554,7.03822222 7.46044443,6.40022222 7.14266666,5.66066666 C6.82488889,4.92111109 6.66599999,4.14511109 6.66599998,3.33266666 C6.66599998,3.1451111 6.67288888,2.97666666 6.68666666,2.82733333 L6.68733333,2.828 Z" id="Dark-\u5F62\u72B6"></path></g></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

-1
View File
@@ -1 +0,0 @@
<svg width="1em" height="1em" class="icon-light" viewBox="0 0 13 13" xmlns="http://www.w3.org/2000/svg" style="vertical-align: -0.125em;color: rgba(0, 0, 0, 0.88);"><g id="Light-\u9875\u9762-1" stroke="none" stroke-width="1px" fill="none" fill-rule="evenodd"><g id="Light-\u4E3B\u9898\u5305" transform="translate(-2943.000000, -292.000000)" fill="currentColor" fill-rule="nonzero"><g id="Light-\u7F16\u7EC4-12" transform="translate(2415.000000, 222.000000)"><g id="Light-\u89C6\u56FE\u5207\u6362-\u7F16\u8F91\u6001" transform="translate(518.000000, 60.000000)"><g id="Light-eye" transform="translate(8.000000, 8.000000)"><g id="Light-sun" transform="translate(2.000000, 2.000000)"><rect id="Light-\u77E9\u5F62" opacity="0" x="0" y="0" width="13" height="13"></rect><path d="M6.5,9.75 C4.7051875,9.75 3.25,8.2948125 3.25,6.5 C3.25,4.7051875 4.7051875,3.25 6.5,3.25 C8.2948125,3.25 9.75,4.7051875 9.75,6.5 C9.75,8.2948125 8.2948125,9.75 6.5,9.75 Z M6.5,8.66666667 C7.69661696,8.66666667 8.66666667,7.69661696 8.66666667,6.5 C8.66666667,5.30338304 7.69661696,4.33333333 6.5,4.33333333 C5.30338305,4.33333333 4.33333336,5.30338305 4.33333336,6.5 C4.33333336,7.69661695 5.30338305,8.66666667 6.5,8.66666667 Z M5.95833333,1.08333333 C5.95833333,0.784179087 6.20084576,0.541666658 6.5,0.541666658 C6.79915424,0.541666658 7.04166667,0.784179087 7.04166667,1.08333333 L7.04166667,2.16666667 C7.04166667,2.46582091 6.79915424,2.70833334 6.5,2.70833334 C6.20084576,2.70833334 5.95833333,2.46582091 5.95833333,2.16666667 L5.95833333,1.08333333 L5.95833333,1.08333333 Z M5.95833333,10.8333333 C5.95833333,10.5341791 6.20084576,10.2916667 6.5,10.2916667 C6.79915424,10.2916667 7.04166667,10.5341791 7.04166667,10.8333333 L7.04166667,11.9166667 C7.04166667,12.2158209 6.79915424,12.4583333 6.5,12.4583333 C6.20084576,12.4583333 5.95833333,12.2158209 5.95833333,11.9166667 L5.95833333,10.8333333 L5.95833333,10.8333333 Z M1.08333333,7.04166667 C0.784179087,7.04166667 0.541666658,6.79915424 0.541666658,6.5 C0.541666658,6.20084576 0.784179087,5.95833333 1.08333333,5.95833333 L2.16666667,5.95833333 C2.46582091,5.95833333 2.70833334,6.20084576 2.70833334,6.5 C2.70833334,6.79915424 2.46582091,7.04166667 2.16666667,7.04166667 L1.08333333,7.04166667 L1.08333333,7.04166667 Z M10.8333333,7.04166667 C10.5341791,7.04166667 10.2916667,6.79915424 10.2916667,6.5 C10.2916667,6.20084576 10.5341791,5.95833333 10.8333333,5.95833333 L11.9166667,5.95833333 C12.2158209,5.95833333 12.4583333,6.20084576 12.4583333,6.5 C12.4583333,6.79915424 12.2158209,7.04166667 11.9166667,7.04166667 L10.8333333,7.04166667 L10.8333333,7.04166667 Z M2.05454167,2.82045833 C1.84926545,2.60791971 1.85220137,2.27007933 2.06114035,2.06114035 C2.27007933,1.85220137 2.60791971,1.84926545 2.82045833,2.05454167 L3.63295833,2.86704167 C3.83823455,3.07958029 3.83529863,3.41742067 3.62635965,3.62635965 C3.41742067,3.83529863 3.07958029,3.83823455 2.86704167,3.63295833 L2.05454167,2.82045833 L2.05454167,2.82045833 Z M9.36704167,10.1329583 C9.16176545,9.92041971 9.16470137,9.58257933 9.37364035,9.37364035 C9.58257933,9.16470137 9.92041971,9.16176545 10.1329583,9.36704167 L10.9454583,10.1795417 C11.1507346,10.3920803 11.1477986,10.7299207 10.9388596,10.9388596 C10.7299207,11.1477986 10.3920803,11.1507346 10.1795417,10.9454583 L9.36704167,10.1329583 L9.36704167,10.1329583 Z M2.82045833,10.9454583 C2.60791971,11.1507346 2.27007933,11.1477986 2.06114035,10.9388596 C1.85220137,10.7299207 1.84926545,10.3920803 2.05454167,10.1795417 L2.86704167,9.36704167 C3.07958029,9.16176545 3.41742067,9.16470137 3.62635965,9.37364035 C3.83529863,9.58257933 3.83823455,9.92041971 3.63295833,10.1329583 L2.82045833,10.9454583 L2.82045833,10.9454583 Z M10.1329583,3.63295833 C9.92041971,3.83823455 9.58257933,3.83529863 9.37364035,3.62635965 C9.16470137,3.41742067 9.16176545,3.07958029 9.36704167,2.86704167 L10.1795417,2.05454167 C10.3920803,1.84926545 10.7299207,1.85220137 10.9388596,2.06114035 C11.1477986,2.27007933 11.1507346,2.60791971 10.9454583,2.82045833 L10.1329583,3.63295833 L10.1329583,3.63295833 Z" id="Light-\u5F62\u72B6"></path></g></g></g></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

+5 -6
View File
@@ -3,7 +3,7 @@
:drag="true"
:destroyOnClose="true"
:title="t('components.CronModal.title')"
:open="props.open"
:visible="props.visible"
:body-style="{ padding: '0 24px' }"
@cancel="fnCronModal(false)"
@ok="fnCronModal(true)"
@@ -35,7 +35,6 @@
</ProModal>
</template>
<script lang="ts" setup>
import { ProModal } from 'antdv-pro-modal';
import CronSecond from './components/Second.vue';
import CronMinute from './components/Minute.vue';
import CronHour from './components/Hour.vue';
@@ -45,9 +44,9 @@ import { reactive, computed, watch } from 'vue';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const emit = defineEmits(['cancel', 'ok', 'update:open']);
const emit = defineEmits(['cancel', 'ok', 'update:visible']);
const props = defineProps({
open: {
visible: {
type: Boolean,
required: true,
},
@@ -76,7 +75,7 @@ const cronStr = computed(() => {
/**监听是否显示,初始cron属性 */
watch(
() => props.open,
() => props.visible,
val => {
if (!val) return;
const arr = props.cron.split(' ');
@@ -99,7 +98,7 @@ watch(
* @param val modal触发事件
*/
function fnCronModal(val: boolean) {
emit('update:open', false);
emit('update:visible', false);
if (val) {
emit('ok', cronStr.value);
} else {
+2 -2
View File
@@ -12,7 +12,7 @@ const router = useRouter();
const { t } = useI18n();
/**显示遮罩 */
const isOpen = computed(() => !['none', 'lock'].includes(maskStore.type));
const isVisible = computed(() => !['none', 'lock'].includes(maskStore.type));
// 用户无操作一段时间后进行锁屏
function idleTimeout(time: number, callback: Function) {
@@ -67,7 +67,7 @@ onUnmounted(() => {});
</script>
<template>
<a-modal
v-model:open="isOpen"
v-model:visible="isVisible"
get-container="#app"
:footer="null"
:zIndex="1008"
+20 -43
View File
@@ -1,9 +1,9 @@
<!-- https://github.com/jackocnr/intl-tel-input/blob/master/react/src/intl-tel-input/react.tsx -->
<script lang="ts" setup>
import { Iti } from 'intl-tel-input';
import intlTelInput from 'intl-tel-input/intlTelInputWithUtils';
import intlTelInput, { Iti, SomeOptions } from 'intl-tel-input';
import 'intl-tel-input/build/css/intlTelInput.min.css';
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
import 'intl-tel-input/build/js/utils.js';
import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
import useI18n from '@/hooks/useI18n';
const { currentLocale } = useI18n();
const emit = defineEmits(['update:value', 'update:change']);
@@ -45,13 +45,13 @@ const itiRef = ref<Iti | null>(null);
function fnChange() {
if (!itiRef.value) return;
const number = itiRef.value?.getNumber() || '';
const num = itiRef.value?.getNumber() || '';
const countryIso = itiRef.value?.getSelectedCountryData().iso2 || '';
// note: this number will be in standard E164 format, but any container component can use
// intlTelInputUtils.formatNumber() to convert this to another format
// as well as intlTelInputUtils.getNumberType() etc. if need be
let data = {
number,
num,
countryIso,
validity: false,
errorCode: -1,
@@ -69,11 +69,21 @@ function fnChange() {
data.errorCode = errorCode;
}
// console.log(data);
emit('update:value', number);
emit('update:value', num);
emit('update:change', data);
}
watch(
() => props.value,
v => {
if (v) {
itiRef.value?.setNumber(v);
} else {
itiRef.value?.setNumber('');
}
}
);
onMounted(() => {
nextTick(async () => {
if (inputRef.value) {
@@ -96,13 +106,7 @@ onMounted(() => {
formatOnDisplay: true,
autoPlaceholder: 'polite',
i18n: i18n,
});
if (props.value) {
itiRef.value.setNumber(props.value);
}
if (props.disabled) {
itiRef.value.setDisabled(props.disabled);
}
} as SomeOptions);
inputRef.value.addEventListener('countrychange', fnChange);
}
});
@@ -120,7 +124,8 @@ onBeforeUnmount(() => {
<input
type="tel"
class="ant-input"
ref="inputRef"
ref="inputRef"
:value="value"
:disabled="disabled"
:placeholder="placeholder"
:maxlength="maxlength"
@@ -137,32 +142,4 @@ onBeforeUnmount(() => {
.iti .iti__country-container .iti__search-input {
padding: 4px 8px;
}
.iti .ant-input {
box-sizing: border-box;
margin: 0;
font-variant: tabular-nums;
list-style: none;
font-feature-settings: 'tnum';
position: relative;
display: inline-block;
width: 100%;
min-width: 0;
padding: 4px 11px;
color: #000000d9;
font-size: 14px;
line-height: 1.5715;
background-color: transparent;
background-image: none;
border: 1px solid #424242;
border-radius: 6px;
transition: all 0.3s;
}
.iti .ant-input:focus,
.iti .ant-input-focused {
border-color: var(--ant-primary-color-hover);
box-shadow: 0 0 0 2px var(--ant-primary-color-outline);
border-right-width: 1px !important;
outline: 0;
}
</style>
+3 -4
View File
@@ -2,6 +2,7 @@
import { reactive, watch, onMounted, PropType, nextTick } from 'vue';
import { Container, Draggable } from 'vue3-smooth-dnd';
import useI18n from '@/hooks/useI18n';
import { type ColumnsType } from 'ant-design-vue/lib/table';
import { dbGetJSON, dbSetJSON } from '@/utils/cache-db-utils';
import { CACHE_DB_TABLE_DND } from '@/constants/cache-keys-constants';
const { t, currentLocale } = useI18n();
@@ -36,7 +37,7 @@ const props = defineProps({
});
/**表格字段列 */
const tableColumns = reactive(props.columns);
const tableColumns = reactive<ColumnsType>(props.columns);
/**表格字段列勾选状态 */
const state = reactive<{
@@ -55,9 +56,7 @@ const state = reactive<{
function fnTableColumnsCheckAllChange(e: any) {
const checked = e.target.checked;
state.indeterminate = false;
state.columnsTitleList = checked
? tableColumns.map(s => `${s.title as string}`)
: [];
state.columnsTitleList = checked ? tableColumns.map(s => `${s.title}`) : [];
}
/**表格字段列拖拽操作 */
-225
View File
@@ -1,225 +0,0 @@
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { FitAddon } from '@xterm/addon-fit';
import { Terminal } from '@xterm/xterm';
import '@xterm/xterm/css/xterm.css';
import { RESULT_CODE_ERROR } from '@/constants/result-constants';
import { OptionsType, WS } from '@/plugins/ws-websocket';
const ws = new WS();
const emit = defineEmits(['connect', 'close', 'message']);
const props = defineProps({
/**终端ID,必传 */
id: {
type: String,
required: true,
},
/**连接主机ID,必传 */
hostId: {
type: String,
required: true,
},
/**初始发送命令 */
initCmd: {
type: [String, Boolean],
default: false,
},
});
/**终端输入DOM节点实例对象 */
const terminalDom = ref<HTMLElement | undefined>(undefined);
/**终端输入实例对象 */
const terminal = ref<any>(null);
/**终端输入命令 */
const terminalCmd = ref<string>('');
/**终端输入渲染 */
function handleRanderXterm(container: HTMLElement | undefined) {
if (!container) return;
const xterm = new Terminal({
lineHeight: 1.2,
fontSize: 12,
fontFamily: "Monaco, Menlo, Consolas, 'Courier New', monospace",
theme: {
background: '#000000',
},
cursorBlink: true, // 光标闪烁
cursorStyle: 'block',
scrollback: 1000,
scrollSensitivity: 15,
tabStopWidth: 4,
disableStdin: false, // 禁止输入
});
// 挂载
xterm.open(container);
// 自适应尺寸
const fitAddon = new FitAddon();
xterm.loadAddon(fitAddon);
// 终端输入字符按键监听
xterm.onKey(({ key, domEvent }) => {
// console.log(key, domEvent);
// 单键输入
switch (domEvent.key) {
case 'Enter':
const cmdStr = terminalCmd.value.trim();
// 发送文本
terminal.value.scrollToBottom();
terminal.value.writeln('\r\n');
ws.send({
requestId: `redis_${props.hostId}`,
type: 'redis',
data: `${cmdStr}\r\n`,
});
terminalCmd.value = '';
// 退出登录
if ('quit' === cmdStr) {
setTimeout(() => {
ws.close();
}, 1000);
}
break;
case 'Backspace':
// 处理退格键,删除最后一个字符
xterm.write('\b \b');
break;
default:
xterm.write(key);
terminalCmd.value += key;
return;
}
});
// 创建 ResizeObserver 实例
var observer = new ResizeObserver(entries => {
fitAddon.fit();
});
// 监听元素大小变化
observer.observe(container);
terminal.value = xterm;
}
/**连接打开后回调 */
function wsOpen(ev: any) {
// console.info('wsOpen', ev);
nextTick(() => {
handleRanderXterm(terminalDom.value);
// 连接事件
emit('connect', {
timeStamp: ev.timeStamp,
cols: terminal.value.cols,
rows: terminal.value.rows,
hostId: props.hostId,
id: props.id,
});
// 初始发送命令
if (typeof props.initCmd === 'string') {
ws.send({
requestId: `redis_${props.hostId}`,
type: 'redis',
data: `${props.initCmd}\r\n`,
});
}
});
}
/**连接错误后回调 */
function wsError(ev: any) {
console.error('wsError', ev);
if (terminal.value != null) {
let message = 'disconnected';
terminal.value.write(`\x1b[31m${message}\x1b[m\r\n`);
} else if (terminalDom.value) {
terminalDom.value.style.background = '#000';
terminalDom.value.style.color = '#ff4d4f';
terminalDom.value.style.height = '60%';
terminalDom.value.innerText = 'disconnected';
}
}
/**连接关闭后回调 */
function wsClose(code: number) {
// console.warn('wsClose', code);
if (terminal.value != null) {
let message = 'disconnected';
terminal.value.write(`\x1b[31m${message}\x1b[m\r\n`);
}
// 关闭事件
emit('close', {
code: code,
hostId: props.hostId,
id: props.id,
});
}
/**接收消息后回调 */
function wsMessage(res: Record<string, any>) {
emit('message', res);
// console.log('wsMessage', res);
const { code, requestId, data } = res;
if (code === RESULT_CODE_ERROR) {
console.warn(res.msg);
return;
}
if (!requestId) return;
if (data.indexOf('is empty') > 0) return;
if (terminal.value != null) {
// terminal.value.write(data.trim().replace(/\n/g, "\r\n"));
// 是否n结尾
if (/[\r\n]$/.test(data)) {
terminal.value.writeln(data.trim().replace(/\n/g, '\r\n'));
} else {
terminal.value.write(data.replace(/\n/g, '\r\n'));
}
}
}
onMounted(() => {
if (props.hostId) {
// 建立链接
const options: OptionsType = {
url: '/ws/redis',
params: {
hostId: props.hostId,
},
onmessage: wsMessage,
onerror: wsError,
onopen: wsOpen,
onclose: wsClose,
};
ws.connect(options);
}
});
onBeforeUnmount(() => {
ws.close();
});
// 给组件设置属性 ref="xxxTerminal"
// setup内使用 const xxxTerminal = ref();
defineExpose({
/**发送方法 */
send: (data: string) => {
ws.send({
requestId: `redis_${props.hostId}`,
type: 'redis',
data: `${data}\r\n`,
});
},
});
</script>
<template>
<div class="terminal">
<div ref="terminalDom" :id="id" class="terminal"></div>
</div>
</template>
<style lang="css" scoped>
.terminal {
width: 100%;
height: 100%;
}
</style>
+1 -1
View File
@@ -126,7 +126,7 @@ function handleRanderXterm(container: HTMLElement | undefined) {
// console.log('尺寸', cols, rows);
ws.send({
requestId: `ssh_resize_${props.hostId}`,
type: 'resize',
type: 'ssh_resize',
data: { cols, rows },
});
});
+21 -43
View File
@@ -43,11 +43,6 @@ const props = defineProps({
type: String,
default: 'ssh',
},
/**消息处理函数 */
processMessages: {
type: Function,
default: undefined,
},
});
/**终端输入DOM节点实例对象 */
@@ -158,49 +153,32 @@ function wsMessage(res: Record<string, any>) {
}
if (!requestId) return;
if (terminal.value != null) {
let text = '';
// 处理消息
if (props.processMessages) {
text = props.processMessages(data);
}else{
text = processMessage(data);
}
// 无消息是则不输出
if (text === '') {
// 查找的开始输出标记
const parts: string[] = data.split('\u001b[?2004l\r');
if (parts.length > 0) {
let text = parts[parts.length - 1];
// 找到最后输出标记
let lestIndex = text.lastIndexOf('\u001b[?2004h\u001b]0;');
if (lestIndex !== -1) {
text = text.substring(0, lestIndex);
}
if (text === '' || text === '\r\n' || text.startsWith('^C\r\n')) {
return;
}
// 是否还有最后输出标记
lestIndex = text.lastIndexOf('\u001b[?2004h');
if (lestIndex !== -1) {
text = text.substring(0, lestIndex);
}
// console.log({ parts, text });
terminal.value.write(text);
return;
}
terminal.value.write(text);
// 无标记
terminal.value.write(data);
}
}
/**终端消息处理*/
function processMessage(data: string): string {
// 查找的开始输出标记
const parts: string[] = data.split('\u001b[?2004l\r');
if (parts.length > 0) {
if (parts[0].startsWith('^C') || parts[0].startsWith('\r')) {
return '';
}
let text = parts[parts.length - 1];
// 找到最后输出标记
let lestIndex = text.lastIndexOf('\u001b[?2004h\u001b]0;');
if (lestIndex !== -1) {
text = text.substring(0, lestIndex);
}
if (text === '' || text === '\r\n' || text.startsWith('^C\r\n')) {
return '';
}
// 是否还有最后输出标记
lestIndex = text.lastIndexOf('\u001b[?2004h');
if (lestIndex !== -1) {
text = text.substring(0, lestIndex);
}
// console.log({ parts, text });
return text;
}
return data;
}
onMounted(() => {
if (props.neType && props.neId) {
// 建立链接
+2 -2
View File
@@ -1,5 +1,5 @@
<script lang="ts" setup>
import { message } from 'ant-design-vue/es';
import { message } from 'ant-design-vue/lib';
import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { FitAddon } from '@xterm/addon-fit';
import { Terminal } from '@xterm/xterm';
@@ -160,7 +160,7 @@ function handleRanderXterm(container: HTMLElement | undefined) {
// console.log('尺寸', cols, rows);
ws.send({
requestId: `telnet_resize_${props.hostId}`,
type: 'resize',
type: 'telnet_resize',
data: { cols, rows },
});
});
+97
View File
@@ -0,0 +1,97 @@
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { FitAddon } from '@xterm/addon-fit';
import { Terminal } from '@xterm/xterm';
import '@xterm/xterm/css/xterm.css';
const emit = defineEmits(['update:value']);
const props = defineProps({
/**终端ID,必传 */
id: {
type: String,
required: true,
},
/**窗口单行字符数 */
cols: {
type: Number,
default: 80,
},
/**窗口行数 */
rows: {
type: Number,
default: 40,
},
/**信息 */
value: {
type: String,
default: '',
},
});
/**终端输入DOM节点实例对象 */
const terminalDom = ref<HTMLElement | undefined>(undefined);
/**终端输入实例对象 */
const terminal = ref<any>(null);
/**终端输入渲染 */
function handleRanderXterm(container: HTMLElement | undefined) {
if (!container) return;
const xterm = new Terminal({
cols: props.cols,
rows: props.rows,
lineHeight: 1.2,
fontSize: 12,
fontFamily: "Monaco, Menlo, Consolas, 'Courier New', monospace",
theme: {
background: '#000000',
},
cursorBlink: false, // 光标闪烁
cursorStyle: 'block',
scrollback: 1000,
scrollSensitivity: 15,
tabStopWidth: 4,
disableStdin: true, // 禁止输入
});
// 挂载
xterm.open(container);
// 自适应尺寸
const fitAddon = new FitAddon();
xterm.loadAddon(fitAddon);
// 创建 ResizeObserver 实例
var observer = new ResizeObserver(entries => {
fitAddon.fit();
});
// 监听元素大小变化
observer.observe(container);
terminal.value = xterm;
}
onMounted(() => {
nextTick(() => {
handleRanderXterm(terminalDom.value);
// 初始发送命令
if (typeof props.value === 'string') {
terminal.value.write(props.value);
}
});
});
onBeforeUnmount(() => {
if (terminal.value != null) {
terminal.value.dispose();
}
});
</script>
<template>
<div ref="terminalDom" :id="id" class="terminal"></div>
</template>
<style lang="css" scoped>
.terminal {
width: 100%;
height: 100%;
}
</style>
+6 -7
View File
@@ -1,11 +1,10 @@
<script setup lang="ts">
import { message } from 'ant-design-vue/es';
import { FileType } from 'ant-design-vue/es/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { ProModal } from 'antdv-pro-modal';
import { message } from 'ant-design-vue/lib';
import { FileType } from 'ant-design-vue/lib/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const emit = defineEmits(['upload', 'close', 'update:open']);
const emit = defineEmits(['upload', 'close', 'update:visible']);
const props = defineProps({
/**窗口标题 */
title: {
@@ -18,7 +17,7 @@ const props = defineProps({
default: false,
},
/**是否弹出显示,必传 */
open: {
visible: {
type: Boolean,
required: true,
},
@@ -81,7 +80,7 @@ function fnUpload(up: UploadRequestOption) {
:drag="true"
:destroyOnClose="true"
:title="props.title"
:open="props.open"
:visible="props.visible"
:keyboard="false"
:mask-closable="false"
:confirm-loading="props.loading"
-2
View File
@@ -16,9 +16,7 @@ export const NE_TYPE_LIST = [
'N3IWF',
'MOCNGW',
'SMSC',
'SMSF',
'CBC',
'CHF',
];
/**
+1 -1
View File
@@ -1,5 +1,5 @@
import { onBeforeMount } from 'vue';
import { ConfigProvider, message } from 'ant-design-vue/es';
import { ConfigProvider, message } from 'ant-design-vue/lib';
import { CACHE_LOCAL_PRIMARY_COLOR } from '@/constants/cache-keys-constants';
import { localGet, localSet } from '@/utils/cache-local-utils';
+4 -26
View File
@@ -6,7 +6,7 @@ export default {
// 通用
common: {
title: 'Login Platform',
title: 'Core Network Management Platform',
desc: 'Core Network Management Platform',
loading: 'Please wait...',
inputPlease: 'Please input',
@@ -192,7 +192,6 @@ export default {
lockPasswd: "Unlock Password",
lockPasswdTip: "No password can be set",
fullscreen: "Full Screen",
theme: "Theme light/dark mode",
logout: "Logout",
profile: "Profile",
settings: "Settings",
@@ -318,8 +317,6 @@ export default {
color: "Style color scheme",
colorActions: "Overall style color scheme setting",
colorRandomly: "Randomization",
theme: "Theme dark and light modes",
themeActions: "Toggle light/dark mode",
navTheme: "Dark Menu",
navThemeActions: "Menus that can only change the navigation mode",
fixedHeader: "Fixed top navigation bar",
@@ -870,7 +867,7 @@ export default {
import: 'Import',
loadDataConfirm: 'Are you sure you want to reload the data?',
loadData: 'Load Data',
loadDataTip: 'Successfully fetched loaded data: {num} items, the system is internally updating the data, it will take about {timer} seconds, please wait!!!!!.',
loadDataTip: 'Successfully fetched load data: {num} entries, the system is internally updating the data. Please wait a moment!!!!',
startIMSI: 'Start IMSI',
batchAddText: 'Batch Add',
batchDelText: 'Batch Delete',
@@ -898,7 +895,7 @@ export default {
import: 'Import',
loadDataConfirm: 'Are you sure you want to reload the data?',
loadData: 'Load Data',
loadDataTip: 'Successfully fetched loaded data: {num} items, the system is internally updating the data, it will take about {timer} seconds, please wait!!!!!.',
loadDataTip: 'Successfully fetched load data: {num} entries, the system is internally updating the data. Please wait a moment!!!!',
numAdd: 'Number of releases',
numDel: 'Number of deleted',
checkDel: 'Check Delete',
@@ -1057,14 +1054,6 @@ export default {
realTimeData: "Real Time Data",
},
customTarget:{
TourTitle1:'Calculate element selection',
TourDes1:'Select the metric corresponding to the selected NE type for the calculation formula',
TourTitle2:'Calculate symbol selection',
TourDes2:'Select a calculation symbol',
TourTitle3:'Calculation formula',
TourDes3:'The calculation formula is automatically composed from the calculation elements and calculation symbols selected earlier',
TourTitle4:'Result unit',
TourDes4:'Units are optional. PS: Formula automatically × 100% when the % sign',
kpiId:' Custom Indicator',
kpiIdTip:'This Ne has no custom indicators',
period:' Granularity',
@@ -1073,9 +1062,7 @@ export default {
expression:'Expression',
description:' Description',
kpiSet:' Statistical Settings',
sixHoursAgo:'Six hours ago',
threeHoursAgo:'Three hours ago.',
delCustomTip:'Confirm deletion of data item with record Custom Indicator {num}?',
delCustomTip:'Confirm deletion of data item with record number {num}?',
delCustom:' Successfully delete record number {num} custom indicator',
addCustom:' Add custom indicator',
editCustom:' Edit Custom indicator',
@@ -1087,14 +1074,8 @@ export default {
element:'Element',
granularity:'Granularity',
unit:'Unit',
expressionModal:'Expression Modal',
expressionErrorTip:'Please check the expression, the wrong indicator is {kpiId}',
expressionNoIdTip:'Please check the expression, no valid indicator is found',
},
kpiKeyTarget:{
"time":"Time",
"rawData":"Table Data",
"statistics":"NE metrics",
"fullWidthLayout":"Full Width",
"twoColumnLayout":"Two Column",
"saveLayout": "Save Layout",
@@ -1107,9 +1088,6 @@ export default {
"layout3": "Layout 3"
},
kpiOverView:{
"kpiName":"NE Metrics Name",
"maxValue":"Max Value",
"minValue":"Min Value",
"kpiChartTitle":"Overview of NE metrics",
"changeLine":"Change to Line Charts",
"changeBar":"Change to Bar Charts",
+8 -29
View File
@@ -6,7 +6,7 @@ export default {
// 通用
common: {
title: '登录平台',
title: '核心网管理平台',
desc: '核心网管理平台',
loading: '请稍等...',
inputPlease: '请输入',
@@ -192,7 +192,6 @@ export default {
lockPasswd: "解锁密码",
lockPasswdTip: "可不设置密码",
fullscreen: "全屏显示",
theme: "主题明/暗模式",
logout: "退出登录",
profile: "个人中心",
settings: "个人设置",
@@ -318,8 +317,6 @@ export default {
color: "风格配色",
colorActions: "整体风格配色设置",
colorRandomly: "随机",
theme: "主题明暗模式",
themeActions: "切换浅色/暗黑模式",
navTheme: "深色菜单",
navThemeActions: "只能改变导航模式的菜单",
fixedHeader: "固定顶部导航栏",
@@ -870,7 +867,7 @@ export default {
import: '导入',
loadDataConfirm: '确认要重新加载数据吗?',
loadData: '加载数据',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,大约需要{timer}秒,请稍候!!!',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,请稍候!!!',
startIMSI: '起始IMSI',
batchAddText: '批量新增',
batchDelText: '批量删除',
@@ -898,7 +895,7 @@ export default {
import: '导入',
loadDataConfirm: '确认要重新加载数据吗?',
loadData: '加载数据',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,大约需要{timer}秒,请稍候!!!',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,请稍候!!!',
numAdd: '放号个数',
numDel: '删除个数',
checkDel:'勾选删除',
@@ -1057,14 +1054,6 @@ export default {
realTimeData: "实时数据",
},
customTarget:{
TourTitle1:'计算元素选择',
TourDes1:'选择已经勾选网元类型对应的指标用于计算公式',
TourTitle2:'计算符号选择',
TourDes2:'选择计算符号',
TourTitle3:'计算公式',
TourDes3:'由前面选择的计算元素和计算符号自动组成计算公式',
TourTitle4:'结果单位',
TourDes4:'单位可选可填。PS:%符号时公式自动×100%',
kpiId:'自定义指标项',
kpiIdTip:'该网元没有自定义指标',
period:'颗粒度',
@@ -1073,9 +1062,7 @@ export default {
expression:'计算公式',
description:'描述',
kpiSet:'统计设置',
sixHoursAgo:'6小时前',
threeHoursAgo:'3小时前',
delCustomTip:'确认删除自定义指标项为 {num} 的数据项?',
delCustomTip:'确认删除记录编号为 {num} 的数据项?',
delCustom:'成功删除记录编号为 {num} 自定义指标',
addCustom:'添加自定义指标',
editCustom:'编辑自定义指标',
@@ -1087,14 +1074,8 @@ export default {
element:'元素',
granularity:'颗粒度',
unit:'单位',
expressionModal:'表达式模块',
expressionErrorTip:'请检查表达式,错误的指标为{kpiId}',
expressionNoIdTip:'请检查表达式,没有找到任何有效的指标',
},
},
kpiKeyTarget:{
"time":"时间",
"rawData":"表格数据",
"statistics":"指标",
"fullWidthLayout":"全宽布局",
"twoColumnLayout":"两列布局",
"saveLayout": "保存布局",
@@ -1107,14 +1088,12 @@ export default {
"layout3": "布局3"
},
kpiOverView:{
"kpiName":"指标名",
"maxValue":"最大值",
"minValue":"最小值",
"kpiChartTitle":"网元指标概览",
"changeLine":"切换为折线图",
"changeBar":"切换为柱状图",
"chooseShowMetrics":"选择需要显示的指标",
"chooseMetrics":"选择指标",
},
},
traceManage: {
@@ -1356,8 +1335,8 @@ export default {
filter: "全局过滤",
startTime: '开始时间',
endTime: '结束时间',
today: '今天',
yesterday: '昨天',
today: '昨天',
yesterday: '今天',
week: '本周',
month: '本月',
avgLoad: '平均负载',
+16 -32
View File
@@ -1,9 +1,10 @@
<script setup lang="ts">
import {
ProLayout,
WaterMark,
getMenuData,
clearMenuItem,
MenuDataItem,
type MenuDataItem,
} from 'antdv-pro-layout';
import RightContent from './components/RightContent.vue';
import Tabs from './components/Tabs.vue';
@@ -11,25 +12,26 @@ import GlobalMask from '@/components/GlobalMask/index.vue';
import { scriptUrl } from '@/assets/js/icon_font_8d5l8fzk5b87iudi';
import {
computed,
nextTick,
onMounted,
onUnmounted,
reactive,
watch,
onMounted,
onUnmounted,
nextTick,
} from 'vue';
import { useRouter } from 'vue-router';
import useLayoutStore from '@/store/modules/layout';
import useAppStore from '@/store/modules/app';
import useRouterStore from '@/store/modules/router';
import useTabsStore from '@/store/modules/tabs';
import useI18n from '@/hooks/useI18n';
import useAlarmStore from '@/store/modules/alarm';
import { getServerTime } from '@/api';
import useAppStore from '@/store/modules/app';
import { useRouter } from 'vue-router';
import { MENU_PATH_INLINE } from '@/constants/menu-constants';
const { proConfig, waterMarkContent } = useLayoutStore();
import useI18n from '@/hooks/useI18n';
import { getServerTime } from '@/api';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { parseDateToStr } from '@/utils/date-utils';
import { parseUrlPath } from '@/plugins/file-static-url';
const { proConfig, waterMarkContent } = useLayoutStore();
const { t, currentLocale } = useI18n();
const routerStore = useRouterStore();
const tabsStore = useTabsStore();
@@ -37,7 +39,7 @@ const appStore = useAppStore();
const router = useRouter();
/**菜单面板 */
const layoutState = reactive({
let layoutState = reactive({
collapsed: false, // 是否展开菜单面板
openKeys: ['/'], // 打开菜单key
selectedKeys: ['/index'], // 选中高亮菜单key
@@ -245,7 +247,7 @@ onUnmounted(() => {
</script>
<template>
<a-watermark :content="waterMarkContent" :z-index="100">
<WaterMark :content="waterMarkContent" :z-index="100">
<ProLayout
v-model:collapsed="layoutState.collapsed"
v-model:selectedKeys="layoutState.selectedKeys"
@@ -288,10 +290,10 @@ onUnmounted(() => {
</RouterLink>
</template>
<!--插槽-渲染顶部内容区域,仅布局side有效-->
<!--插槽-顶部左侧,只对side布局有效-->
<template #headerContentRender></template>
<!--插槽-渲染顶部内容右端区域-->
<!--插槽-顶部右侧-->
<template #headerContentRightRender>
<RightContent />
</template>
@@ -362,7 +364,7 @@ onUnmounted(() => {
<!-- 全局遮罩 -->
<GlobalMask />
</a-watermark>
</WaterMark>
</template>
<style lang="less" scoped>
@@ -411,19 +413,6 @@ onUnmounted(() => {
}
}
.theme-light.theme-menu-light .app-name {
color: #141414 !important;
}
.theme-light.theme-menu-dark .app-name {
color: #fff !important;
}
.theme-dark.theme-menu-light .app-name {
color: #fff !important;
}
.theme-dark.theme-menu-dark .app-name {
color: #fff !important;
}
.footer {
z-index: 16;
margin: 0px;
@@ -438,7 +427,6 @@ onUnmounted(() => {
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
padding: 4px 16px;
background: #fff;
box-shadow: 0 1px 4px #0015291f;
@@ -446,10 +434,6 @@ onUnmounted(() => {
height: 32px;
}
[data-theme='dark'] &-fixed {
background: #141414;
}
& #serverTimeDom {
color: inherit;
opacity: 0.85;
+11 -45
View File
@@ -1,22 +1,16 @@
<script setup lang="ts">
import svgLight from '@/assets/svg/light.svg';
import svgDark from '@/assets/svg/dark.svg';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { viewTransitionTheme } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { ref } from 'vue';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { useRoute, useRouter } from 'vue-router';
import { useFullscreen } from '@vueuse/core';
import { hasPermissions } from '@/plugins/auth-user';
import useI18n from '@/hooks/useI18n';
import useLayoutStore from '@/store/modules/layout';
import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user';
import useAlarmStore from '@/store/modules/alarm';
import useMaskStore from '@/store/modules/mask';
import { hasPermissions } from '@/plugins/auth-user';
import { ref } from 'vue';
const { isFullscreen, toggle } = useFullscreen();
const { t, changeLocale, optionsLocale } = useI18n();
const layoutStore = useLayoutStore();
const maskStore = useMaskStore();
const userStore = useUserStore();
const appStore = useAppStore();
@@ -63,13 +57,6 @@ function fnClickAlarm() {
router.push({ name: 'ActiveAlarm_2088' });
}
/**改变主题色 */
function fnClickTheme(e: any) {
viewTransitionTheme(isDarkMode => {
layoutStore.changeConf('theme', isDarkMode ? 'light' : 'dark');
}, e);
}
/**改变多语言 */
function fnChangeLocale(e: any) {
changeLocale(e.key);
@@ -78,7 +65,7 @@ function fnChangeLocale(e: any) {
<template>
<a-space :size="12" align="center">
<a-tooltip placement="bottomRight">
<a-tooltip placement="bottom">
<template #title>{{ t('loayouts.rightContent.alarm') }}</template>
<a-button type="text" style="color: inherit" @click="fnClickAlarm">
<template #icon>
@@ -96,7 +83,7 @@ function fnChangeLocale(e: any) {
<!-- 锁屏操作 -->
<span v-perms:has="['system:setting:lock']">
<a-tooltip placement="bottomRight">
<a-tooltip placement="bottom">
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
<a-button type="text" style="color: inherit" @click="fnClickLock()">
<template #icon>
@@ -105,11 +92,10 @@ function fnChangeLocale(e: any) {
</a-button>
<ProModal
:drag="true"
:center-y="true"
:width="400"
:minHeight="200"
:mask-closable="false"
v-model:open="lockConfirm"
v-model:visible="lockConfirm"
:title="t('loayouts.rightContent.lockTip')"
@ok="fnClickLockToPage()"
>
@@ -133,7 +119,7 @@ function fnChangeLocale(e: any) {
</a-tooltip>
</span>
<a-tooltip placement="bottomRight">
<a-tooltip placement="bottom">
<template #title>{{ t('loayouts.rightContent.fullscreen') }}</template>
<a-button type="text" style="color: inherit" @click="toggle">
<template #icon>
@@ -143,27 +129,14 @@ function fnChangeLocale(e: any) {
</a-button>
</a-tooltip>
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.theme') }}</template>
<a-button type="text" @click="fnClickTheme">
<template #icon>
<img
v-if="layoutStore.proConfig.theme === 'dark'"
:src="svgDark"
class="theme-icon"
/>
<img v-else :src="svgLight" class="theme-icon" />
</template>
</a-button>
</a-tooltip>
<a-dropdown
placement="bottomRight"
placement="bottom"
trigger="click"
v-if="appStore.i18nOpen && hasPermissions(['system:setting:i18n'])"
>
<a-button type="text" style="color: inherit">
<template #icon> <TranslationOutlined /> </template>
<a-button size="small" type="default">
{{ t('i18n') }}
<DownOutlined />
</a-button>
<template #overlay>
<a-menu @click="fnChangeLocale">
@@ -231,11 +204,4 @@ function fnChangeLocale(e: any) {
overflow: hidden;
}
}
.theme-icon {
width: 18px;
height: 18px;
margin-bottom: 4px;
color: inherit;
}
</style>
+3 -14
View File
@@ -4,9 +4,9 @@ import { computed, watch } from 'vue';
import { useRouter } from 'vue-router';
import useTabsStore from '@/store/modules/tabs';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const tabsStore = useTabsStore();
const router = useRouter();
const { t } = useI18n();
defineProps({
/**标签栏宽度 */
@@ -112,7 +112,7 @@ watch(router.currentRoute, v => tabsStore.tabOpen(v), { immediate: true });
<a-tabs
class="tabs"
:class="{ 'tabs-fixed': fixedHeader }"
:style="{ width: fixedHeader ? width : '100%', top: headerRender === false ? 0 : undefined }"
:style="{ width: width, top: headerRender === false ? 0 : undefined }"
hide-add
tab-position="top"
type="editable-card"
@@ -150,7 +150,7 @@ watch(router.currentRoute, v => tabsStore.tabOpen(v), { immediate: true });
</a-tooltip>
<a-tooltip placement="topRight">
<template #title>{{ t('loayouts.tabs.more') }}</template>
<a-dropdown placement="bottomRight" trigger="click">
<a-dropdown trigger="click" placement="bottomRight">
<a-button type="ghost" shape="circle" size="small">
<template #icon><DownOutlined /></template>
</a-button>
@@ -199,18 +199,7 @@ watch(router.currentRoute, v => tabsStore.tabOpen(v), { immediate: true });
}
}
[data-theme='dark'] .tabs {
background: #141414;
}
.tabs :deep(.ant-tabs-nav:before) {
border-bottom: none;
}
.tabs :deep(.ant-tabs-nav-list .ant-tabs-tab) {
border-radius: 8px;
}
.tabs :deep(.ant-tabs-nav-list .ant-tabs-tab.ant-tabs-tab-active) {
border-bottom-right-radius: unset;
border-bottom-left-radius: unset;
}
</style>
+4 -3
View File
@@ -4,15 +4,16 @@ import App from './App.vue';
import router from './router';
import directive from './directive';
import i18n from './i18n';
import 'antdv-pro-modal/dist/style.css';
import ProModal from "antdv-pro-modal";
import 'antdv-pro-layout/dist/style.css';
import 'ant-design-vue/dist/reset.css';
import 'antdv-pro-modal/dist/style.css';
import 'ant-design-vue/dist/antd.variable.min.css';
const app = createApp(App);
app.use(store);
app.use(router);
app.use(directive);
app.use(i18n);
app.use(ProModal);
app.mount('#app');
-23
View File
@@ -19,26 +19,3 @@ export function parseUrlPath(path: string) {
: import.meta.env.VITE_API_BASE_URL;
return `${baseUrl}${path}?r=${Math.random().toFixed(2)}`;
}
/**
* 解析静态文件相对路径
* @param path 静态资源文件
* @returns
*/
export function parseBasePath(path: string) {
if (!path || path === '#') {
return '#';
}
if (validHttp(path)) {
return path;
}
// 兼容旧前端可改配置文件
const baseUrl = import.meta.env.VITE_HISTORY_BASE_URL;
let scriptUrl =
baseUrl.length === 1 && baseUrl.indexOf('/') === 0
? ''
: baseUrl.indexOf('/') === -1
? '/' + baseUrl
: baseUrl;
return `${scriptUrl}${path}?r=${Math.random().toFixed(2)}`;
}
+10 -91
View File
@@ -1,23 +1,16 @@
import { theme } from 'ant-design-vue/es';
import type { ThemeConfig } from 'ant-design-vue/es/config-provider/context';
import { CACHE_LOCAL_PROCONFIG } from '@/constants/cache-keys-constants';
import { localGetJSON, localSetJSON } from '@/utils/cache-local-utils';
import { defineStore } from 'pinia';
import {
CACHE_LOCAL_PRIMARY_COLOR,
CACHE_LOCAL_PROCONFIG,
} from '@/constants/cache-keys-constants';
import {
localGet,
localGetJSON,
localSetJSON,
} from '@/utils/cache-local-utils';
/**布局参数类型 */
type LayoutStore = {
/**布局设置抽屉显示 */
visible: boolean;
/**布局配置 */
proConfig: {
/**导航布局 */
layout: 'side' | 'top' | 'mix';
/**全局主题色*/
/**全局主题色,需要导入样式文件 */
theme: 'dark' | 'light';
/**菜单导航主题色 */
menuTheme: 'dark' | 'light';
@@ -36,33 +29,10 @@ type LayoutStore = {
/**内容区域-导航标签项 */
tabRender: any | boolean | undefined;
};
/**主题配置 */
themeConfig: ThemeConfig;
/**水印内容 */
waterMarkContent: string;
};
/**
* 获取随机颜色范围
* @returns 颜色
*/
function getRandomColor(): string {
const colors: string[] = [
'#f5222d',
'#fa541c',
'#fa8c16',
'#a0d911',
'#13c2c2',
'#1890ff',
'#722ed1',
'#eb2f96',
'#faad14',
'#52c41a',
];
const i = Math.floor(Math.random() * 10);
return colors[i];
}
/**判断是否关闭内容区域 */
const proRender = (render: any) => (render === false ? false : undefined);
@@ -80,6 +50,7 @@ const proConfigLocal: LayoutStore['proConfig'] = localGetJSON(
const useLayoutStore = defineStore('layout', {
state: (): LayoutStore => ({
visible: false,
proConfig: {
layout: proConfigLocal.layout,
theme: proConfigLocal.theme,
@@ -92,27 +63,13 @@ const useLayoutStore = defineStore('layout', {
menuHeaderRender: proRender(proConfigLocal.menuHeaderRender),
tabRender: proRender(proConfigLocal.tabRender),
},
themeConfig: {
algorithm: [theme.darkAlgorithm],
// algorithm: themeColor["dark"],
token: {
// colorBgContainer: "#fff",
colorPrimary: localGet(CACHE_LOCAL_PRIMARY_COLOR) || '#1890ff',
// borderRadius: 6,
},
},
waterMarkContent: import.meta.env.VITE_APP_NAME,
}),
getters: {
getColorPrimary(): string {
let color = '#1890ff';
if (this.themeConfig.token) {
color = this.themeConfig.token.colorPrimary || color;
}
return color;
},
},
actions: {
/**改变显示状态 */
changeVisibleLayoutSetting() {
this.visible = !this.visible;
},
/**修改水印文字 */
changeWaterMark(text: string) {
this.waterMarkContent = text;
@@ -120,48 +77,10 @@ const useLayoutStore = defineStore('layout', {
/**修改布局设置 */
changeConf(key: string, value: boolean | string | number | undefined) {
if (Reflect.has(this.proConfig, key)) {
// console.log(key, value);
if (key === 'theme') {
// const themeColor = {
// light: theme.defaultAlgorithm,
// compact: theme.compactAlgorithm,
// dark: theme.darkAlgorithm,
// };
if (value === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
this.themeConfig.algorithm = [theme.darkAlgorithm];
} else {
document.documentElement.setAttribute('data-theme', 'light');
this.themeConfig.algorithm = [theme.defaultAlgorithm];
}
}
Reflect.set(this.proConfig, key, value);
localSetJSON(CACHE_LOCAL_PROCONFIG, this.proConfig);
}
},
/**主题色初始化 */
initPrimaryColor() {
// 主题色初始化
this.changePrimaryColor(this.getColorPrimary);
// 明暗模式初始化
const themeMode = this.proConfig.theme;
document.documentElement.setAttribute('data-theme', themeMode);
this.changeConf('theme', themeMode);
},
/**
* 主题色变更
* @param color 颜色
*/
changePrimaryColor(color?: string) {
if (!color) {
color = getRandomColor();
}
if (this.themeConfig && this.themeConfig.token) {
this.themeConfig.token.colorPrimary = color;
localStorage.setItem(CACHE_LOCAL_PRIMARY_COLOR, color);
}
},
},
});
+5 -5
View File
@@ -1,7 +1,7 @@
import defaultAvatar from '@/assets/images/default_avatar.png';
import useLayoutStore from './layout';
import { login, logout, getInfo } from '@/api/login';
import { setToken, removeToken } from '@/plugins/auth-token';
import { getToken, setToken, removeToken } from '@/plugins/auth-token';
import { defineStore } from 'pinia';
import { TOKEN_RESPONSE_FIELD } from '@/constants/token-constants';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
@@ -133,10 +133,10 @@ const useUserStore = defineStore('user', {
}
// 水印文字信息=用户昵称 手机号
// let waterMarkContent = this.userName;
// if (this.phonenumber) {
// waterMarkContent = `${this.userName} ${this.phonenumber}`;
// }
let waterMarkContent = this.userName;
if (this.phonenumber) {
waterMarkContent = `${this.userName} ${this.phonenumber}`;
}
// useLayoutStore().changeWaterMark(waterMarkContent);
useLayoutStore().changeWaterMark('');
}
-5
View File
@@ -8,8 +8,3 @@ declare module '*.vue' {
}
declare module 'vue3-smooth-dnd';
declare module 'intl-tel-input/intlTelInputWithUtils' {
import intlTelInput from 'intl-tel-input';
export default intlTelInput;
}
+5 -5
View File
@@ -1,7 +1,7 @@
<script lang="ts" setup>
import { Modal, message } from 'ant-design-vue/es';
import { FileType } from 'ant-design-vue/es/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { Modal, message } from 'ant-design-vue/lib';
import { FileType } from 'ant-design-vue/lib/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import { onMounted, reactive, ref, toRaw } from 'vue';
import { updateUserProfile, uploadAvatar } from '@/api/profile';
import { regExpEmail, regExpMobile, regExpNick } from '@/utils/regular-utils';
@@ -27,7 +27,7 @@ let stateForm = reactive({
nickName: '',
email: '',
phonenumber: '',
sex: '0',
sex: undefined,
},
/**表单提交点击状态 */
formClick: false,
@@ -169,7 +169,7 @@ onMounted(() => {
<IntlTelInput
v-model:value="stateForm.form.phonenumber"
allow-clear
:maxlength="20"
:maxlength="16"
:placeholder="t('views.account.settings.phonenumberPleace')"
></IntlTelInput>
</a-form-item>
@@ -1,5 +1,5 @@
<script lang="ts" setup>
import { Modal, message } from 'ant-design-vue/es';
import { Modal, message } from 'ant-design-vue/lib';
import { reactive } from 'vue';
import { updateUserPwd } from '@/api/profile';
import { regExpPasswd } from '@/utils/regular-utils';
@@ -147,7 +147,7 @@ function fnFinish() {
</a-input-password>
</a-form-item>
<a-form-item :wrapper-col="{ span: 4 }">
<a-form-item :wrapper-col="{ span: 3 }">
<a-button
block
type="primary"
+12 -40
View File
@@ -1,32 +1,22 @@
<script lang="ts" setup>
import { viewTransitionTheme } from 'antdv-pro-layout';
import { ref } from 'vue';
import { getLocalColor, changePrimaryColor } from '@/hooks/useTheme';
import useLayoutStore from '@/store/modules/layout';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const { proConfig, changeConf, themeConfig, changePrimaryColor } =
useLayoutStore();
const { proConfig, changeConf } = useLayoutStore();
let timerId: any = null;
let color = ref<string>(getLocalColor());
/**改变主题色 */
function fnColorChange(e: Event) {
const target = e.target as HTMLInputElement;
// 需要防抖函数处理
clearTimeout(timerId);
timerId = setTimeout(() => {
if (target.nodeName === 'INPUT') {
changePrimaryColor(target.value ?? '#1890ff');
} else {
changePrimaryColor();
}
}, 300);
}
/**手动变更主题-过渡动画 */
function changeTheme(e: any) {
viewTransitionTheme(isDarkMode => {
changeConf('theme', isDarkMode ? 'light' : 'dark');
}, e);
if (target.nodeName === 'INPUT') {
changePrimaryColor(target.value ?? '#1890ff');
} else {
changePrimaryColor();
}
color.value = getLocalColor();
}
</script>
@@ -66,31 +56,13 @@ function changeTheme(e: any) {
<template #extra>
<a-space :size="16" align="end" direction="horizontal">
<a-button type="primary" size="small" @click="fnColorChange">
<BgColorsOutlined />
{{ t('views.account.settings.colorRandomly') }}
</a-button>
<input
type="color"
:value="themeConfig?.token?.colorPrimary"
@input="fnColorChange"
/>
<input type="color" :value="color" @input="fnColorChange" />
</a-space>
</template>
</a-list-item>
<a-list-item>
{{ t('views.account.settings.theme') }}
<template #actions>
{{ t('views.account.settings.themeActions') }}
</template>
<template #extra>
<a-button
:type="proConfig.theme === 'dark' ? 'primary' : 'default'"
size="small"
@click="changeTheme"
>
{{ proConfig.theme }}
</a-button>
</template>
</a-list-item>
<a-list-item>
{{ t('views.account.settings.navTheme') }}
<template #actions>
+1 -2
View File
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import { PageContainer } from 'antdv-pro-layout';
import { message } from 'ant-design-vue/es';
import { message } from 'ant-design-vue/lib';
import { getUserProfile } from '@/api/profile';
import { reactive, ref, onMounted } from 'vue';
import { parseDateToStr } from '@/utils/date-utils';
@@ -205,7 +205,6 @@ onMounted(() => {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px 0;
&-no {
align-self: flex-start;
font-size: 14px;
@@ -0,0 +1,518 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { Form, message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import {
listNeBackup,
delNeBackup,
downloadNeBackup,
} from '@/api/configManage/backupManage';
import { saveAs } from 'file-saver';
import useI18n from '@/hooks/useI18n';
import { updateBackInfo } from '@/api/configManage/backupManage';
import useNeInfoStore from '@/store/modules/neinfo';
const { t } = useI18n();
/**查询参数 */
let queryParams = reactive({
/**网元类型 */
neType: '',
/**当前页数 */
pageNum: 1,
/**每页条数 */
pageSize: 20,
});
/**查询参数重置 */
function fnQueryReset() {
queryParams = Object.assign(queryParams, {
neType: '',
pageNum: 1,
pageSize: 20,
});
tablePagination.current = 1;
tablePagination.pageSize = 20;
fnGetList();
}
/**表格状态类型 */
type TabeStateType = {
/**加载等待 */
loading: boolean;
/**紧凑型 */
size: SizeType;
/**搜索栏 */
seached: boolean;
/**记录数据 */
data: object[];
/**勾选记录 */
selectedRowKeys: (string | number)[];
};
/**表格状态 */
let tableState: TabeStateType = reactive({
loading: false,
size: 'middle',
seached: true,
data: [],
selectedRowKeys: [],
});
/**表格字段列 */
let tableColumns: ColumnsType = [
{
title: t('common.rowId'),
dataIndex: 'id',
align: 'center',
width: 1,
},
{
title: t('views.configManage.backupManage.neType'),
dataIndex: 'neType',
align: 'center',
width: 2,
},
{
title: t('views.configManage.backupManage.neID'),
dataIndex: 'neId',
align: 'center',
width: 2,
},
{
title: t('views.configManage.backupManage.fileName'),
dataIndex: 'fileName',
align: 'center',
width: 3,
},
{
title: t('views.configManage.backupManage.remark'),
dataIndex: 'comment',
align: 'center',
width: 3,
},
{
title: t('views.configManage.backupManage.createAt'),
dataIndex: 'createTime',
align: 'center',
customRender(opt) {
if (!opt.value) return '';
return parseDateToStr(opt.value);
},
width: 3,
},
{
title: t('common.operate'),
key: 'id',
align: 'center',
fixed: 'right',
width: 2,
},
];
/**表格分页器参数 */
let tablePagination = reactive({
/**当前页数 */
current: 1,
/**每页条数 */
pageSize: 20,
/**默认的每页条数 */
defaultPageSize: 20,
/**指定每页可以显示多少条 */
pageSizeOptions: ['10', '20', '50', '100'],
/**只有一页时是否隐藏分页器 */
hideOnSinglePage: false,
/**是否可以快速跳转至某页 */
showQuickJumper: true,
/**是否可以改变 pageSize */
showSizeChanger: true,
/**数据总数 */
total: 0,
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
onChange: (page: number, pageSize: number) => {
tablePagination.current = page;
tablePagination.pageSize = pageSize;
queryParams.pageNum = page;
queryParams.pageSize = pageSize;
fnGetList();
},
});
/**表格紧凑型变更操作 */
function fnTableSize({ key }: MenuInfo) {
tableState.size = key as SizeType;
}
/**信息文件下载 */
function fnDownloadFile(row: Record<string, any>) {
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.configManage.backupManage.totalSure', {
oper: t('common.downloadText'),
id: row.id,
}),
onOk() {
const key = 'downloadNeBackup';
message.loading({ content: t('common.loading'), key });
downloadNeBackup(toRaw(row)).then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.msgSuccess', { msg: t('common.downloadText') }),
key,
duration: 2,
});
saveAs(res.data, `${row.fileName}`);
} else {
message.error({
content: `${res.msg}`,
key,
duration: 2,
});
}
});
},
});
}
/**
* 备份信息删除
* @param row 记录编号ID
*/
function fnRecordDelete(row: Record<string, any>) {
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.configManage.backupManage.totalSure', {
oper: t('common.deleteText'),
id: row.id,
}),
onOk() {
const key = 'delNeBackup';
message.loading({ content: t('common.loading'), key });
delNeBackup(toRaw(row)).then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.msgSuccess', { msg: t('common.deleteText') }),
key,
duration: 2,
});
fnGetList();
} else {
message.error({
content: `${res.msg}`,
key: key,
duration: 2,
});
}
});
},
});
}
/**查询备份信息列表, pageNum初始页数 */
function fnGetList(pageNum?: number) {
if (tableState.loading) return;
tableState.loading = true;
if (pageNum) {
queryParams.pageNum = pageNum;
}
listNeBackup(toRaw(queryParams)).then(res => {
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
// 取消勾选
if (tableState.selectedRowKeys.length > 0) {
tableState.selectedRowKeys = [];
}
tablePagination.total = res.total;
tableState.data = res.rows;
if (
tablePagination.total <=
(queryParams.pageNum - 1) * tablePagination.pageSize &&
queryParams.pageNum !== 1
) {
tableState.loading = false;
fnGetList(queryParams.pageNum - 1);
}
}
tableState.loading = false;
});
}
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
visibleByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
from: Record<string, any>;
/**确定按钮 loading */
confirmLoading: boolean;
};
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
visibleByEdit: false,
title: '任务设置',
from: {
id: 0,
backupInfo: '',
},
confirmLoading: false,
});
/**
* 对话框弹出显示为 新增或者修改
* @param noticeId 网元id, 不传为新增
*/
function fnModalVisibleByEdit(row: Record<string, any>) {
if (modalState.confirmLoading) return;
modalState.from.backupInfo = row.comment;
modalState.from.id = row.id;
modalState.title = t('views.configManage.backupManage.edit');
modalState.visibleByEdit = true;
}
/**对话框内表单属性和校验规则 */
const modalStateFrom = Form.useForm(
modalState.from,
reactive({
backupInfo: [
{
required: true,
message:
t('views.configManage.backupManage.remark') + t('common.unableNull'),
},
],
})
);
/**
* 对话框弹出确认执行函数
* 进行表达规则校验
*/
function fnModalOk() {
modalStateFrom
.validate()
.then(e => {
modalState.confirmLoading = true;
const from = toRaw(modalState.from);
const hide = message.loading(t('common.loading'), 0);
updateBackInfo(from)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.msgSuccess', { msg: modalState.title }),
duration: 3,
});
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
fnGetList();
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
fnGetList();
}
})
.finally(() => {
hide();
modalState.confirmLoading = false;
});
})
.catch(e => {
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
});
}
/**
* 对话框弹出关闭执行函数
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
}
onMounted(() => {
// 获取列表数据
fnGetList();
});
</script>
<template>
<PageContainer>
<a-card
v-show="tableState.seached"
:bordered="false"
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
>
<!-- 表格搜索栏 -->
<a-form :model="queryParams" name="queryParams" layout="horizontal">
<a-row :gutter="16">
<a-col :lg="6" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.backupManage.neType')"
name="neType "
>
<a-auto-complete
v-model:value="queryParams.neType"
:options="useNeInfoStore().getNeSelectOtions"
allow-clear
:placeholder="t('views.configManage.backupManage.neTypePlease')"
/>
</a-form-item>
</a-col>
<a-col :lg="6" :md="12" :xs="24">
<a-form-item>
<a-space :size="8">
<a-button type="primary" @click.prevent="fnGetList(1)">
<template #icon><SearchOutlined /></template>
{{ t('common.search') }}
</a-button>
<a-button type="default" @click.prevent="fnQueryReset">
<template #icon><ClearOutlined /></template>
{{ t('common.reset') }}
</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-card>
<a-card :bordered="false" :body-style="{ padding: '0px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-space :size="8" align="center">
<!-- <a-button type="primary" @click.prevent="fnModalVisibleByEdit()">
<template #icon><FieldTimeOutlined /></template>
{{ t('views.configManage.backupManage.setBackupTask') }}
</a-button> -->
</a-space>
</template>
<!-- 插槽-卡片右侧 -->
<template #extra>
<a-space :size="8" align="center">
<a-tooltip>
<template #title>{{ t('common.searchBarText') }}</template>
<a-switch
v-model:checked="tableState.seached"
:checked-children="t('common.switch.show')"
:un-checked-children="t('common.switch.hide')"
size="small"
/>
</a-tooltip>
<a-tooltip>
<template #title>{{ t('common.reloadText') }}</template>
<a-button type="text" @click.prevent="fnGetList(1)">
<template #icon><ReloadOutlined /></template>
</a-button>
</a-tooltip>
<a-tooltip>
<template #title>{{ t('common.sizeText') }}</template>
<a-dropdown trigger="click">
<a-button type="text">
<template #icon><ColumnHeightOutlined /></template>
</a-button>
<template #overlay>
<a-menu
:selected-keys="[tableState.size as string]"
@click="fnTableSize"
>
<a-menu-item key="default">
{{ t('common.size.default') }}
</a-menu-item>
<a-menu-item key="middle">
{{ t('common.size.middle') }}
</a-menu-item>
<a-menu-item key="small">
{{ t('common.size.small') }}
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-tooltip>
</a-space>
</template>
<!-- 表格列表 -->
<a-table
class="table"
row-key="id"
:columns="tableColumns"
:loading="tableState.loading"
:data-source="tableState.data"
:size="tableState.size"
:pagination="tablePagination"
:scroll="{ x: 1200, y: 400 }"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'id'">
<a-space :size="8" align="center">
<a-tooltip>
<template #title>{{ t('common.downloadText') }}</template>
<a-button type="link" @click.prevent="fnDownloadFile(record)">
<template #icon><DownloadOutlined /></template>
</a-button>
</a-tooltip>
<a-tooltip>
<template #title>{{ t('common.deleteText') }}</template>
<a-button type="link" @click.prevent="fnRecordDelete(record)">
<template #icon><DeleteOutlined /></template>
</a-button>
</a-tooltip>
<a-tooltip>
<template #title>{{ t('common.editText') }}</template>
<a-button
type="link"
@click.prevent="fnModalVisibleByEdit(record)"
>
<template #icon><FormOutlined /></template>
</a-button>
</a-tooltip>
</a-space>
</template>
</template>
</a-table>
</a-card>
<!-- 新增框或修改框 -->
<ProModal
:drag="true"
:width="800"
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@cancel="fnModalCancel"
>
<a-form name="modalStateFrom" layout="horizontal">
<a-form-item
:label="t('views.configManage.backupManage.remark')"
name="backupInfo"
v-bind="modalStateFrom.validateInfos.backupInfo"
>
<a-textarea
v-model:value="modalState.from.backupInfo"
:auto-size="{ minRows: 2, maxRows: 6 }"
:maxlength="250"
:show-count="true"
/>
</a-form-item>
</a-form>
</ProModal>
</PageContainer>
</template>
<style lang="less" scoped>
.table :deep(.ant-pagination) {
padding: 0 24px;
}
</style>
+33 -34
View File
@@ -1,11 +1,10 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, ref } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { message, Modal, Form } 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 { message, Modal, Form } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import {
listNeInfo,
getNeInfo,
@@ -21,8 +20,8 @@ import {
} from '@/api/configManage/neManage';
import { updateNeConfigReload } from '@/api/configManage/configParam';
import useI18n from '@/hooks/useI18n';
import { FileType } from 'ant-design-vue/es/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { FileType } from 'ant-design-vue/lib/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { NE_TYPE_LIST } from '@/constants/ne-constants';
@@ -195,11 +194,11 @@ function fnTableSize({ key }: MenuInfo) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**详情框是否显示 */
openByView: boolean;
visibleByView: boolean;
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**导入是否显示 */
openByImport: boolean;
visibleByImport: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -212,9 +211,9 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByView: false,
openByEdit: false,
openByImport: false,
visibleByView: false,
visibleByEdit: false,
visibleByImport: false,
title: '网元',
from: {
id: undefined,
@@ -327,7 +326,7 @@ function fnModalVisibleByEdit(row?: Record<string, any>) {
if (!row) {
modalStateFrom.resetFields();
modalState.title = t('views.configManage.neManage.addNe');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
if (modalState.confirmLoading) return;
const hide = message.loading(t('common.loading'), 0);
@@ -338,7 +337,7 @@ function fnModalVisibleByEdit(row?: Record<string, any>) {
if (res.code === RESULT_CODE_SUCCESS) {
modalState.from = Object.assign(modalState.from, res.data);
modalState.title = t('views.configManage.neManage.editNe');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
message.error(t('views.configManage.neManage.getInfo'), 2);
}
@@ -371,7 +370,7 @@ function fnModalOk() {
content: t('common.msgSuccess', { msg: modalState.title }),
duration: 3,
});
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
fnGetList(1);
}
@@ -419,7 +418,7 @@ function fnImportModalOk() {
content: t('common.msgSuccess', { msg: modalState.title }),
duration: 3,
});
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
} else {
message.error({
@@ -445,8 +444,8 @@ function fnImportModalOk() {
* 进行表达规则校验
*/
function fnImportModalCancel() {
modalState.openByView = false;
modalState.openByImport = false;
modalState.visibleByView = false;
modalState.visibleByImport = false;
importStateFrom.resetFields();
}
@@ -455,8 +454,8 @@ function fnImportModalCancel() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.openByView = false;
modalState.visibleByEdit = false;
modalState.visibleByView = false;
modalStateFrom.resetFields();
}
@@ -708,7 +707,7 @@ function fnRecordMore(type: string | number, row: Record<string, any>) {
if (type === 'import') {
modalState.importFrom = Object.assign(modalState.importFrom, row);
modalState.title = t('views.configManage.neManage.import');
modalState.openByImport = true;
modalState.visibleByImport = true;
}
}
@@ -979,7 +978,7 @@ onMounted(() => {
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -991,7 +990,7 @@ onMounted(() => {
:label-col="{ span: 6 }"
:labelWrap="true"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.neType')"
@@ -1008,7 +1007,7 @@ onMounted(() => {
<template #title>{{
t('views.configManage.neManage.neTypeTip')
}}</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit;" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -1029,7 +1028,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.uid')"
@@ -1069,7 +1068,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.ip')"
@@ -1091,7 +1090,7 @@ onMounted(() => {
<template #title>
<div>{{ t('views.configManage.neManage.portTip') }}</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit;" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -1099,7 +1098,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.neName')"
@@ -1121,14 +1120,14 @@ onMounted(() => {
<template #title>
<div>{{ t('views.configManage.neManage.macTip') }}</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit;" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip> </template
></a-input>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.vendorName')"
@@ -1145,7 +1144,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.province')"
@@ -1180,14 +1179,14 @@ onMounted(() => {
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByImport"
:visible="modalState.visibleByImport"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnImportModalOk"
@cancel="fnImportModalCancel"
>
<a-form name="importStateFrom" layout="horizontal">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.configManage.neManage.neType')"
+19 -23
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { PageContainer } from 'antdv-pro-layout';
import { ColumnsType } from 'ant-design-vue/es/table';
import { message } from 'ant-design-vue/es';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { message } from 'ant-design-vue/lib';
import { reactive, ref, onMounted, onBeforeUnmount, markRaw } from 'vue';
import useI18n from '@/hooks/useI18n';
import { TooltipComponent } from 'echarts/components';
@@ -108,6 +108,10 @@ let tableColumns: ColumnsType = [
type TabeStateType = {
/**加载等待 */
loading: boolean;
/**紧凑型 */
size: string;
/**搜索栏 */
seached: boolean;
/**记录数据 */
data: object[];
/**勾选记录 */
@@ -117,6 +121,8 @@ type TabeStateType = {
/**表格状态 */
let tableState: TabeStateType = reactive({
loading: false,
size: 'middle',
seached: false,
data: [],
selectedRowKeys: [],
});
@@ -174,13 +180,15 @@ function fnGetList(one: boolean) {
tableState.loading = false;
var rightNum = 0;
var errorNum = 0;
res.data.forEach((item: any) => {
if (item.serverState.online) {
// if (res.length) nfInfo.serialNum = res[0].serialNum;
for (let i = 0; i < res.length; i++) {
if (res[i].status == '正常' || res[i].status == 'Normal') {
rightNum++;
} else {
errorNum++;
}
});
}
const optionData: any = {
title: {
text: '',
@@ -241,9 +249,9 @@ function fnDesign(container: HTMLElement | undefined, option: any) {
}
/**抽屉 网元详细信息 */
const open = ref(false);
const visible = ref(false);
const closeDrawer = () => {
open.value = false;
visible.value = false;
};
/**抽屉 网元详细信息 */
@@ -295,7 +303,7 @@ function rowClick(record: any, index: any) {
expiryDate: pronData.expire,
};
}
open.value = true;
visible.value = true;
},
};
}
@@ -336,7 +344,7 @@ onBeforeUnmount(() => {
<template>
<PageContainer :breadcrumb="{}">
<div>
<a-drawer :open="open" @close="closeDrawer" :width="700">
<a-drawer :visible="visible" @close="closeDrawer" :width="700">
<a-descriptions bordered :column="1" :label-style="{ width: '160px' }">
<a-descriptions-item :label="t('views.index.hostName')">{{
pronInfo.hostName
@@ -350,9 +358,6 @@ onBeforeUnmount(() => {
<a-descriptions-item :label="t('views.index.version')">{{
pronInfo.version
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.capability')">{{
pronInfo.capability
}}</a-descriptions-item>
<a-descriptions-item :label="t('views.index.cpuUse')">{{
pronInfo.cpuUse
}}</a-descriptions-item>
@@ -375,7 +380,6 @@ onBeforeUnmount(() => {
<a-table
class="table"
row-key="id"
size="small"
:columns="tableColumns"
:loading="tableState.loading"
:data-source="tableState.data"
@@ -396,18 +400,10 @@ onBeforeUnmount(() => {
</a-table>
</a-col>
<a-col :lg="10" :md="8" :xs="24">
<a-card
:title="t('views.index.runStatus')"
style="margin-bottom: 16px"
size="small"
>
<a-card :title="t('views.index.runStatus')" style="margin-bottom: 16px">
<div style="width: 100%; min-height: 200px" ref="statusBar"></div>
</a-card>
<a-card
:title="t('views.index.mark')"
style="margin-top: 16px"
size="small"
>
<a-card :title="t('views.index.mark')" style="margin-top: 16px">
<a-descriptions
bordered
:column="1"
@@ -0,0 +1,280 @@
<script setup lang="ts">
import { reactive, toRaw, watch, ref } from 'vue';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { listNeVersion } from '@/api/configManage/softwareManage';
import { parseDateToStr } from '@/utils/date-utils';
import useNeInfoStore from '@/store/modules/neinfo';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
title: {
type: String,
default: '标题',
},
visible: {
type: Boolean,
default: false,
},
});
/**开始结束时间 */
let queryRangePicker = ref<[string, string]>(['', '']);
/**查询参数 */
let queryParams = reactive({
/**网元类型 */
neType: '',
/**记录开始时间 */
beginTime: '',
/**记录结束时间 */
endTime: '',
/**状态 */
status: undefined,
/**当前页数 */
pageNum: 1,
/**每页条数 */
pageSize: 20,
});
/**查询参数重置 */
function fnQueryReset() {
queryRangePicker.value = ['', ''];
queryParams = Object.assign(queryParams, {
neType: '',
status: undefined,
beginTime: '',
endTime: '',
pageNum: 1,
pageSize: 20,
});
tablePagination.current = 1;
tablePagination.pageSize = 20;
fnGetList();
}
/**表格状态类型 */
type TabeStateType = {
/**加载等待 */
loading: boolean;
/**紧凑型 */
size: SizeType;
/**记录数据 */
data: object[];
/**勾选记录 */
selectedRowKeys: (string | number)[];
};
/**表格状态 */
let tableState: TabeStateType = reactive({
loading: false,
size: 'small',
data: [],
selectedRowKeys: [],
});
/**表格字段列 */
let tableColumns: ColumnsType = [
{
title: t('views.configManage.softwareManage.neType'),
dataIndex: 'neType',
align: 'center',
width: 100,
},
{
title: t('views.configManage.neManage.neId'),
dataIndex: 'neId',
align: 'center',
width: 200,
},
{
title: t('views.configManage.softwareManage.versions'),
dataIndex: 'version',
align: 'center',
},
{
title: t('views.configManage.softwareManage.upVersions'),
dataIndex: 'preVersion',
align: 'center',
},
{
title: t('views.configManage.softwareManage.backVersions'),
dataIndex: 'newVersion',
align: 'center',
},
{
title: t('views.configManage.softwareManage.status'),
dataIndex: 'status',
key: 'status',
align: 'center',
width: 100,
},
{
title: t('views.configManage.softwareManage.letUpTime'),
dataIndex: 'updateTime',
align: 'center',
customRender(opt) {
if (!opt.value) return '';
return parseDateToStr(opt.value);
},
width: 200,
},
];
/**表格分页器参数 */
let tablePagination = reactive({
/**当前页数 */
current: 1,
/**每页条数 */
pageSize: 20,
/**默认的每页条数 */
defaultPageSize: 20,
/**指定每页可以显示多少条 */
pageSizeOptions: ['10', '20', '50', '100'],
/**只有一页时是否隐藏分页器 */
hideOnSinglePage: false,
/**是否可以快速跳转至某页 */
showQuickJumper: true,
/**是否可以改变 pageSize */
showSizeChanger: true,
/**数据总数 */
total: 0,
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
onChange: (page: number, pageSize: number) => {
tablePagination.current = page;
tablePagination.pageSize = pageSize;
queryParams.pageNum = page;
queryParams.pageSize = pageSize;
fnGetList();
},
});
/**查询角色未授权用户列表, pageNum初始页数 */
function fnGetList(pageNum?: number) {
if (tableState.loading) return;
tableState.loading = true;
if (pageNum) {
queryParams.pageNum = pageNum;
}
if (!queryRangePicker.value) {
queryRangePicker.value = ['', ''];
}
queryParams.beginTime = queryRangePicker.value[0];
queryParams.endTime = queryRangePicker.value[1];
listNeVersion(toRaw(queryParams)).then(res => {
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
tablePagination.total = res.total;
tableState.data = res.rows;
if (
tablePagination.total <=
(queryParams.pageNum - 1) * tablePagination.pageSize &&
queryParams.pageNum !== 1
) {
tableState.loading = false;
fnGetList(queryParams.pageNum - 1);
}
}
tableState.loading = false;
});
}
/**弹框取消按钮事件 */
function fnModalCancel() {
emit('cancel');
}
/**显示弹框时初始数据 */
function init() {
// 查询参数重置
fnQueryReset();
}
/**监听是否显示,初始数据 */
watch(
() => props.visible,
val => {
if (val) init();
}
);
</script>
<template>
<ProModal
:drag="true"
:forceFullscreen="true"
:destroyOnClose="true"
:title="props.title"
:visible="props.visible"
:keyboard="false"
:mask-closable="false"
@cancel="fnModalCancel"
:footer="false"
>
<!-- 表格搜索栏 -->
<a-form :model="queryParams" name="queryParams" layout="horizontal">
<a-row :gutter="16">
<a-col :lg="6" :md="6" :xs="24">
<a-form-item
:label="t('views.configManage.softwareManage.neType')"
name="neType"
>
<a-auto-complete
v-model:value="queryParams.neType"
:options="useNeInfoStore().getNeSelectOtions"
allow-clear
:placeholder="t('views.configManage.softwareManage.neTypePlease')"
/>
</a-form-item>
</a-col>
<a-col :lg="6" :md="6" :xs="24">
<a-form-item
:label="t('views.configManage.softwareManage.createTime')"
name="queryRangePicker"
>
<a-range-picker
v-model:value="queryRangePicker"
allow-clear
bordered
value-format="YYYY-MM-DD"
style="width: 100%"
></a-range-picker>
</a-form-item>
</a-col>
<a-col :lg="6" :md="6" :xs="24">
<a-form-item>
<a-space :size="8">
<a-button type="primary" @click.prevent="fnGetList(1)">
<template #icon><SearchOutlined /></template>
{{ t('common.search') }}
</a-button>
<a-button type="default" @click.prevent="fnQueryReset">
<template #icon><ClearOutlined /></template>
{{ t('common.reset') }}
</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
<a-table
class="table"
row-key="id"
:columns="tableColumns"
:loading="tableState.loading"
:data-source="tableState.data"
:size="tableState.size"
:scroll="{ x: true }"
:pagination="tablePagination"
>
</a-table>
</ProModal>
</template>
<style lang="less" scoped>
.table :deep(.ant-pagination) {
padding: 0 24px;
}
</style>
File diff suppressed because it is too large. Load diff
+4 -4
View File
@@ -1,10 +1,10 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, ref, onBeforeUnmount } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { message, Modal } 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 { message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import useI18n from '@/hooks/useI18n';
import {
RESULT_CODE_ERROR,
+10 -26
View File
@@ -1,10 +1,10 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, ref, onBeforeUnmount } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { message, Modal } 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 { message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import useI18n from '@/hooks/useI18n';
import {
RESULT_CODE_ERROR,
@@ -571,7 +571,9 @@ onBeforeUnmount(() => {
<a-select
v-model:value="recordTypes"
mode="multiple"
:options="['MOC', 'MTC'].map(v => ({ value: v }))"
:options="
['MOC', 'MTC', 'MOSM', 'MTSM'].map(v => ({ value: v }))
"
:placeholder="t('common.selectPlease')"
@change="fnQueryRecordTypeChange"
></a-select>
@@ -754,13 +756,7 @@ onBeforeUnmount(() => {
</div>
<div>
<span>{{ t('views.dashboard.cdr.time') }}: </span>
<span>
{{
typeof record.cdrJSON.releaseTime === 'number'
? parseDateToStr(+record.cdrJSON.releaseTime * 1000)
: record.cdrJSON.releaseTime
}}
</span>
<span>{{ parseDateToStr(+record.timestamp * 1000) }}</span>
</div>
</a-col>
<a-col :lg="6" :md="12" :xs="24">
@@ -804,23 +800,11 @@ onBeforeUnmount(() => {
</div>
<div>
<span>{{ t('views.dashboard.cdr.seizureTime') }}: </span>
<span>
{{
typeof record.cdrJSON.seizureTime === 'number'
? parseDateToStr(+record.cdrJSON.seizureTime * 1000)
: record.cdrJSON.seizureTime
}}
</span>
<span>{{ record.cdrJSON.seizureTime }}</span>
</div>
<div>
<span>{{ t('views.dashboard.cdr.releaseTime') }}: </span>
<span>
{{
typeof record.cdrJSON.releaseTime === 'number'
? parseDateToStr(+record.cdrJSON.releaseTime * 1000)
: record.cdrJSON.releaseTime
}}
</span>
<span>{{ record.cdrJSON.releaseTime }}</span>
</div>
</a-col>
</a-row>
+16 -12
View File
@@ -1,10 +1,10 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, ref, onBeforeUnmount } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { message, Modal } 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 { message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import useI18n from '@/hooks/useI18n';
import {
RESULT_CODE_ERROR,
@@ -25,6 +25,9 @@ const queue = new PQueue({ concurrency: 1, autoStart: true });
/**网元可选 */
let neOtions = ref<Record<string, any>[]>([]);
/**event Type */
let mmeEventType = ref<DictType[]>([]);
/**字典数据 */
let dict: {
/**UE 事件认证代码类型 */
@@ -415,12 +418,13 @@ onMounted(() => {
dict.ueAauthCode = resArr[0].value;
}
if (resArr[1].status === 'fulfilled') {
const ueEventType: any[] = JSON.parse(JSON.stringify(resArr[1]));
dict.ueEventType = ueEventType.map(item => {
if (item.value === 'cm-state') {
item.label = item.label.replace('CM', 'ECM');
resArr[1].value.map(item => {
const realJson = JSON.parse(JSON.stringify(item));
if (realJson.value === 'cm-state') {
realJson.label = realJson.label.replace('CM', 'ECM');
}
return item;
mmeEventType.value.push(realJson);
});
}
if (resArr[2].status === 'fulfilled') {
@@ -492,7 +496,7 @@ onBeforeUnmount(() => {
<a-select
v-model:value="eventTypes"
mode="multiple"
:options="dict.ueEventType"
:options="mmeEventType"
:placeholder="t('common.selectPlease')"
@change="fnQueryEventTypeChange"
></a-select>
@@ -649,7 +653,7 @@ onBeforeUnmount(() => {
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'eventType'">
<DictTag :options="dict.ueEventType" :value="record.eventType" />
<DictTag :options="mmeEventType" :value="record.eventType" />
</template>
<template v-if="column.key === 'result'">
<span v-if="record.eventType === 'auth-result'">
@@ -706,7 +710,7 @@ onBeforeUnmount(() => {
</div>
<div>
<span>{{ t('views.dashboard.ue.eventType') }}: </span>
<DictTag :options="dict.ueEventType" :value="record.eventType" />
<DictTag :options="mmeEventType" :value="record.eventType" />
</div>
<div>
<span>{{ t('views.dashboard.ue.result') }}: </span>
@@ -1,14 +1,13 @@
<script setup lang="ts">
import { reactive, toRaw, watch } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import { dbGetJSON, dbSetJSON } from '@/utils/cache-db-utils';
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
title: {
type: String,
default: '标题',
},
open: {
visible: {
type: Boolean,
default: false,
},
@@ -28,13 +27,13 @@ let dataState = reactive({
function fnModalOk() {
dbSetJSON('tbl_mocn', `tmp`, toRaw(dataState));
emit('ok');
emit('update:open', false);
emit('update:visible', false);
}
/**弹框取消按钮事件 */
function fnModalCancel() {
emit('cancel');
emit('update:open', false);
emit('update:visible', false);
}
/**显示弹框时初始数据 */
@@ -49,7 +48,7 @@ function init() {
/**监听是否显示,初始数据 */
watch(
() => props.open,
() => props.visible,
val => {
if (val) init();
}
@@ -61,7 +60,7 @@ watch(
:drag="true"
:width="800"
:title="props.title"
:open="props.open"
:visible="props.visible"
:keyboard="false"
:mask-closable="false"
@cancel="fnModalCancel"
+5 -5
View File
@@ -8,7 +8,7 @@ import Topology from '../overview/components/Topology/index.vue';
import NeResources from '../overview/components/NeResources/index.vue';
import UserActivity from '../overview/components/UserActivity/index.vue';
import AlarnTypeBar from './components/AlarnTypeBar/index.vue';
import Setting from './components/setting.vue';
import setting from './components/setting.vue';
import UPFFlow from '../overview/components/UPFFlow/index.vue';
import { listUDMSub } from '@/api/neData/udm_sub';
import { listUENumBySMF } from '@/api/neUser/smf';
@@ -208,7 +208,7 @@ onBeforeUnmount(() => {
/**MOCN状态 */
const mocnState = reactive({
title: 'Set MOCN Data',
open: false,
visible: false,
data: {
/**基站数 */
baseNum: 0,
@@ -220,7 +220,7 @@ const mocnState = reactive({
});
/**MOCN 右击设置 */
function fnRightClick() {
mocnState.open = true;
mocnState.visible = true;
}
</script>
@@ -543,9 +543,9 @@ function fnRightClick() {
</div>
</div>
</div>
<Setting
<setting
:title="mocnState.title"
v-model:open="mocnState.open"
v-model:visible="mocnState.visible"
></setting>
</div>
</template>
@@ -2,10 +2,9 @@
import { onMounted, ref } from 'vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listAllNeInfo } from '@/api/ne/neInfo';
import { message } from 'ant-design-vue/es';
import { message } from 'ant-design-vue/lib';
import { getGraphData } from '@/api/monitor/topology';
import { Graph, GraphData, Tooltip } from '@antv/g6';
import { parseBasePath } from '@/plugins/file-static-url';
import { edgeLineAnimateState } from '@/views/monitor/topologyBuild/hooks/registerEdge';
import { nodeImageAnimateState } from '@/views/monitor/topologyBuild/hooks/registerNode';
import {
@@ -187,12 +186,6 @@ function fnGraphDataLoad(reload: boolean = false) {
const nf: Record<string, any>[] = nodes.filter(
(node: Record<string, any>) => {
Reflect.set(node, 'neState', { online: false });
// 图片路径处理
if (node.img) node.img = parseBasePath(node.img);
if (node.icon.show && node.icon?.img) {
node.icon.img = parseBasePath(node.icon.img);
}
// 遍历是否有网元数据
const nodeID: string = node.id;
const hasNe = res.neList.some(ne => {
Reflect.set(node, 'neInfo', ne.neType === nodeID ? ne : {});
+3 -3
View File
@@ -136,7 +136,7 @@ export default function useWS() {
sortField: 'timestamp',
sortOrder: 'desc',
pageNum: 1,
pageSize: 20,
pageSize: 5,
},
});
// MME_UE会话事件
@@ -149,7 +149,7 @@ export default function useWS() {
sortField: 'timestamp',
sortOrder: 'desc',
pageNum: 1,
pageSize: 20,
pageSize: 5,
},
});
// IMS_CDR会话事件
@@ -163,7 +163,7 @@ export default function useWS() {
sortField: 'timestamp',
sortOrder: 'desc',
pageNum: 1,
pageSize: 20,
pageSize: 5,
},
});
}
-2
View File
@@ -162,7 +162,6 @@ function loadData() {
clearInterval(interval10s.value);
interval10s.value = setInterval(() => {
if (!interval10s.value) return
if (upfTFActive.value === '0') {
upfTFSend('7');
upfTFActive.value = '7';
@@ -177,7 +176,6 @@ function loadData() {
clearInterval(interval5s.value);
interval5s.value = setInterval(() => {
if (!interval5s.value) return
fnGetSkim(); // 获取概览信息
fnGetNeState(); // 获取网元状态
}, 5_000);
+10 -11
View File
@@ -1,10 +1,10 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, onBeforeUnmount, ref } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { Modal, 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 { Modal, message } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import useNeInfoStore from '@/store/modules/neinfo';
import useI18n from '@/hooks/useI18n';
import {
@@ -16,6 +16,7 @@ import {
exportSMFDataCDR,
listSMFDataCDR,
} from '@/api/neData/smf';
import { parseDateToStr } from '@/utils/date-utils';
import { OptionsType, WS } from '@/plugins/ws-websocket';
import PQueue from 'p-queue';
import saveAs from 'file-saver';
@@ -699,7 +700,7 @@ onBeforeUnmount(() => {
</div>
<div>
<span>{{ t('views.dashboard.cdr.time') }}: </span>
<span>{{ record.cdrJSON.invocationTimestamp }}</span>
<span>{{ parseDateToStr(+record.timestamp * 1000) }}</span>
</div>
<a-divider orientation="left">
{{ t('views.dashboard.cdr.rowInfo') }}
@@ -814,12 +815,10 @@ onBeforeUnmount(() => {
</div>
<div>
<span>Network Function IPv4: </span>
<span>
{{
record.cdrJSON.nFunctionConsumerInformation
?.networkFunctionIPv4Address
}}
</span>
<span>{{
record.cdrJSON.nFunctionConsumerInformation
.networkFunctionIPv4Address
}}</span>
</div>
</a-col>
</a-row>
+6 -15
View File
@@ -1,10 +1,10 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, ref, onBeforeUnmount } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { message, Modal } 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 { message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import useDictStore from '@/store/modules/dict';
import useI18n from '@/hooks/useI18n';
import {
@@ -176,10 +176,7 @@ let tableColumns: ColumnsType = [
width: 150,
customRender(opt) {
const cdrJSON = opt.value;
if (typeof cdrJSON.updateTime === 'number') {
return parseDateToStr(+cdrJSON.updateTime * 1000);
}
return cdrJSON.updateTime;
return parseDateToStr(+cdrJSON.updateTime * 1000);
},
},
{
@@ -718,13 +715,7 @@ onBeforeUnmount(() => {
</div>
<div>
<span>{{ t('views.dashboard.cdr.time') }}: </span>
<span>
{{
typeof record.cdrJSON.updateTime === 'number'
? parseDateToStr(+record.cdrJSON.updateTime * 1000)
: record.cdrJSON.updateTime
}}
</span>
<span>{{ parseDateToStr(+record.timestamp * 1000) }}</span>
</div>
<a-divider orientation="left">
{{ t('views.dashboard.cdr.rowInfo') }}
+50 -54
View File
@@ -1,11 +1,10 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { message, Modal } 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 { message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import {
listAct,
updateConfirm,
@@ -329,15 +328,15 @@ function fnTableSize({ key }: MenuInfo) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**详情框是否显示 */
openByView: boolean;
visibleByView: boolean;
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**显示过滤设置是否显示 */
openByShowSet: boolean;
visibleByShowSet: boolean;
/**告警帮助文档是否显示 */
helpShowView: boolean;
/**个性化设置置是否显示 */
openByMyselfSet: boolean;
visibleByMyselfSet: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -350,11 +349,11 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByView: false,
openByEdit: false,
openByShowSet: false,
visibleByView: false,
visibleByEdit: false,
visibleByShowSet: false,
helpShowView: false,
openByMyselfSet: false,
visibleByMyselfSet: false,
title: '全部信息',
from: {
alarmId: '',
@@ -406,7 +405,7 @@ function fnModalVisibleByVive(row: Record<string, any>) {
modalState.title = t('views.faultManage.activeAlarm.viewIdInfo', {
alarmId: row.alarmId,
});
modalState.openByView = true;
modalState.visibleByView = true;
}
/** 告警帮助文档详细信息 */
@@ -435,7 +434,7 @@ function fnModalOk() {
duration: 3,
});
modalState.confirmLoading = false;
modalState.openByView = false;
modalState.visibleByView = false;
return false;
}
const result = updateConfirm(from);
@@ -447,7 +446,7 @@ function fnModalOk() {
content: t('common.msgSuccess', { msg: modalState.title }),
duration: 3,
});
modalState.openByView = false;
modalState.visibleByView = false;
fnGetList();
} else {
message.error({
@@ -477,7 +476,7 @@ function fnShowModalOk() {
content: t('common.msgSuccess', { msg: modalState.title }),
duration: 3,
});
modalState.openByShowSet = false;
modalState.visibleByShowSet = false;
fnGetList();
} else {
message.error({
@@ -605,7 +604,7 @@ function fnShowSet() {
: {};
modalState.showSetFrom = Object.assign(modalState.showSetFrom, realJson);
modalState.title = t('views.faultManage.activeAlarm.showSet');
modalState.openByShowSet = true;
modalState.visibleByShowSet = true;
} else {
message.error(t('common.getInfoFail'), 2);
}
@@ -618,14 +617,11 @@ function mapKeysWithReduce(data: any[], titleMapping: Record<string, string>) {
if (typeof item !== 'object' || item === null) {
return item; // 如果不是对象,直接返回原值
}
return Object.keys(item).reduce(
(newItem: Record<string, any>, key: string) => {
const title = titleMapping[key] || key;
newItem[title] = item[key];
return newItem;
},
{}
); // 确保初始值是一个空对象
return Object.keys(item).reduce((newItem: Record<string, any>, key: string) => {
const title = titleMapping[key] || key;
newItem[title] = item[key];
return newItem;
}, {}); // 确保初始值是一个空对象
});
}
@@ -708,9 +704,9 @@ function fnExportAll() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.openByView = false;
modalState.openByShowSet = false;
modalState.visibleByEdit = false;
modalState.visibleByView = false;
modalState.visibleByShowSet = false;
modalState.helpShowView = false;
}
@@ -841,7 +837,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="6" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmCode')"
@@ -881,7 +877,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="6" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.pvFlag')"
@@ -916,7 +912,7 @@ onMounted(() => {
<a-card :bordered="false" :body-style="{ padding: '0px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-space :size="8" align="center">
<div class="button-container">
<a-button
type="primary"
@click.prevent="fnCancelConfirm()"
@@ -960,12 +956,12 @@ onMounted(() => {
<template #icon> <export-outlined /> </template>
{{ t('views.faultManage.activeAlarm.exportAll') }}
</a-button>
</a-space>
</div>
</template>
<!-- 插槽-卡片右侧 -->
<template #extra>
<a-space :size="8" align="center">
<div class="button-container">
<a-tooltip>
<template #title>{{ t('common.searchBarText') }}</template>
<a-switch
@@ -1010,7 +1006,7 @@ onMounted(() => {
:columns="tableColumns"
v-model:columns-dnd="tableColumnsDnd"
></TableColumnsDnd>
</a-space>
</div>
</template>
<!-- 表格列表 -->
@@ -1088,7 +1084,7 @@ onMounted(() => {
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.helpShowView"
:visible="modalState.helpShowView"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
:body-style="{ padding: '0px' }"
@@ -1115,7 +1111,7 @@ onMounted(() => {
:body-style="{ height: '520px', overflowY: 'scroll' }"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByView"
:visible="modalState.visibleByView"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -1128,7 +1124,7 @@ onMounted(() => {
:label-col="{ span: 8 }"
:label-wrap="true"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmId')"
@@ -1147,7 +1143,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.neId')"
@@ -1166,7 +1162,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.neType')"
@@ -1185,7 +1181,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmTitle')"
@@ -1204,7 +1200,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmType')"
@@ -1231,9 +1227,9 @@ onMounted(() => {
{{ modalState.from.locationInfo }}
</a-form-item>
<a-row> </a-row>
<a-row :gutter="16"> </a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.province')"
@@ -1276,7 +1272,7 @@ onMounted(() => {
{{ modalState.from.specificProblem }}
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.ackUser')"
@@ -1295,7 +1291,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.ackTime')"
@@ -1322,7 +1318,7 @@ onMounted(() => {
:width="800"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByShowSet"
:visible="modalState.visibleByShowSet"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnShowModalOk"
@@ -1330,7 +1326,7 @@ onMounted(() => {
@cancel="fnModalCancel"
>
<a-form name="modalStateShowFrom" layout="horizontal">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.neType')"
@@ -1355,7 +1351,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.pvFlag')"
@@ -1386,7 +1382,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.origLevel')"
@@ -1422,7 +1418,7 @@ onMounted(() => {
:width="800"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByMyselfSet"
:visible="modalState.visibleByMyselfSet"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnShowModalOk"
@@ -1430,7 +1426,7 @@ onMounted(() => {
@cancel="fnModalCancel"
>
<a-form name="modalStateShowFrom" layout="horizontal">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.neType')"
@@ -1454,7 +1450,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.pvFlag')"
@@ -1485,7 +1481,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.origLevel')"
+34 -33
View File
@@ -1,11 +1,10 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { message, Modal } 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 { message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { listAct, exportAll } from '@/api/faultManage/eventAlarm';
import useI18n from '@/hooks/useI18n';
import useDictStore from '@/store/modules/dict';
@@ -212,13 +211,13 @@ function fnTableSize({ key }: MenuInfo) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**详情框是否显示 */
openByView: boolean;
visibleByView: boolean;
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**显示过滤设置是否显示 */
openByShowSet: boolean;
visibleByShowSet: boolean;
/**个性化设置置是否显示 */
openByMyselfSet: boolean;
visibleByMyselfSet: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -231,10 +230,10 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByView: false,
openByEdit: false,
openByShowSet: false,
openByMyselfSet: false,
visibleByView: false,
visibleByEdit: false,
visibleByShowSet: false,
visibleByMyselfSet: false,
title: '全部信息',
from: {
alarmId: '',
@@ -286,7 +285,7 @@ function fnModalVisibleByVive(row: Record<string, any>) {
modalState.title = t('views.faultManage.activeAlarm.viewIdInfo', {
alarmId: row.alarmId,
});
modalState.openByView = true;
modalState.visibleByView = true;
}
/**表格状态 */
@@ -311,8 +310,8 @@ const onSelectChange = (
// key替换中文title
function mapKeysWithReduce(data: any, titleMapping: any) {
return data.map((item: any) => {
return Object.keys(item).reduce((newItem: any, key: any) => {
return data.map((item:any) => {
return Object.keys(item).reduce((newItem:any, key:any) => {
const title = titleMapping[key] || key;
newItem[title] = item[key];
return newItem;
@@ -361,7 +360,7 @@ function fnExportAll() {
writeSheet(res.data, 'alarm', sortData).then(fileBlob => {
saveAs(fileBlob, `evnet_${Date.now()}.xlsx`);
message.success({
content: t('common.msgSuccess', { msg: t('common.export') }),
key,
@@ -385,8 +384,8 @@ function fnExportAll() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.openByView = false;
modalState.visibleByEdit = false;
modalState.visibleByView = false;
}
/**查询列表, pageNum初始页数 */
@@ -509,7 +508,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="6" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmCode')"
@@ -551,7 +550,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="6" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmType')"
@@ -571,7 +570,7 @@ onMounted(() => {
<a-card :bordered="false" :body-style="{ padding: '0px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-space :size="8" align="center">
<div class="button-container">
<a-button
type="primary"
@click.prevent="fnExportAll()"
@@ -580,12 +579,12 @@ onMounted(() => {
<template #icon> <export-outlined /> </template>
{{ t('views.faultManage.activeAlarm.exportAll') }}
</a-button>
</a-space>
</div>
</template>
<!-- 插槽-卡片右侧 -->
<template #extra>
<a-space :size="8" align="center">
<div class="button-container">
<a-tooltip>
<template #title>{{ t('common.searchBarText') }}</template>
<a-switch
@@ -630,7 +629,7 @@ onMounted(() => {
:columns="tableColumns"
v-model:columns-dnd="tableColumnsDnd"
></TableColumnsDnd>
</a-space>
</div>
</template>
<!-- 表格列表 -->
@@ -642,7 +641,7 @@ onMounted(() => {
:data-source="tableState.data"
:size="tableState.size"
:pagination="tablePagination"
:scroll="{ x: tableColumns.length * 120, y: 400 }"
:scroll="{ x: 2500, y: 400 }"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'origSeverity'">
@@ -690,7 +689,7 @@ onMounted(() => {
:body-style="{ height: '520px', overflowY: 'scroll' }"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByView"
:visible="modalState.visibleByView"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@cancel="fnModalCancel"
@@ -707,7 +706,7 @@ onMounted(() => {
:label-col="{ span: 8 }"
:label-wrap="true"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmId')"
@@ -726,7 +725,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.neId')"
@@ -745,7 +744,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.neType')"
@@ -764,7 +763,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmTitle')"
@@ -791,7 +790,9 @@ onMounted(() => {
{{ modalState.from.locationInfo }}
</a-form-item>
<a-row>
<a-row :gutter="16"> </a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.province')"
@@ -818,7 +819,7 @@ onMounted(() => {
{{ modalState.from.addInfo }}
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.specificProblemId')"
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { Form, message } from 'ant-design-vue/es';
import { Form, message } from 'ant-design-vue/lib';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import {
getForwardSet,
@@ -177,7 +177,7 @@ onMounted(() => {
<template>
<PageContainer>
<a-row>
<a-row :gutter="16">
<a-col :span="8" v-if="false">
<!-- 日志设置 -->
<a-card :title="alarmState.title" :loading="alarmState.fromLoading">
+37 -41
View File
@@ -1,11 +1,10 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { message, Modal } 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 { message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import {
listAct,
updateConfirm,
@@ -263,13 +262,13 @@ function fnTableSize({ key }: MenuInfo) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**详情框是否显示 */
openByView: boolean;
visibleByView: boolean;
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**显示过滤设置是否显示 */
openByShowSet: boolean;
visibleByShowSet: boolean;
/**个性化设置置是否显示 */
openByMyselfSet: boolean;
visibleByMyselfSet: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -282,10 +281,10 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByView: false,
openByEdit: false,
openByShowSet: false,
openByMyselfSet: false,
visibleByView: false,
visibleByEdit: false,
visibleByShowSet: false,
visibleByMyselfSet: false,
title: '全部信息',
from: {
alarmId: '',
@@ -337,7 +336,7 @@ function fnModalVisibleByVive(row: Record<string, any>) {
modalState.title = t('views.faultManage.activeAlarm.viewIdInfo', {
alarmId: row.alarmId,
});
modalState.openByView = true;
modalState.visibleByView = true;
}
/**
@@ -352,7 +351,7 @@ function fnModalOk() {
duration: 3,
});
modalState.confirmLoading = false;
modalState.openByView = false;
modalState.visibleByView = false;
return false;
}
const result = updateConfirm(from);
@@ -364,7 +363,7 @@ function fnModalOk() {
content: t('common.msgSuccess', { msg: modalState.title }),
duration: 3,
});
modalState.openByView = false;
modalState.visibleByView = false;
fnGetList();
} else {
message.error({
@@ -431,16 +430,13 @@ function fnCancelConfirm() {
function mapKeysWithReduce(data: any[], titleMapping: Record<string, string>) {
return data.map((item: any) => {
if (typeof item !== 'object' || item === null) {
return item;
return item;
}
return Object.keys(item).reduce(
(newItem: Record<string, any>, key: string) => {
const title = titleMapping[key] || key;
newItem[title] = item[key];
return newItem;
},
{}
);
return Object.keys(item).reduce((newItem: Record<string, any>, key: string) => {
const title = titleMapping[key] || key;
newItem[title] = item[key];
return newItem;
}, {});
});
}
@@ -522,9 +518,9 @@ function fnExportAll() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.openByView = false;
modalState.openByShowSet = false;
modalState.visibleByEdit = false;
modalState.visibleByView = false;
modalState.visibleByShowSet = false;
}
/**查询列表, pageNum初始页数 */
@@ -648,7 +644,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="6" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmCode')"
@@ -688,7 +684,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="6" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.pvFlag')"
@@ -809,7 +805,7 @@ onMounted(() => {
onChange: onSelectChange,
}"
:pagination="tablePagination"
:scroll="{ x: tableColumns.length * 120, y: 400 }"
:scroll="{ x: 2500, y: 400 }"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'origSeverity'">
@@ -857,7 +853,7 @@ onMounted(() => {
:body-style="{ height: '520px', overflowY: 'scroll' }"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByView"
:visible="modalState.visibleByView"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -869,7 +865,7 @@ onMounted(() => {
layout="horizontal"
:label-col="{ span: 8 }"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmId')"
@@ -888,7 +884,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.neId')"
@@ -907,7 +903,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.neType')"
@@ -926,7 +922,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.alarmTitle')"
@@ -945,7 +941,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.pvFlag')"
@@ -972,7 +968,7 @@ onMounted(() => {
>
{{ modalState.from.locationInfo }}
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.province')"
@@ -1013,7 +1009,7 @@ onMounted(() => {
>
{{ modalState.from.specificProblem }}
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.clearType')"
@@ -1032,7 +1028,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.ackUser')"
@@ -1051,7 +1047,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.faultManage.activeAlarm.ackTime')"
+3 -3
View File
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
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 { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listAlarm } from '@/api/logManage/alarm';
+25 -18
View File
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { SizeType } from 'ant-design-vue/es/config-provider';
import { ColumnsType } from 'ant-design-vue/es/table';
import { Modal, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { Modal, message } from 'ant-design-vue/lib';
import { parseDateToStr } from '@/utils/date-utils';
import {
getBakFile,
@@ -277,27 +277,34 @@ onMounted(() => {
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-form :model="queryParams" name="queryParams" layout="horizontal">
<a-row :gutter="16" align="middle">
<a-col>
<span>{{ t('views.logManage.exportFile.fileName') }}:</span>&nbsp;
<a-select
v-model:value="logSelect"
:options="fileList"
@change="fnNeChange"
:allow-clear="false"
style="width: 200px"
/>
<a-row :gutter="16">
<a-col :lg="8" :md="12" :xs="24">
<a-form-item
:label="t('views.logManage.exportFile.fileName')"
name="fileName"
style="margin-bottom: 0"
>
<a-select
v-model:value="logSelect"
:options="fileList"
@change="fnNeChange"
:allow-clear="false"
/>
</a-form-item>
</a-col>
<template v-if="queryParams.path">
<span>{{ t('views.logManage.neFile.nePath') }}:</span>&nbsp;
<a-col>
<a-col :lg="16" :md="18" :xs="24" v-if="queryParams.path">
<a-form-item
:label="t('views.logManage.neFile.nePath')"
name="configName"
style="margin-bottom: 0"
>
<a-breadcrumb>
<a-breadcrumb-item>
{{ queryParams.path }}
</a-breadcrumb-item>
</a-breadcrumb>
</a-col>
</template>
</a-form-item>
</a-col>
</a-row>
</a-form>
</template>
+3 -3
View File
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
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 { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listForwarding } from '@/api/logManage/forwarding';
+2 -2
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { Form, Modal, message } from 'ant-design-vue/es';
import { Form, Modal, message } from 'ant-design-vue/lib';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import {
backupDownload,
@@ -411,7 +411,7 @@ onMounted(() => {
<template>
<PageContainer>
<a-row>
<a-row :gutter="16">
<a-col :span="8">
<!-- 日志设置 -->
<a-card :title="logSetState.title" :loading="logSetState.fromLoading">
+12 -15
View File
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
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 { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listMML } from '@/api/logManage/mml';
@@ -62,12 +62,12 @@ let tableState: TabeStateType = reactive({
});
/**表格字段列 */
let tableColumns: ColumnsType = reactive([
let tableColumns: ColumnsType = [
{
title: t('common.rowId'),
dataIndex: 'id',
align: 'left',
width: 80,
width: 100,
},
{
title: t('views.logManage.mml.account'),
@@ -108,9 +108,9 @@ let tableColumns: ColumnsType = reactive([
dataIndex: 'mml',
key: 'mml',
align: 'left',
ellipsis: true,
width: 200,
},
]);
];
/**表格分页器参数 */
let tablePagination = reactive({
@@ -161,11 +161,7 @@ function fnGetList(pageNum?: number) {
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
tablePagination.total = res.total;
tableState.data = res.rows;
if (
tablePagination.total <=
(queryParams.pageNum - 1) * tablePagination.pageSize &&
queryParams.pageNum !== 1
) {
if (tablePagination.total <=(queryParams.pageNum - 1) * tablePagination.pageSize &&queryParams.pageNum !== 1) {
tableState.loading = false;
fnGetList(queryParams.pageNum - 1);
}
@@ -293,15 +289,16 @@ onMounted(() => {
:loading="tableState.loading"
:data-source="tableState.data"
:size="tableState.size"
:pagination="tablePagination"
:pagination="tablePagination"
:scroll="{ x: tableColumns.length * 100 }"
>
<template #bodyCell="{ column, record }">
<!-- <template v-if="column.key === 'mml'">
<template v-if="column.key === 'mml'">
<a-tooltip placement="topLeft">
<template #title>{{ record.result }}</template>
<div class="mmlText">{{ record.mml }}</div>
</a-tooltip>
</template> -->
</template>
</template>
</a-table>
</a-card>
@@ -4,9 +4,9 @@ import { ProModal } from 'antdv-pro-modal';
import TerminalSSHView from '@/components/TerminalSSHView/index.vue';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
open: {
visible: {
type: Boolean,
default: false,
required: true,
@@ -34,7 +34,7 @@ const props = defineProps({
/**对话框对象信息状态类型 */
type StateType = {
/**框是否显示 */
open: boolean;
visible: boolean;
/**标题 */
title: string;
/**查看命令 */
@@ -43,7 +43,7 @@ type StateType = {
/**对话框对象信息状态 */
let state: StateType = reactive({
open: false,
visible: false,
title: '文件查看',
form: {
follow: true,
@@ -54,21 +54,21 @@ let state: StateType = reactive({
});
function onClose() {
state.open = false;
state.visible = false;
emit('cancel');
emit('update:open', false);
emit('update:visible', false);
}
/**监听是否显示,初始数据 */
watch(
() => props.open,
() => props.visible,
val => {
if (val) {
if (props.neType && props.neId) {
const filePath = props.filePath;
const fileName = filePath.substring(filePath.lastIndexOf('/') + 1);
state.title = fileName;
state.open = true;
state.visible = true;
}
}
}
@@ -114,9 +114,9 @@ function fnReload() {
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="state.open"
:visible="state.visible"
:title="state.title"
:body-style="{ overflow: 'hidden' }"
:body-style="{ padding: '12px', overflow: 'hidden' }"
:footer="null"
@cancel="onClose"
>
@@ -132,7 +132,7 @@ function fnReload() {
></TerminalSSHView>
<!-- 命令控制属性 -->
<a-form name="form" layout="horizontal">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.logManage.neFile.viewAs')">
<a-input-group compact>
+42 -32
View File
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { SizeType } from 'ant-design-vue/es/config-provider';
import { ColumnsType } from 'ant-design-vue/es/table';
import { Modal, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { Modal, message } from 'ant-design-vue/lib';
import { parseDateToStr } from '@/utils/date-utils';
import { getNeFile, listNeFiles } from '@/api/tool/neFile';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
@@ -260,7 +260,7 @@ function fnGetList(pageNum?: number) {
/**抽屉状态 */
const viewDrawerState = reactive({
open: false,
visible: false,
/**文件路径 /var/log/amf.log */
filePath: '',
/**网元类型 */
@@ -274,7 +274,7 @@ function fnDrawerOpen(row: Record<string, any>) {
viewDrawerState.filePath = [...nePathArr.value, row.fileName].join('/');
viewDrawerState.neType = neTypeSelect.value[0];
viewDrawerState.neId = neTypeSelect.value[1];
viewDrawerState.open = !viewDrawerState.open;
viewDrawerState.visible = !viewDrawerState.visible;
}
onMounted(() => {
@@ -300,33 +300,43 @@ onMounted(() => {
<a-card :bordered="false" :body-style="{ padding: '0px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-row :gutter="16" align="middle">
<a-col>
<span>{{ t('views.logManage.neFile.neType') }}:</span>&nbsp;
<a-cascader
v-model:value="neTypeSelect"
:options="neInfoStore.getNeCascaderOptions"
@change="fnNeChange"
:allow-clear="false"
:placeholder="t('views.logManage.neFile.neTypePlease')"
:disabled="downLoading || tableState.loading"
/>
</a-col>
<template v-if="nePathArr.length > 0">
<span>{{ t('views.logManage.neFile.nePath') }}:</span>&nbsp;
<a-col>
<a-breadcrumb>
<a-breadcrumb-item
v-for="(path, index) in nePathArr"
:key="path"
@click="fnDirCD(path, index)"
>
{{ path }}
</a-breadcrumb-item>
</a-breadcrumb>
<a-form :model="queryParams" name="queryParams" layout="horizontal">
<a-row :gutter="16">
<a-col :lg="8" :md="12" :xs="24">
<a-form-item
:label="t('views.logManage.neFile.neType')"
name="neType"
style="margin-bottom: 0"
>
<a-cascader
v-model:value="neTypeSelect"
:options="neInfoStore.getNeCascaderOptions"
@change="fnNeChange"
:allow-clear="false"
:placeholder="t('views.logManage.neFile.neTypePlease')"
:disabled="downLoading || tableState.loading"
/>
</a-form-item>
</a-col>
</template>
</a-row>
<a-col :lg="16" :md="18" :xs="24" v-if="nePathArr.length > 0">
<a-form-item
:label="t('views.logManage.neFile.nePath')"
name="configName"
style="margin-bottom: 0"
>
<a-breadcrumb>
<a-breadcrumb-item
v-for="(path, index) in nePathArr"
:key="path"
@click="fnDirCD(path, index)"
>
{{ path }}
</a-breadcrumb-item>
</a-breadcrumb>
</a-form-item>
</a-col>
</a-row>
</a-form>
</template>
<!-- 插槽-卡片右侧 -->
@@ -387,7 +397,7 @@ onMounted(() => {
<!-- 文件内容查看抽屉 -->
<ViewDrawer
v-model:open="viewDrawerState.open"
v-model:visible="viewDrawerState.visible"
:file-path="viewDrawerState.filePath"
:ne-type="viewDrawerState.neType"
:ne-id="viewDrawerState.neId"
+110 -52
View File
@@ -1,19 +1,15 @@
<script lang="ts" setup>
import svgLight from '@/assets/svg/light.svg';
import svgDark from '@/assets/svg/dark.svg';
import { message } from 'ant-design-vue/es';
import { reactive, onMounted, computed, toRaw } from 'vue';
import { message } from 'ant-design-vue/lib';
import { reactive, onMounted, computed } from 'vue';
import useUserStore from '@/store/modules/user';
import useAppStore from '@/store/modules/app';
import { getCaptchaImage } from '@/api/login';
import { useRouter, useRoute } from 'vue-router';
import useI18n from '@/hooks/useI18n';
import useLayoutStore from '@/store/modules/layout';
import { viewTransitionTheme } from 'antdv-pro-layout';
import { toRaw } from 'vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { parseUrlPath } from '@/plugins/file-static-url';
const { t, changeLocale, optionsLocale } = useI18n();
const layoutStore = useLayoutStore();
const { t, changeLocale, optionsLocale, currentLocale } = useI18n();
const appStore = useAppStore();
const router = useRouter();
const route = useRoute();
@@ -89,12 +85,28 @@ function fnGetCaptcha() {
});
}
// LOGO地址
const logoUrl = computed(() => {
let url =
appStore.logoType === 'brand'
? parseUrlPath(appStore.filePathBrand)
: parseUrlPath(appStore.filePathIcon);
if (url.indexOf('{language}') === -1) {
return url;
}
// 语言参数替换
const local = currentLocale.value;
const lang = local.split('_')[0];
return url.replace('{language}', lang);
});
// 判断是否有背景地址
const calcBG = computed(() => {
const bgURL = parseUrlPath(appStore.loginBackground);
if (bgURL && bgURL !== '#') {
return {
backgroundImage: `url('${bgURL}')`,
backgroundImage: `url(${bgURL})`,
backgroundPosition: 'center',
backgroundSize: 'cover',
};
@@ -113,13 +125,6 @@ function fnLocale() {
appStore.setTitle(title);
}
/**改变主题色 */
function fnClickTheme(e: any) {
viewTransitionTheme(isDarkMode => {
layoutStore.changeConf('theme', isDarkMode ? 'light' : 'dark');
}, e);
}
onMounted(() => {
fnLocale();
fnGetCaptcha();
@@ -141,9 +146,21 @@ function fnChangeLocale(e: any) {
<div class="animation animation5"></div>
</section>
<header class="header">
<div class="header-left">
<template v-if="appStore.logoType === 'icon'">
<img :src="logoUrl" class="logo-icon" :alt="appStore.appName" />
<span class="title">{{ appStore.appName }}</span>
</template>
<template v-if="appStore.logoType === 'brand'">
<img :src="logoUrl" class="logo-brand" :alt="appStore.appName" />
</template>
</div>
</header>
<a-card :bordered="false" class="login-card">
<div class="title">
{{ t('common.title') }}
<div class="desc">
{{ t('common.desc') }}
</div>
<a-form :model="state.from" name="stateFrom" @finish="fnFinish">
<a-form-item
@@ -192,7 +209,7 @@ function fnChangeLocale(e: any) {
</a-input-password>
</a-form-item>
<a-row v-if="state.captcha.enabled">
<a-row :gutter="8" v-if="state.captcha.enabled">
<a-col :span="16">
<a-form-item
name="code"
@@ -230,6 +247,7 @@ function fnChangeLocale(e: any) {
</a-row>
<a-row
:gutter="8"
justify="space-between"
align="middle"
style="margin-bottom: 16px"
@@ -256,26 +274,18 @@ function fnChangeLocale(e: any) {
{{ t('views.login.loginBtn') }}
</a-button>
<a-row justify="end" align="middle" style="margin-top: 18px">
<a-col :span="3">
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.theme') }}</template>
<a-button type="text" @click="fnClickTheme">
<template #icon>
<img
v-if="layoutStore.proConfig.theme === 'dark'"
:src="svgDark"
class="theme-icon"
/>
<img v-else :src="svgLight" class="theme-icon" />
</template>
</a-button>
</a-tooltip>
</a-col>
<a-col :span="3" v-if="appStore.i18nOpen">
<a-dropdown trigger="click" placement="bottomRight">
<a-button type="text">
<template #icon> <TranslationOutlined /> </template>
<a-row
:gutter="8"
justify="space-between"
align="middle"
style="margin-top: 18px"
v-if="appStore.i18nOpen"
>
<a-col :offset="18" :span="6">
<a-dropdown trigger="click">
<a-button size="small" type="default">
{{ t('i18n') }}
<DownOutlined />
</a-button>
<template #overlay>
<a-menu @click="fnChangeLocale">
@@ -289,6 +299,10 @@ function fnChangeLocale(e: any) {
</a-row>
</a-form>
</a-card>
<footer class="footer">
<div class="footer-copyright">{{ appStore.copyright }}</div>
</footer>
</div>
</template>
@@ -301,7 +315,7 @@ function fnChangeLocale(e: any) {
// background: url('./../assets/black_dot.png') 0% 0% / 14px 14px repeat;
background-image: url(@/assets/background_light.jpg);
background-image: url(@/assets/background.jpg);
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
@@ -349,9 +363,43 @@ function fnChangeLocale(e: any) {
}
}
[data-theme='dark'] .container {
background-image: url(@/assets/background_dark.jpg);
background-color: #141414;
.header {
position: fixed;
left: 0;
top: 0;
width: 100%;
z-index: 1000;
background-color: rgb(255 255 255 / 85%);
padding: 0 16px;
display: flex;
justify-content: space-between;
align-items: center;
.logo-icon {
height: 40px;
width: 40px;
margin-right: 14px;
vertical-align: top;
border-style: none;
border-radius: 6.66px;
margin-top: 4px;
margin-bottom: 4px;
}
.logo-brand {
height: 48px;
width: 174px;
vertical-align: top;
border-style: none;
border-radius: 2px;
}
.title {
position: relative;
top: 6px;
color: rgba(0, 0, 0, 0.85);
font-weight: 600;
font-size: 24px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
}
}
.login-card {
@@ -361,10 +409,10 @@ function fnChangeLocale(e: any) {
margin-left: 60%;
border-radius: 6px;
& .title {
text-align: left;
& .desc {
text-align: center;
margin-bottom: 18px;
color: #141414;
color: #666;
font-weight: 600;
font-size: 18px;
}
@@ -374,15 +422,25 @@ function fnChangeLocale(e: any) {
}
}
[data-theme='dark'] .login-card {
& .title {
color: #999;
}
}
@media (max-width: 992px) {
.login-card {
margin: 0 auto;
}
}
.footer {
position: absolute;
bottom: 0;
height: 36px;
padding: 8px 16px 0;
text-align: left;
background-color: rgb(255 255 255 / 85%);
width: 100%;
&-copyright {
font-size: 14px;
color: rgba(0, 0, 0, 0.75);
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
}
}
</style>
+2 -2
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { Form, message } from 'ant-design-vue/es';
import { Form, message } from 'ant-design-vue/lib';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { getOperationSet, updateOperationSet } from '@/api/mmlManage/mmlSet';
import { regExpIPv4 } from '@/utils/regular-utils';
@@ -90,7 +90,7 @@ onMounted(() => {
<template>
<PageContainer>
<a-row>
<a-row :gutter="16">
<a-col :span="8">
<!-- 接口设置 -->
<a-card
+2 -2
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { Modal, message } from 'ant-design-vue/es';
import { Modal, message } from 'ant-design-vue/lib';
import CodemirrorEdite from '@/components/CodemirrorEdite/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeInfoStore from '@/store/modules/neinfo';
@@ -9,7 +9,7 @@ import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
import useI18n from '@/hooks/useI18n';
import { getMMLByNE, sendMMlByNE } from '@/api/mmlManage/neOperate';
import { uploadFileToNE } from '@/api/tool/file';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
const neInfoStore = useNeInfoStore();
const { t } = useI18n();
+2 -2
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { Modal, message } from 'ant-design-vue/es';
import { Modal, message } from 'ant-design-vue/lib';
import CodemirrorEdite from '@/components/CodemirrorEdite/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeInfoStore from '@/store/modules/neinfo';
@@ -9,7 +9,7 @@ import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
import useI18n from '@/hooks/useI18n';
import { getMMLByOMC, sendMMlByOMC } from '@/api/mmlManage/omcOperate';
import { uploadFileToNE } from '@/api/tool/file';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
const { t } = useI18n();
/**网元参数 */
+2 -2
View File
@@ -1,14 +1,14 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { Modal, message } from 'ant-design-vue/es';
import { Modal, message } from 'ant-design-vue/lib';
import CodemirrorEdite from '@/components/CodemirrorEdite/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeInfoStore from '@/store/modules/neinfo';
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
import useI18n from '@/hooks/useI18n';
import { getMMLByUDM, sendMMlByUDM } from '@/api/mmlManage/udmOperate';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import { uploadFileToNE } from '@/api/tool/file';
const { t } = useI18n();
+3 -3
View File
@@ -9,8 +9,8 @@ import {
clearCacheSafe,
} from '@/api/monitor/cache';
import { PageContainer } from 'antdv-pro-layout';
import { ColumnsType } from 'ant-design-vue/es/table/Table';
import { message } from 'ant-design-vue/es';
import { ColumnsType } from 'ant-design-vue/lib/table/Table';
import { message } from 'ant-design-vue/lib';
import { hasPermissions } from '@/plugins/auth-user';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n';
@@ -268,7 +268,7 @@ onMounted(() => {
<template>
<PageContainer>
<a-row :gutter="16">
<a-row :gutter="20">
<a-col :lg="8" :md="8" :xs="24">
<a-card
:title="t('views.monitor.cache.cacheList')"
+31 -32
View File
@@ -2,11 +2,10 @@
import { useRouter, useRoute } from 'vue-router';
import { reactive, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { message, Modal, Form } 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 { message, Modal, Form } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import {
exportJob,
listJob,
@@ -191,9 +190,9 @@ function fnTableSelectedRowKeys(keys: (string | number)[]) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**详情框是否显示 */
openByView: boolean;
visibleByView: boolean;
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -201,13 +200,13 @@ type ModalStateType = {
/**确定按钮 loading */
confirmLoading: boolean;
/**cron生成框是否显示 */
openByCron: boolean;
visibleByCron: boolean;
};
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByView: false,
openByEdit: false,
visibleByView: false,
visibleByEdit: false,
title: '任务',
from: {
jobId: undefined,
@@ -223,7 +222,7 @@ let modalState: ModalStateType = reactive({
remark: '',
},
confirmLoading: false,
openByCron: false,
visibleByCron: false,
});
/**对话框内表单属性和校验规则 */
@@ -274,7 +273,7 @@ function fnModalVisibleByVive(jobId: string | number) {
if (res.code === RESULT_CODE_SUCCESS && res.data) {
modalState.from = Object.assign(modalState.from, res.data);
modalState.title = t('views.monitor.job.viewJob');
modalState.openByView = true;
modalState.visibleByView = true;
} else {
message.error(t('views.monitor.job.viewInfoErr'), 2);
}
@@ -289,7 +288,7 @@ function fnModalVisibleByEdit(jobId?: string | number) {
if (!jobId) {
modalStateFrom.resetFields();
modalState.title = t('views.monitor.job.addJob');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
if (modalState.confirmLoading) return;
const hide = message.loading(t('common.loading'), 0);
@@ -300,7 +299,7 @@ function fnModalVisibleByEdit(jobId?: string | number) {
if (res.code === RESULT_CODE_SUCCESS && res.data) {
modalState.from = Object.assign(modalState.from, res.data);
modalState.title = t('views.monitor.job.editJob');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
message.error(t('views.monitor.job.viewInfoErr'), 2);
}
@@ -329,7 +328,7 @@ function fnModalOk() {
key,
duration: 2,
});
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
fnGetList(1);
} else {
@@ -354,8 +353,8 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.openByView = false;
modalState.visibleByEdit = false;
modalState.visibleByView = false;
modalStateFrom.resetFields();
}
@@ -363,7 +362,7 @@ function fnModalCancel() {
* 对话框弹出cron生成回调
*/
function fnModalCron(opt: boolean, cronStr?: string) {
modalState.openByCron = opt;
modalState.visibleByCron = opt;
if (cronStr) {
modalState.from.cronExpression = cronStr;
}
@@ -652,7 +651,7 @@ onMounted(() => {
<a-card :bordered="false" :body-style="{ padding: '0px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-space :size="8" align="center">
<div class="button-container">
<a-button
type="primary"
@click.prevent="fnModalVisibleByEdit()"
@@ -696,12 +695,12 @@ onMounted(() => {
<template #icon><SyncOutlined /></template>
{{ t('views.monitor.job.resetQueue') }}
</a-button>
</a-space>
</div>
</template>
<!-- 插槽-卡片右侧 -->
<template #extra>
<a-space :size="8" align="center">
<div class="button-container">
<a-tooltip>
<template #title>{{ t('common.searchBarText') }}</template>
<a-switch
@@ -741,7 +740,7 @@ onMounted(() => {
</template>
</a-dropdown>
</a-tooltip>
</a-space>
</div>
</template>
<!-- 表格列表 -->
@@ -849,12 +848,12 @@ onMounted(() => {
<ProModal
:drag="true"
:width="800"
:open="modalState.openByView"
:visible="modalState.visibleByView"
:title="modalState.title"
@cancel="fnModalCancel"
>
<a-form layout="horizontal" :label-col="{ span: 6 }" :label-wrap="true">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.monitor.job.jobName')" name="jobName">
{{ modalState.from.jobName }}
@@ -870,7 +869,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.job.invokeTarget')"
@@ -892,7 +891,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.job.cronExpression')"
@@ -964,7 +963,7 @@ onMounted(() => {
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -976,7 +975,7 @@ onMounted(() => {
:label-col="{ span: 6 }"
:label-wrap="true"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.job.jobName')"
@@ -1003,7 +1002,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.job.jobGroup')"
@@ -1048,7 +1047,7 @@ onMounted(() => {
<template #title>
<div>{{ t('views.monitor.job.invokeTargetTip') }}</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -1074,7 +1073,7 @@ onMounted(() => {
{{ t('views.monitor.job.cronExpressionTip1') }}
</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
<template #addonAfter>
@@ -1122,7 +1121,7 @@ onMounted(() => {
<!-- 生成cron表达式 -->
<CronModal
v-model:open="modalState.openByCron"
v-model:visible="modalState.visibleByCron"
:cron="modalState.from.cronExpression"
@ok="fnModalCron(false, $event)"
></CronModal>
+16 -17
View File
@@ -2,11 +2,10 @@
import { useRoute, useRouter } from 'vue-router';
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { message, Modal } 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 { message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import {
exportJobLog,
listJobLog,
@@ -217,7 +216,7 @@ function fnTableSelectedRowKeys(keys: (string | number)[]) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**详情框是否显示 */
open: boolean;
visibleByView: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -226,7 +225,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
open: false,
visibleByView: false,
title: '任务日志',
from: {
jobLogId: undefined,
@@ -247,14 +246,14 @@ let modalState: ModalStateType = reactive({
function fnModalVisibleByVive(row: Record<string, string>) {
modalState.from = Object.assign(modalState.from, row);
modalState.title = t('views.monitor.jobLog.viewLog');
modalState.open = true;
modalState.visibleByView = true;
}
/**
* 对话框弹出关闭执行函数
*/
function fnModalCancel() {
modalState.open = false;
modalState.visibleByView = false;
}
/**
@@ -504,7 +503,7 @@ onMounted(() => {
<a-card :bordered="false" :body-style="{ padding: '0px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-space :size="8" align="center">
<div class="button-container">
<a-button type="default" @click.prevent="fnClose()">
<template #icon><CloseOutlined /></template>
{{ t('common.close') }}
@@ -536,12 +535,12 @@ onMounted(() => {
<template #icon><ExportOutlined /></template>
{{ t('common.export') }}
</a-button>
</a-space>
</div>
</template>
<!-- 插槽-卡片右侧 -->
<template #extra>
<a-space :size="8" align="center">
<div class="button-container">
<a-tooltip>
<template #title>{{ t('common.searchBarText') }}</template>
<a-switch
@@ -581,7 +580,7 @@ onMounted(() => {
</template>
</a-dropdown>
</a-tooltip>
</a-space>
</div>
</template>
<!-- 表格列表 -->
@@ -636,12 +635,12 @@ onMounted(() => {
<ProModal
:drag="true"
:width="800"
:open="modalState.open"
:visible="modalState.visibleByView"
:title="modalState.title"
@cancel="fnModalCancel"
>
<a-form layout="horizontal" :label-col="{ span: 6 }" :label-wrap="true">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('common.rowId')" name="jobLogId">
{{ modalState.from.jobLogId }}
@@ -663,7 +662,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.jobLog.jobName')"
@@ -684,7 +683,7 @@ onMounted(() => {
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.jobLog.invokeTarget')"
+1 -1
View File
@@ -466,7 +466,7 @@ onMounted(() => {
</a-form>
</a-card>
<a-row>
<a-row :gutter="16">
<a-col :lg="24" :md="24" :xs="24">
<a-card :bordered="false" :body-style="{ marginBottom: '24px' }">
<!-- 插槽-卡片左侧侧 -->
+4 -4
View File
@@ -1,12 +1,12 @@
<script setup lang="ts">
import { reactive, onMounted } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { message, Modal } from 'ant-design-vue/es';
import { message, Modal } from 'ant-design-vue/lib';
import { forceLogout, listOnline } from '@/api/monitor/online';
import { parseDateToStr } from '@/utils/date-utils';
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 { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
+1 -1
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ColumnsType } from 'ant-design-vue/es/table';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { getSystemInfo } from '@/api/monitor/system';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n';
+13 -30
View File
@@ -4,10 +4,9 @@ import { PageContainer } from 'antdv-pro-layout';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listAllNeInfo, stateNeInfo } from '@/api/ne/neInfo';
import { message } from 'ant-design-vue/es';
import { message } from 'ant-design-vue/lib';
import { randerGroph, switchLayout } from './graph';
import { parseDateToStr } from '@/utils/date-utils';
import { parseBasePath } from '@/plugins/file-static-url';
const { t } = useI18n();
/**图DOM节点实例对象 */
@@ -24,18 +23,16 @@ const graphG6Data = reactive<Record<string, any>>({
/**查询全部网元数据列表 */
function fnRanderData() {
if (!graphG6Dom.value) return false;
if (!graphG6Dom.value) return;
graphG6.value = randerGroph(t, graphG6Dom.value, graphG6Data);
return true;
}
/**网元状态调度器 */
const interval = ref<boolean>(true);
const interval10s = ref<any>(null);
/**查询网元状态 */
async function fnGetState() {
for (const node of graphG6Data.nodes) {
if (!interval.value) return;
const ne = node.info;
// if (ne.neType === 'OMC') continue;
const result = await stateNeInfo(ne.neType, ne.neId);
@@ -64,7 +61,7 @@ function fnGetList(refresh: boolean = false) {
res.data.length > 0
) {
// 根网管
let rootNodeInfo = { neName: 'OMC_001' };
let rootNodeInfo = { neName: "OMC_001" };
const nodes = [];
const edges = [];
for (const item of res.data) {
@@ -90,7 +87,7 @@ function fnGetList(refresh: boolean = false) {
x: -30,
y: -30,
// 可更换为其他图片地址
img: parseBasePath('/svg/service_db.svg'),
img: '/svg/service_db.svg',
width: 60,
height: 60,
},
@@ -105,7 +102,7 @@ function fnGetList(refresh: boolean = false) {
icon: {
x: -24,
y: -24,
img: parseBasePath('/svg/service.svg'),
img: '/svg/service.svg',
width: 48,
height: 48,
},
@@ -142,31 +139,17 @@ function fnGetList(refresh: boolean = false) {
}
})
.then(hasNeList => {
if (!hasNeList) return false;
if (!hasNeList) return;
if (refresh) {
// graphG6.value.get('canvas').set('localRefresh', true);
graphG6.value.destroy();
// graphG6.value.clear();
}
return fnRanderData();
})
.then(randerGroph => {
if (!randerGroph) return;
repeatFn();
});
}
/**递归刷新网元状态 */
function repeatFn() {
if (!interval.value) {
return;
}
fnGetState()
.finally(() => {
repeatFn(); // 递归调用自己
})
.catch(error => {
console.error(error);
fnRanderData();
fnGetState();
interval10s.value = setInterval(() => {
fnGetState(); // 获取网元状态
}, 10_000);
});
}
@@ -176,7 +159,7 @@ onMounted(() => {
});
onBeforeUnmount(() => {
interval.value = false;
clearInterval(interval10s.value);
});
</script>
@@ -6,7 +6,7 @@ import {
RESULT_CODE_SUCCESS,
} from '@/constants/result-constants';
import { listAllNeInfo } from '@/api/ne/neInfo';
import { message } from 'ant-design-vue/es';
import { message } from 'ant-design-vue/lib';
import { getGraphData } from '@/api/monitor/topology';
import { parseDateToStr } from '@/utils/date-utils';
import { Graph, GraphData, Menu, Tooltip } from '@antv/g6';
@@ -24,7 +24,6 @@ import {
import useNeOptions from '@/views/ne/neInfo/hooks/useNeOptions';
import useI18n from '@/hooks/useI18n';
import { OptionsType, WS } from '@/plugins/ws-websocket';
import { parseBasePath } from '@/plugins/file-static-url';
const { t } = useI18n();
const { fnNeRestart, fnNeStop, fnNeLogFile } = useNeOptions();
const ws = new WS();
@@ -166,7 +165,7 @@ const graphNodeTooltip = new Tooltip({
</span></div>
<div><strong>${t('views.monitor.topology.expiryDate')}:</strong><span>
${neState.expire ?? '--'}
</span></div>
</span></div>
</div>
`;
},
@@ -292,11 +291,6 @@ function fnGraphDataLoad(reload: boolean = false) {
const nf: Record<string, any>[] = nodes.filter(
(node: Record<string, any>) => {
Reflect.set(node, 'neState', { online: false });
// 图片路径处理
if (node.img) node.img = parseBasePath(node.img);
if (node.icon.show && node.icon?.img)
node.icon.img = parseBasePath(node.icon.img);
// 遍历是否有网元数据
const nodeID: string = node.id;
const hasNe = res.neList.some(ne => {
Reflect.set(node, 'neInfo', ne.neType === nodeID ? ne : {});
@@ -353,11 +347,11 @@ function fnGraphDataLoad(reload: boolean = false) {
}
clearInterval(interval10s.value);
interval10s.value = null;
fnGetState();
interval10s.value = setInterval(async () => {
if (!interval10s.value) return;
fnGetState(); // 获取网元状态
}, 20_000);
fnGetState().finally(() => {
interval10s.value = setInterval(() => {
fnGetState(); // 获取网元状态
}, 10_000);
});
});
}
@@ -365,7 +359,7 @@ function fnGraphDataLoad(reload: boolean = false) {
const interval10s = ref<any>(null);
/**查询网元状态 */
function fnGetState() {
async function fnGetState() {
// 获取节点状态
for (const node of graphState.data.nodes) {
if (notNeNodes.includes(node.id)) continue;
@@ -512,20 +506,16 @@ onBeforeUnmount(() => {
>
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-space :size="8" align="center">
<div class="button-container" style="margin-bottom: -12px">
<span>
{{ t('views.monitor.topologyBuild.graphGroup') }}:
{{ graphState.group }}
</span>
</a-space>
</div>
</template>
<!-- 插槽-卡片右侧 -->
<template #extra>
<a-button
type="default"
size="small"
@click.prevent="fnGraphDataLoad(true)"
>
<a-button type="default" @click.prevent="fnGraphDataLoad(true)">
<template #icon><ReloadOutlined /></template>
{{ t('common.reloadText') }}
</a-button>
@@ -1,6 +1,5 @@
<script setup lang="ts">
import { reactive, watch } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import useI18n from '@/hooks/useI18n';
import {
graphEvent,
@@ -54,21 +53,21 @@ watch(graphEvent, v => {
edgeState.form.id = '#';
modalState.title = t('views.monitor.topologyBuild.edgeTitleAdd');
modalState.formType = 'edge';
modalState.open = true;
modalState.visible = true;
}
if (type === 'canvas-create-node') {
nodeState.origin = {};
nodeState.form.id = '';
modalState.title = t('views.monitor.topologyBuild.nodeTitleAdd');
modalState.formType = 'node';
modalState.open = true;
modalState.visible = true;
}
if (type === 'canvas-create-combo') {
comboState.origin = {};
comboState.form.id = '';
modalState.title = t('views.monitor.topologyBuild.comboTitleAdd');
modalState.formType = 'combo';
modalState.open = true;
modalState.visible = true;
}
// 边
if (type === 'edge-edit' && item) {
@@ -77,7 +76,7 @@ watch(graphEvent, v => {
edgeState.form = Object.assign(edgeState.form, edge);
modalState.title = t('views.monitor.topologyBuild.edgeTitleEdit');
modalState.formType = 'edge';
modalState.open = true;
modalState.visible = true;
}
// 节点
if (type === 'node-edit' && item) {
@@ -86,7 +85,7 @@ watch(graphEvent, v => {
nodeState.form = Object.assign(nodeState.form, node);
modalState.title = t('views.monitor.topologyBuild.nodeTitleEdit');
modalState.formType = 'node';
modalState.open = true;
modalState.visible = true;
}
// 分组
if (type === 'combo-edit' && item) {
@@ -99,14 +98,14 @@ watch(graphEvent, v => {
}
modalState.title = t('views.monitor.topologyBuild.comboTitleEdit');
modalState.formType = 'combo';
modalState.open = true;
modalState.visible = true;
}
});
/**对话框对象信息状态类型 */
type ModalStateType = {
/**对话框是否显示 */
open: boolean;
visible: boolean;
/**标题 */
title: string;
/**图元素表单类型 */
@@ -117,7 +116,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
open: false,
visible: false,
title: '图信息',
formType: 'edge',
confirmLoading: false,
@@ -133,21 +132,21 @@ function fnModalOk() {
// 边编辑确认
if (type === 'edge') {
handleOkEdge().then(result => {
modalState.open = !result;
modalState.visible = !result;
modalState.confirmLoading = false;
});
}
// 节点编辑确认
if (type === 'node') {
handleOkNode().then(result => {
modalState.open = !result;
modalState.visible = !result;
modalState.confirmLoading = false;
});
}
// 分租编辑确认
if (type === 'combo') {
handleOkcombo().then(result => {
modalState.open = !result;
modalState.visible = !result;
modalState.confirmLoading = false;
});
}
@@ -158,7 +157,7 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.open = false;
modalState.visible = false;
const type = modalState.formType;
// 边编辑还原
if (type === 'edge') {
@@ -180,10 +179,10 @@ function fnModalCancel() {
:drag="true"
:width="800"
:destroyOnClose="true"
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
:body-style="{ maxHeight: '650px', 'overflow-y': 'auto' }"
:keyboard="false"
:mask-closable="false"
:open="modalState.open"
:visible="modalState.visible"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -241,7 +240,7 @@ function fnModalCancel() {
</a-form-item>
<!-- 圆形尺寸 -->
<a-row v-if="comboState.form.type.startsWith('circle')">
<a-row :gutter="16" v-if="comboState.form.type.startsWith('circle')">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.comboFormSize')"
@@ -270,7 +269,7 @@ function fnModalCancel() {
</a-row>
<!-- 矩形尺寸 -->
<a-row v-if="comboState.form.type.startsWith('rect')">
<a-row :gutter="16" v-if="comboState.form.type.startsWith('rect')">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.comboFormSize')"
@@ -309,7 +308,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formStyleFill')"
@@ -397,7 +396,7 @@ function fnModalCancel() {
</a-input>
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formLabelStyleFill')"
@@ -425,7 +424,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formLabelRefX')"
@@ -458,7 +457,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formLabelPosition')"
@@ -526,7 +525,7 @@ function fnModalCancel() {
</a-select>
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.nodeFormX')"
@@ -553,7 +552,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col
:lg="12"
:md="12"
@@ -654,7 +653,7 @@ function fnModalCancel() {
</a-row>
<template v-if="!nodeState.form.type.startsWith('image')">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formStyleStroke')"
@@ -729,7 +728,7 @@ function fnModalCancel() {
</a-input>
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formLabelStyleFill')"
@@ -757,7 +756,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formLabelPosition')"
@@ -792,7 +791,7 @@ function fnModalCancel() {
{{ t('views.monitor.topologyBuild.nodeFormTypeImage') }}
</a-divider>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.nodeFormClipShow')"
@@ -836,7 +835,7 @@ function fnModalCancel() {
<!-- 裁剪功能 -->
<template v-if="nodeState.form.clipCfg.show">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.nodeFormClipType')"
@@ -852,7 +851,10 @@ function fnModalCancel() {
</a-row>
<!-- 剪裁圆形 -->
<a-row v-if="nodeState.form.clipCfg.type.startsWith('circle')">
<a-row
:gutter="16"
v-if="nodeState.form.clipCfg.type.startsWith('circle')"
>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.nodeFormClipTypeCircle')"
@@ -870,7 +872,10 @@ function fnModalCancel() {
</a-row>
<!-- 剪裁矩形 -->
<a-row v-if="nodeState.form.clipCfg.type.startsWith('rect')">
<a-row
:gutter="16"
v-if="nodeState.form.clipCfg.type.startsWith('rect')"
>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="
@@ -906,7 +911,7 @@ function fnModalCancel() {
</a-row>
<!-- 剪裁椭圆 -->
<a-row v-if="nodeState.form.clipCfg.type === 'ellipse'">
<a-row :gutter="16" v-if="nodeState.form.clipCfg.type === 'ellipse'">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="
@@ -942,7 +947,7 @@ function fnModalCancel() {
</a-row>
<!-- 裁剪图形坐标 -->
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.nodeFormClipX')"
@@ -987,7 +992,7 @@ function fnModalCancel() {
{{ t('views.monitor.topologyBuild.nodeFormIcon') }}
</a-divider>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.nodeFormIconShow')"
@@ -1011,7 +1016,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.nodeFormIconWidth')"
@@ -1042,7 +1047,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row v-if="nodeState.form.type === 'triangle'">
<a-row :gutter="16" v-if="nodeState.form.type === 'triangle'">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.nodeFormIconOffset')"
@@ -1082,7 +1087,7 @@ function fnModalCancel() {
</a-select>
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.edgeFormSource')"
@@ -1113,7 +1118,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formStyleStroke')"
@@ -1141,7 +1146,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.edgeFormStartArrow')"
@@ -1180,7 +1185,7 @@ function fnModalCancel() {
</a-input>
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formLabelStyleFill')"
@@ -1208,7 +1213,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formLabelRefX')"
@@ -1241,7 +1246,7 @@ function fnModalCancel() {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.formLabelPosition')"
@@ -1,4 +1,4 @@
import { message, Form } from 'ant-design-vue/es';
import { message, Form } from 'ant-design-vue/lib';
import { reactive, toRaw, watch } from 'vue';
import { graphG6, selectSourceTargetOptions } from './useGraph';
import useI18n from '@/hooks/useI18n';
@@ -1,4 +1,4 @@
import { message, Form } from 'ant-design-vue/es';
import { message, Form } from 'ant-design-vue/lib';
import { reactive, watch } from 'vue';
import useI18n from '@/hooks/useI18n';
import { graphG6 } from './useGraph';
@@ -1,4 +1,4 @@
import { message, Form } from 'ant-design-vue/es';
import { message, Form } from 'ant-design-vue/lib';
import { reactive, watch } from 'vue';
import { graphG6 } from './useGraph';
import useI18n from '@/hooks/useI18n';
+46 -43
View File
@@ -1,7 +1,6 @@
<script setup lang="ts">
import { reactive, onMounted, ref, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import useI18n from '@/hooks/useI18n';
import GraphEditModal from './components/GraphEditModal.vue';
import useGraph, { graphG6 } from './/hooks/useGraph';
@@ -12,8 +11,7 @@ import {
saveGraphData,
} from '@/api/monitor/topology';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { Form, Modal, message } from 'ant-design-vue/es';
import { parseBasePath } from '@/plugins/file-static-url';
import { Form, Modal, message } from 'ant-design-vue/lib';
const { t } = useI18n();
const { graphMode, graphModeOptions, handleRanderGraph, handleChangeMode } =
useGraph();
@@ -81,14 +79,6 @@ function fnGraphDataLoad(reload: boolean = false) {
getGraphData(graphState.group)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
res.data.nodes.map((item: any) => {
// 图片路径处理
if (item.img) item.img = parseBasePath(item.img);
if (item.icon.show && item.icon?.img) {
item.icon.img = parseBasePath(item.icon.img);
}
return item;
});
graphState.data = res.data;
}
})
@@ -105,7 +95,7 @@ function fnGraphDataLoad(reload: boolean = false) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**框是否显示 */
open: boolean;
visible: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -118,7 +108,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
open: false,
visible: false,
title: '图组',
form: {
group: '',
@@ -190,7 +180,7 @@ function fnModalOk() {
*/
function fnModalCancel() {
modalState.type = 'save';
modalState.open = false;
modalState.visible = false;
modalStateFrom.resetFields();
}
@@ -198,8 +188,8 @@ function fnModalCancel() {
function fnGraphDataSave() {
modalState.form.group = graphState.group;
modalState.type = 'save';
modalState.title = t('views.monitor.topologyBuild.saveTtite');
modalState.open = true;
(modalState.title = t('views.monitor.topologyBuild.saveTtite')),
(modalState.visible = true);
}
/**图组数据删除 */
@@ -254,44 +244,57 @@ onMounted(() => {
<template>
<PageContainer>
<a-card :bordered="false" :body-style="{ marginBottom: '24px' }">
<a-card
:bordered="false"
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
>
<!-- 表格搜索栏 -->
<a-row :gutter="16">
<a-col>
<span>{{ t('views.monitor.topologyBuild.graphMode') }}:</span>&nbsp;
<a-select
:value="graphMode"
:options="graphModeOptions"
@change="handleChangeMode"
>
</a-select>
</a-col>
<a-col>
<span>{{ t('views.monitor.topologyBuild.graphGroup') }}:</span>&nbsp;
<a-select
v-model:value="graphState.group"
:options="graphState.groupOptions"
:placeholder="t('common.selectPlease')"
@change="fnGraphGroupChange"
/>
</a-col>
</a-row>
<a-form :model="graphState" name="graphState" layout="horizontal">
<a-row :gutter="16">
<a-col :lg="4" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.graphMode')"
name="graphMode"
>
<a-select
:value="graphMode"
:options="graphModeOptions"
@change="handleChangeMode"
>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="6" :md="12" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.graphGroup')"
name="group "
>
<a-select
v-model:value="graphState.group"
:options="graphState.groupOptions"
:placeholder="t('common.selectPlease')"
@change="fnGraphGroupChange"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-card>
<a-card :bordered="false" :body-style="{ padding: '0px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>
<a-space :size="8" align="center">
<div class="button-container" style="margin-bottom: -12px">
<span>
{{ t('views.monitor.topologyBuild.graphGroup') }}:
{{ graphState.group }}
</span>
</a-space>
</div>
</template>
<!-- 插槽-卡片右侧 -->
<template #extra>
<a-space :size="8" align="center">
<div class="button-container" style="margin-bottom: -12px">
<template v-if="graphMode === 'edit'">
<a-button type="primary" size="small" @click="fnGraphDataSave">
<template #icon>
@@ -312,7 +315,7 @@ onMounted(() => {
{{ t('views.monitor.topologyBuild.graphDelete') }}
</a-button>
</template>
</a-space>
</div>
</template>
<div ref="graphG6Dom" class="chart"></div>
@@ -326,7 +329,7 @@ onMounted(() => {
:drag="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.open"
:visible="modalState.visible"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -338,7 +341,7 @@ onMounted(() => {
:label-col="{ span: 6 }"
:labelWrap="true"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="24" :md="24" :xs="24">
<a-form-item
:label="t('views.monitor.topologyBuild.graphGroup')"
@@ -4,8 +4,9 @@ import {
editNeConfigData,
} from '@/api/ne/neConfig';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { Modal,message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider';
import { Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import message from 'ant-design-vue/lib/message';
import { reactive, watch } from 'vue';
/**
@@ -87,7 +88,7 @@ export default function useConfigArray({
modalState.title = `${treeState.selectNode.paramDisplay} ${from.title}`;
modalState.key = from.key;
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
modalState.open = true;
modalState.visible = true;
// 关闭嵌套
arrayState.arrayChildExpandKeys = [];
@@ -232,7 +233,7 @@ export default function useConfigArray({
modalState.title = `${treeState.selectNode.paramDisplay} ${from.title}`;
modalState.key = from.key;
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
modalState.open = true;
modalState.visible = true;
}
/**多列表新增单行确认 */
@@ -4,8 +4,9 @@ import {
delNeConfigData,
} from '@/api/ne/neConfig';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { Modal, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider';
import { Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import message from 'ant-design-vue/lib/message';
import { nextTick, reactive } from 'vue';
/**
@@ -173,7 +174,7 @@ export default function useConfigArrayChild({
modalState.title = `${arrayChildState.title} ${from.title}`;
modalState.key = from.key;
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
modalState.open = true;
modalState.visible = true;
}
/**多列表嵌套行编辑确认 */
@@ -284,7 +285,7 @@ export default function useConfigArrayChild({
modalState.title = `${arrayChildState.title} ${from.title}`;
modalState.key = from.key;
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
modalState.open = true;
modalState.visible = true;
}
/**多列表新增单行确认 */
+2 -2
View File
@@ -1,7 +1,7 @@
import { editNeConfigData } from '@/api/ne/neConfig';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { SizeType } from 'ant-design-vue/es/config-provider';
import { message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import message from 'ant-design-vue/lib/message';
import { reactive, toRaw } from 'vue';
/**
+9 -10
View File
@@ -1,9 +1,8 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw, watch } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { message } from 'ant-design-vue/es';
import { DataNode } from 'ant-design-vue/es/tree';
import { message } from 'ant-design-vue/lib';
import { DataNode } from 'ant-design-vue/lib/tree';
import useI18n from '@/hooks/useI18n';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
@@ -251,7 +250,7 @@ function fnGetNeConfig() {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**添加框是否显示 */
open: boolean;
visible: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -268,7 +267,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
open: false,
visible: false,
title: 'Item',
from: {},
confirmLoading: false,
@@ -302,7 +301,7 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.open = false;
modalState.visible = false;
modalState.from = {};
modalState.type = 'arrayAdd';
modalState.key = '';
@@ -311,7 +310,7 @@ function fnModalCancel() {
// 监听新增编辑弹窗
watch(
() => modalState.open,
() => modalState.visible,
val => {
// SMF需要选择配置的UPF id
if (val && neTypeSelect.value[0] === 'SMF') {
@@ -442,7 +441,7 @@ onMounted(() => {
<a-card
size="small"
:bordered="false"
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
:body-style="{ maxHeight: '650px', 'overflow-y': 'auto' }"
:loading="treeState.selectLoading"
>
<template #title>
@@ -825,10 +824,10 @@ onMounted(() => {
:drag="true"
:width="800"
:destroyOnClose="true"
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
:body-style="{ maxHeight: '650px', 'overflow-y': 'auto' }"
:keyboard="false"
:mask-closable="false"
:open="modalState.open"
:visible="modalState.visible"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
+9 -10
View File
@@ -1,10 +1,9 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { Form, Modal, TableColumnsType, 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 { Form, Modal, TableColumnsType, message } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import useNeInfoStore from '@/store/modules/neinfo';
import useI18n from '@/hooks/useI18n';
import useDictStore from '@/store/modules/dict';
@@ -268,7 +267,7 @@ function fnRecordDelete(id: string) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -279,7 +278,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByEdit: false,
visibleByEdit: false,
title: '备份记录',
from: {
id: undefined,
@@ -299,7 +298,7 @@ function fnModalVisibleByEdit(row: Record<string, any>) {
modalState.from.name = row.name;
modalState.from.remark = row.remark;
modalState.title = t('views.ne.neConfigBackup.title', { txt: row.id });
modalState.openByEdit = true;
modalState.visibleByEdit = true;
}
/**对话框内表单属性和校验规则 */
@@ -333,7 +332,7 @@ function fnModalOk() {
content: t('common.msgSuccess', { msg: modalState.title }),
duration: 3,
});
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
fnGetList();
} else {
@@ -359,7 +358,7 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
}
@@ -558,7 +557,7 @@ onMounted(() => {
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -1,503 +0,0 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, watch } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import { Form, message } from 'ant-design-vue/es';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useDictStore from '@/store/modules/dict';
const { getDict } = useDictStore();
import {
addNeHost,
getNeHost,
testNeHost,
updateNeHost,
} from '@/api/ne/neHost';
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const props = defineProps({
open: {
type: Boolean,
default: false,
},
/**记录ID */
editId: {
type: String,
default: '',
},
/**分组可选网元 */
neGroup: {
type: Boolean,
default: false,
},
});
/**字典数据 */
let dict: {
/**主机类型 */
neHostType: DictType[];
/**分组 */
neHostGroupId: DictType[];
/**认证模式 */
neHostAuthMode: DictType[];
} = reactive({
neHostType: [],
neHostGroupId: [],
neHostAuthMode: [],
});
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
from: Record<string, any>;
/**确定按钮 loading */
confirmLoading: boolean;
};
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByEdit: false,
title: '信息',
from: {
hostId: undefined,
hostType: 'ssh',
groupId: '0',
title: '',
addr: '',
port: 22,
user: '',
authMode: '0',
password: '',
privateKey: '',
passPhrase: '',
remark: '',
},
confirmLoading: false,
uploadFiles: [],
});
/**对话框内表单属性和校验规则 */
const modalStateFrom = Form.useForm(
modalState.from,
reactive({
title: [
{
required: true,
min: 1,
max: 50,
message: t('views.ne.neHost.titlePlease'),
},
],
addr: [
{
required: true,
min: 1,
max: 128,
message: t('views.ne.neHost.addrPlease'),
},
],
port: [
{
required: true,
message: t('views.ne.neHost.portPlease'),
},
],
user: [
{
required: true,
min: 1,
max: 50,
message: t('views.ne.neHost.userPlease'),
},
],
password: [
{
required: true,
min: 1,
max: 128,
message: t('views.ne.neHost.passwordPlease'),
},
],
privateKey: [
{
required: true,
min: 1,
max: 3000,
message: t('views.ne.neHost.privateKeyPlease'),
},
],
})
);
/**
* 对话框弹出确认执行函数
* 进行表达规则校验
*/
function fnModalOk() {
if (modalState.confirmLoading) return;
const form = toRaw(modalState.from);
const validateArr = ['title', 'addr', 'port', 'user'];
if (form.authMode === '0') {
validateArr.push('password');
} else {
validateArr.push('privateKey');
}
modalStateFrom
.validate(validateArr)
.then(() => {
modalState.confirmLoading = true;
const neHost = form.hostId ? updateNeHost(form) : addNeHost(form);
const hide = message.loading(t('common.loading'), 0);
neHost
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 2,
});
// 返回无引用信息
emit('ok', JSON.parse(JSON.stringify(form)));
fnModalCancel();
} else {
message.error({
content: `${res.msg}`,
duration: 2,
});
}
})
.finally(() => {
modalState.confirmLoading = false;
hide();
});
})
.catch(e => {
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
});
}
/**
* 对话框弹出关闭执行函数
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.confirmLoading = false;
modalStateFrom.resetFields();
emit('cancel');
emit('update:open', false);
}
/**
* 对话框弹出显示为 ID编辑
* @param id id
*/
function fnModalVisibleById(id: string) {
if (modalState.confirmLoading) return;
const hide = message.loading(t('common.loading'), 0);
modalState.confirmLoading = true;
getNeHost(id)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS && res.data) {
modalState.from = Object.assign(modalState.from, res.data);
modalState.title = t('views.ne.neHost.editTitle');
modalState.openByEdit = true;
} else {
message.error(t('common.getInfoFail'), 2);
}
})
.finally(() => {
modalState.confirmLoading = false;
hide();
});
}
/**
* 对话框弹出测试连接
*/
function fnModalTest() {
if (modalState.confirmLoading) return;
const form = toRaw(modalState.from);
const validateArr = ['title', 'addr', 'port', 'user'];
if (form.authMode === '0') {
validateArr.push('password');
}
if (form.authMode === '1') {
validateArr.push('privateKey');
}
modalStateFrom
.validate(validateArr)
.then(() => {
modalState.confirmLoading = true;
const hide = message.loading(t('common.loading'), 0);
testNeHost(form)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.ne.neHost.testOk'),
duration: 2,
});
} else {
message.error({
content: `${res.msg}`,
duration: 2,
});
}
})
.finally(() => {
modalState.confirmLoading = false;
hide();
});
})
.catch(e => {
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
});
}
/**监听是否显示,初始数据 */
watch(
() => props.open,
val => {
if (val) {
if (props.editId) {
fnModalVisibleById(props.editId);
} else {
modalStateFrom.resetFields();
modalState.title = t('views.ne.neHost.addTitle');
modalState.openByEdit = true;
}
}
}
);
onMounted(() => {
// 初始字典数据
Promise.allSettled([
getDict('ne_host_type'),
getDict('ne_host_groupId'),
getDict('ne_host_authMode'),
]).then(resArr => {
if (resArr[0].status === 'fulfilled') {
dict.neHostType = resArr[0].value;
}
if (resArr[1].status === 'fulfilled') {
if (props.neGroup) {
dict.neHostGroupId = resArr[1].value.filter(item => item.value !== '1');
} else {
dict.neHostGroupId = resArr[1].value;
}
}
if (resArr[2].status === 'fulfilled') {
dict.neHostAuthMode = resArr[2].value;
}
});
});
</script>
<template>
<ProModal
:drag="true"
:width="800"
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@cancel="fnModalCancel"
>
<a-form
name="modalStateFromByEdit"
layout="horizontal"
:label-col="{ span: 6 }"
:label-wrap="true"
>
<a-row>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.neHost.hostType')" name="hostType">
<a-select
v-model:value="modalState.from.hostType"
default-value="ssh"
:options="dict.neHostType"
:disabled="!!modalState.from.hostId"
>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.neHost.groupId')" name="groupId">
<a-select
v-model:value="modalState.from.groupId"
default-value="0"
:options="dict.neHostGroupId"
:disabled="!!modalState.from.hostId"
>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item
:label="t('views.ne.neHost.title')"
name="title"
v-bind="modalStateFrom.validateInfos.title"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-input
v-model:value="modalState.from.title"
allow-clear
:maxlength="50"
:placeholder="t('common.inputPlease')"
>
</a-input>
</a-form-item>
<a-row>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.addr')"
name="addr"
v-bind="modalStateFrom.validateInfos.addr"
>
<a-input
v-model:value="modalState.from.addr"
allow-clear
:maxlength="128"
:placeholder="t('common.inputPlease')"
>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.port')"
name="port"
v-bind="modalStateFrom.validateInfos.port"
>
<a-input-number
v-model:value="modalState.from.port"
:min="10"
:max="65535"
:step="1"
:maxlength="5"
style="width: 100%"
></a-input-number>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.user')"
name="user"
v-bind="modalStateFrom.validateInfos.user"
>
<a-input
v-model:value="modalState.from.user"
allow-clear
:maxlength="32"
:placeholder="t('common.inputPlease')"
>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.neHost.authMode')" name="authMode">
<a-select
v-model:value="modalState.from.authMode"
default-value="0"
:options="dict.neHostAuthMode"
>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item
v-if="modalState.from.authMode === '0'"
:label="t('views.ne.neHost.password')"
name="password"
v-bind="modalStateFrom.validateInfos.password"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-input-password
v-model:value="modalState.from.password"
:maxlength="128"
:placeholder="t('common.inputPlease')"
>
</a-input-password>
</a-form-item>
<template v-if="modalState.from.authMode === '1'">
<a-form-item
:label="t('views.ne.neHost.privateKey')"
name="privateKey"
v-bind="modalStateFrom.validateInfos.privateKey"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-textarea
v-model:value="modalState.from.privateKey"
:auto-size="{ minRows: 4, maxRows: 6 }"
:maxlength="3000"
:show-count="true"
:placeholder="t('views.ne.neHost.privateKeyPlease')"
/>
</a-form-item>
<a-form-item
:label="t('views.ne.neHost.passPhrase')"
name="passPhrase"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-input-password
v-model:value="modalState.from.passPhrase"
:maxlength="128"
:placeholder="t('common.inputPlease')"
>
</a-input-password>
</a-form-item>
</template>
<a-form-item
:label="t('common.remark')"
name="remark"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-textarea
v-model:value="modalState.from.remark"
:auto-size="{ minRows: 1, maxRows: 6 }"
:maxlength="450"
:show-count="true"
:placeholder="t('common.inputPlease')"
/>
</a-form-item>
<a-form-item
:label="t('views.ne.neHost.test')"
name="test"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-button
type="primary"
shape="round"
@click="fnModalTest"
:loading="modalState.confirmLoading"
>
<template #icon><LinkOutlined /></template>
</a-button>
</a-form-item>
</a-form>
</ProModal>
</template>
<style lang="less" scoped></style>
+397 -32
View File
@@ -1,20 +1,24 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, defineAsyncComponent } from 'vue';
import { reactive, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
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 { Modal, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { Form, Modal, message } from 'ant-design-vue/lib';
import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { delNeHost, listNeHost } from '@/api/ne/neHost';
import {
addNeHost,
delNeHost,
getNeHost,
listNeHost,
testNeHost,
updateNeHost,
} from '@/api/ne/neHost';
import useDictStore from '@/store/modules/dict';
import useI18n from '@/hooks/useI18n';
const { getDict } = useDictStore();
const { t } = useI18n();
const EditModal = defineAsyncComponent(
() => import('./components/EditModal.vue')
);
/**字典数据 */
let dict: {
@@ -35,7 +39,7 @@ let queryParams = reactive({
/**主机类型 */
hostType: undefined,
/**分组 */
groupId: '1',
groupId: undefined,
/**名称 */
title: '',
/**当前页数 */
@@ -48,7 +52,7 @@ let queryParams = reactive({
function fnQueryReset() {
queryParams = Object.assign(queryParams, {
hostType: undefined,
groupId: '1',
groupId: undefined,
title: '',
pageNum: 1,
pageSize: 20,
@@ -207,31 +211,115 @@ function fnGetList(pageNum?: number) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByEdit: boolean;
/**记录ID */
hostId: string;
visibleByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
from: Record<string, any>;
/**确定按钮 loading */
confirmLoading: boolean;
};
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByEdit: false,
hostId: '',
visibleByEdit: false,
title: '信息',
from: {
hostId: undefined,
hostType: 'ssh',
groupId: '0',
title: '',
addr: '',
port: 22,
user: '',
authMode: '0',
password: '',
privateKey: '',
passPhrase: '',
remark: '',
},
confirmLoading: false,
});
/**对话框内表单属性和校验规则 */
const modalStateFrom = Form.useForm(
modalState.from,
reactive({
title: [
{
required: true,
min: 1,
max: 50,
message: t('views.ne.neHost.titlePlease'),
},
],
addr: [
{
required: true,
min: 1,
max: 128,
message: t('views.ne.neHost.addrPlease'),
},
],
port: [
{
required: true,
message: t('views.ne.neHost.portPlease'),
},
],
user: [
{
required: true,
min: 1,
max: 50,
message: t('views.ne.neHost.userPlease'),
},
],
password: [
{
required: true,
min: 1,
max: 128,
message: t('views.ne.neHost.passwordPlease'),
},
],
privateKey: [
{
required: true,
min: 1,
max: 3000,
message: t('views.ne.neHost.privateKeyPlease'),
},
],
})
);
/**
* 对话框弹出显示为 新增或者修改
* @param roleId 角色编号ID, 不传为新增
*/
function fnModalVisibleByEdit(roleId?: string) {
function fnModalVisibleByEdit(roleId?: string | number) {
if (!roleId) {
modalState.hostId = '';
modalStateFrom.resetFields();
modalState.title = t('views.ne.neHost.addTitle');
modalState.visibleByEdit = true;
} else {
modalState.hostId = roleId;
if (modalState.confirmLoading) return;
const hide = message.loading(t('common.loading'), 0);
modalState.confirmLoading = true;
// 查询角色详细同时根据角色ID查询菜单下拉树结构
getNeHost(roleId).then(res => {
modalState.confirmLoading = false;
hide();
if (res.code === RESULT_CODE_SUCCESS && res.data) {
modalState.from = Object.assign(modalState.from, res.data);
modalState.title = t('views.ne.neHost.editTitle');
modalState.visibleByEdit = true;
} else {
message.error(t('common.getInfoFail'), 2);
}
});
}
modalState.openByEdit = true;
}
/**
@@ -239,8 +327,44 @@ function fnModalVisibleByEdit(roleId?: string) {
* 进行表达规则校验
*/
function fnModalOk() {
// 获取列表数据
fnGetList();
if (modalState.confirmLoading) return;
const form = toRaw(modalState.from);
const validateArr = ['title', 'addr', 'port', 'user'];
if (form.authMode === '0') {
validateArr.push('password');
} else {
validateArr.push('privateKey');
}
modalStateFrom
.validate(validateArr)
.then(() => {
modalState.confirmLoading = true;
const neHost = form.hostId ? updateNeHost(form) : addNeHost(form);
const hide = message.loading(t('common.loading'), 0);
neHost
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 2,
});
fnModalCancel();
fnGetList(1);
} else {
message.error({
content: `${res.msg}`,
duration: 2,
});
}
})
.finally(() => {
modalState.confirmLoading = false;
hide();
});
})
.catch(e => {
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
});
}
/**
@@ -248,8 +372,8 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.hostId = '';
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
}
/**
@@ -281,6 +405,48 @@ function fnRecordDelete(hostId: string) {
});
}
/**
* 对话框弹出测试连接
*/
function fnModalTest() {
if (modalState.confirmLoading) return;
const form = toRaw(modalState.from);
const validateArr = ['title', 'addr', 'port', 'user'];
if (form.authMode === '0') {
validateArr.push('password');
}
if (form.authMode === '1') {
validateArr.push('privateKey');
}
modalStateFrom
.validate(validateArr)
.then(() => {
modalState.confirmLoading = true;
const hide = message.loading(t('common.loading'), 0);
testNeHost(form)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.ne.neHost.testOk'),
duration: 2,
});
} else {
message.error({
content: `${res.msg}`,
duration: 2,
});
}
})
.finally(() => {
modalState.confirmLoading = false;
hide();
});
})
.catch(e => {
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
});
}
onMounted(() => {
// 初始字典数据
Promise.allSettled([
@@ -365,10 +531,10 @@ onMounted(() => {
<a-card :bordered="false" :body-style="{ padding: '0px' }">
<!-- 插槽-卡片左侧侧 -->
<template #title>
<!-- <a-button type="primary" @click.prevent="fnModalVisibleByEdit()">
<a-button type="primary" @click.prevent="fnModalVisibleByEdit()">
<template #icon><PlusOutlined /></template>
{{ t('common.addText') }}
</a-button> -->
</a-button>
</template>
<!-- 插槽-卡片右侧 -->
@@ -445,7 +611,7 @@ onMounted(() => {
<template #icon><FormOutlined /></template>
</a-button>
</a-tooltip>
<!-- <a-tooltip>
<a-tooltip>
<template #title>{{ t('common.deleteText') }}</template>
<a-button
type="link"
@@ -453,19 +619,218 @@ onMounted(() => {
>
<template #icon><DeleteOutlined /></template>
</a-button>
</a-tooltip> -->
</a-tooltip>
</a-space>
</template>
</template>
</a-table>
<!-- 新增框或修改框 -->
<EditModal
v-model:open="modalState.openByEdit"
:edit-id="modalState.hostId"
<ProModal
:drag="true"
:width="800"
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@cancel="fnModalCancel"
></EditModal>
>
<a-form
name="modalStateFromByEdit"
layout="horizontal"
:label-col="{ span: 6 }"
:label-wrap="true"
>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.hostType')"
name="hostType"
>
<a-select
v-model:value="modalState.from.hostType"
default-value="ssh"
:options="dict.neHostType"
>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.neHost.groupId')" name="groupId">
<a-select
v-model:value="modalState.from.groupId"
default-value="0"
:options="dict.neHostGroupId"
>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item
:label="t('views.ne.neHost.title')"
name="title"
v-bind="modalStateFrom.validateInfos.title"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-input
v-model:value="modalState.from.title"
allow-clear
:maxlength="50"
:placeholder="t('common.inputPlease')"
>
</a-input>
</a-form-item>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.addr')"
name="addr"
v-bind="modalStateFrom.validateInfos.addr"
>
<a-input
v-model:value="modalState.from.addr"
allow-clear
:maxlength="128"
:placeholder="t('common.inputPlease')"
>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.port')"
name="port"
v-bind="modalStateFrom.validateInfos.port"
>
<a-input-number
v-model:value="modalState.from.port"
:min="10"
:max="65535"
:step="1"
:maxlength="5"
style="width: 100%"
></a-input-number>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.user')"
name="user"
v-bind="modalStateFrom.validateInfos.user"
>
<a-input
v-model:value="modalState.from.user"
allow-clear
:maxlength="32"
:placeholder="t('common.inputPlease')"
>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.authMode')"
name="authMode"
>
<a-select
v-model:value="modalState.from.authMode"
default-value="0"
:options="dict.neHostAuthMode"
>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item
v-if="modalState.from.authMode === '0'"
:label="t('views.ne.neHost.password')"
name="password"
v-bind="modalStateFrom.validateInfos.password"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-input-password
v-model:value="modalState.from.password"
:maxlength="128"
:placeholder="t('common.inputPlease')"
>
</a-input-password>
</a-form-item>
<template v-if="modalState.from.authMode === '1'">
<a-form-item
:label="t('views.ne.neHost.privateKey')"
name="privateKey"
v-bind="modalStateFrom.validateInfos.privateKey"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-textarea
v-model:value="modalState.from.privateKey"
:auto-size="{ minRows: 4, maxRows: 6 }"
:maxlength="3000"
:show-count="true"
:placeholder="t('views.ne.neHost.privateKeyPlease')"
/>
</a-form-item>
<a-form-item
:label="t('views.ne.neHost.passPhrase')"
name="passPhrase"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-input-password
v-model:value="modalState.from.passPhrase"
:maxlength="128"
:placeholder="t('common.inputPlease')"
>
</a-input-password>
</a-form-item>
</template>
<a-form-item
:label="t('common.remark')"
name="remark"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-textarea
v-model:value="modalState.from.remark"
:auto-size="{ minRows: 1, maxRows: 6 }"
:maxlength="450"
:show-count="true"
:placeholder="t('common.inputPlease')"
/>
</a-form-item>
<a-form-item
:label="t('views.ne.neHost.test')"
name="test"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-button
type="primary"
shape="round"
@click="fnModalTest"
:loading="modalState.confirmLoading"
>
<template #icon><LinkOutlined /></template>
</a-button>
</a-form-item>
</a-form>
</ProModal>
</a-card>
</PageContainer>
</template>
+11 -12
View File
@@ -1,11 +1,10 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
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 { Form, Modal, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import { Form, Modal, message } from 'ant-design-vue/lib';
import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import {
@@ -180,7 +179,7 @@ function fnGetList(pageNum?: number) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -191,7 +190,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByEdit: false,
visibleByEdit: false,
title: '信息',
from: {
cmdId: undefined,
@@ -235,7 +234,7 @@ function fnModalVisibleByEdit(roleId?: string | number) {
if (!roleId) {
modalStateFrom.resetFields();
modalState.title = t('views.ne.neHostCmd.addTitle');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
if (modalState.confirmLoading) return;
const hide = message.loading(t('common.loading'), 0);
@@ -247,7 +246,7 @@ function fnModalVisibleByEdit(roleId?: string | number) {
if (res.code === RESULT_CODE_SUCCESS && res.data) {
modalState.from = Object.assign(modalState.from, res.data);
modalState.title = t('views.ne.neHostCmd.editTitle');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
message.error(t('common.getInfoFail'), 2);
}
@@ -298,7 +297,7 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalStateFrom.resetFields();
}
@@ -504,7 +503,7 @@ onMounted(() => {
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -516,7 +515,7 @@ onMounted(() => {
:label-col="{ span: 6 }"
:label-wrap="true"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHostCmd.cmdType')"
@@ -1,10 +1,10 @@
<script setup lang="ts">
import { reactive, toRaw, watch } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import { Form, Modal, Upload, message, notification } from 'ant-design-vue/es';
import { Form, Modal, Upload, message, notification } from 'ant-design-vue/lib';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { FileType, UploadFile } from 'ant-design-vue/es/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import { FileType, UploadFile } from 'ant-design-vue/lib/upload/interface';
import {
exportNeConfigBackup,
importNeConfigBackup,
@@ -12,11 +12,10 @@ import {
} from '@/api/ne/neConfigBackup';
import saveAs from 'file-saver';
import { uploadFile } from '@/api/tool/file';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
open: {
visible: {
type: Boolean,
default: false,
},
@@ -80,7 +79,7 @@ function typeChange(value: any) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -98,7 +97,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByEdit: false,
visibleByEdit: false,
title: '配置文件导入',
from: {
neType: '',
@@ -164,12 +163,12 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalState.confirmLoading = false;
modalStateFrom.resetFields();
modalState.uploadFiles = [];
emit('cancel');
emit('update:open', false);
emit('update:visible', false);
}
/**表单上传前删除 */
@@ -225,14 +224,14 @@ function fnUploadFile(up: UploadRequestOption) {
/**监听是否显示,初始数据 */
watch(
() => props.open,
() => props.visible,
val => {
if (val) {
if (props.neType && props.neId) {
modalState.from.neType = props.neType;
modalState.from.neId = props.neId;
modalState.title = t('views.ne.neInfo.backConf.title');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
}
}
}
@@ -284,14 +283,14 @@ defineExpose({
:width="800"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@cancel="fnModalCancel"
>
<a-form name="modalStateFrom" layout="horizontal" :label-col="{ span: 6 }">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.common.neType')" name="neType">
{{ modalState.from.neType }}
+27 -31
View File
@@ -1,19 +1,18 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, watch } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import { message, Form, Modal } from 'ant-design-vue/es';
import { message, Form, Modal } from 'ant-design-vue/lib';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { NE_TYPE_LIST } from '@/constants/ne-constants';
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
import { getNeInfo, addNeInfo, updateNeInfo } from '@/api/ne/neInfo';
import { neHostAuthorizedRSA, testNeHost } from '@/api/ne/neHost';
import useDictStore from '@/store/modules/dict';
import useI18n from '@/hooks/useI18n';
const { getDict } = useDictStore();
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
open: {
visible: {
type: Boolean,
default: false,
},
@@ -88,7 +87,7 @@ function fnHostAuthorized(row: Record<string, any>) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -99,7 +98,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByEdit: false,
visibleByEdit: false,
title: '网元',
from: {
id: undefined,
@@ -215,7 +214,7 @@ function fnModalVisibleByEdit(editId: string) {
if (!editId) {
modalStateFrom.resetFields();
modalState.title = t('views.ne.neInfo.addTitle');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
if (modalState.confirmLoading) return;
const hide = message.loading(t('common.loading'), 0);
@@ -226,7 +225,7 @@ function fnModalVisibleByEdit(editId: string) {
if (res.code === RESULT_CODE_SUCCESS) {
Object.assign(modalState.from, res.data);
modalState.title = t('views.ne.neInfo.editTitle');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
message.error(t('common.getInfoFail'), 2);
}
@@ -275,11 +274,11 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalState.confirmLoading = false;
modalStateFrom.resetFields();
emit('cancel');
emit('update:open', false);
emit('update:visible', false);
}
/**表单修改网元类型 */
@@ -342,7 +341,7 @@ function fnNeIPChange(e: any) {
/**监听是否显示,初始数据 */
watch(
() => props.open,
() => props.visible,
val => {
if (val) fnModalVisibleByEdit(props.editId);
}
@@ -373,10 +372,10 @@ onMounted(() => {
:drag="true"
:width="800"
:destroyOnClose="true"
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
:body-style="{ maxHeight: '650px', 'overflow-y': 'auto' }"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -388,7 +387,7 @@ onMounted(() => {
:label-col="{ span: 6 }"
:labelWrap="true"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.common.neType')"
@@ -410,7 +409,7 @@ onMounted(() => {
<template #title>
{{ t('views.ne.common.neTypeTip') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -438,7 +437,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.common.neId')"
@@ -457,7 +456,7 @@ onMounted(() => {
<template #title>
{{ t('views.ne.common.neIdTip') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -480,7 +479,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.common.ipAddr')"
@@ -501,7 +500,7 @@ onMounted(() => {
{{ t('views.ne.common.ipAddrTip') }}
</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -526,7 +525,7 @@ onMounted(() => {
<template #title>
<div>{{ t('views.ne.common.portTip') }}</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input-number>
@@ -554,13 +553,13 @@ onMounted(() => {
{{ t('views.ne.common.rmUidTip') }}
</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
</a-form-item>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.neInfo.neAddress')" name="neAddress">
<a-input
@@ -574,7 +573,7 @@ onMounted(() => {
<template #title>
<div>{{ t('views.ne.neInfo.neAddressTip') }}</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -592,7 +591,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neInfo.vendorName')"
@@ -650,7 +649,7 @@ onMounted(() => {
{{ `${host.hostType.toUpperCase()} ${host.port}` }}
</span>
</template>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.neHost.addr')">
<a-input
@@ -663,10 +662,7 @@ onMounted(() => {
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neHost.port')"
name="neHost.port"
>
<a-form-item :label="t('views.ne.neHost.port')" name="port">
<a-input-number
v-model:value="host.port"
:min="10"
@@ -694,7 +690,7 @@ onMounted(() => {
</a-input>
</a-form-item>
<a-row v-if="host.hostType === 'ssh'">
<a-row :gutter="16" v-if="host.hostType === 'ssh'">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.ne.neHost.user')">
<a-input
+14 -15
View File
@@ -1,14 +1,13 @@
<script setup lang="ts">
import { reactive, toRaw, watch } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import { message, Form } from 'ant-design-vue/es';
import { message, Form } from 'ant-design-vue/lib';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { getOAMFile, saveOAMFile } from '@/api/ne/neInfo';
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
open: {
visible: {
type: Boolean,
default: false,
},
@@ -26,7 +25,7 @@ const props = defineProps({
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**标题 */
title: string;
/**是否同步 */
@@ -39,7 +38,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByEdit: false,
visibleByEdit: false,
title: 'OAM Configuration',
sync: true,
from: {
@@ -88,7 +87,7 @@ function fnModalVisibleByTypeAndId(neType: string, neId: string) {
kpiTimer: data.kpiConfig.timer,
});
modalState.title = t('views.ne.neInfo.oam.title');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
message.error(res.msg, 3);
}
@@ -143,16 +142,16 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalState.confirmLoading = false;
modalStateFrom.resetFields();
emit('cancel');
emit('update:open', false);
emit('update:visible', false);
}
/**监听是否显示,初始数据 */
watch(
() => props.open,
() => props.visible,
val => {
if (val) {
if (props.neType && props.neId) {
@@ -167,10 +166,10 @@ watch(
<ProModal
:drag="true"
:destroyOnClose="true"
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
:body-style="{ maxHeight: '650px', 'overflow-y': 'auto' }"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -197,7 +196,7 @@ watch(
<a-collapse class="collapse" ghost>
<a-collapse-panel header="OAM">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neInfo.oam.oamEnable')"
@@ -240,7 +239,7 @@ watch(
</a-form-item>
</a-collapse-panel>
<a-collapse-panel header="SNMP">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neInfo.oam.snmpEnable')"
@@ -272,7 +271,7 @@ watch(
</a-row>
</a-collapse-panel>
<a-collapse-panel header="KPI">
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label="t('views.ne.neInfo.oam.kpiEnable')"
+1 -1
View File
@@ -1,5 +1,5 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { Modal, message } from 'ant-design-vue/es';
import { Modal, message } from 'ant-design-vue/lib';
import useI18n from '@/hooks/useI18n';
import { useRouter } from 'vue-router';
import { updateNeConfigReload } from '@/api/configManage/configParam';
+20 -20
View File
@@ -1,10 +1,10 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, defineAsyncComponent, ref } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { message, Modal } 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 { message, Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/lib/table';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeInfoStore from '@/store/modules/neinfo';
@@ -177,11 +177,11 @@ function fnTableSelectedRowKeys(keys: (string | number)[]) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**配置备份框是否显示 */
openByBackConf: boolean;
visibleByBackConf: boolean;
/**OAM文件配置框是否显示 */
openByOAM: boolean;
visibleByOAM: boolean;
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**新增框或修改框ID */
editId: string;
/**OAM框网元类型ID */
@@ -193,9 +193,9 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByBackConf: false,
openByOAM: false,
openByEdit: false,
visibleByBackConf: false,
visibleByOAM: false,
visibleByEdit: false,
editId: '',
neId: '',
neType: '',
@@ -212,7 +212,7 @@ function fnModalVisibleByEdit(row?: Record<string, any>) {
} else {
modalState.editId = row.id;
}
modalState.openByEdit = !modalState.openByEdit;
modalState.visibleByEdit = !modalState.visibleByEdit;
}
/**
@@ -256,9 +256,9 @@ function fnModalEditOk(from: Record<string, any>) {
*/
function fnModalEditCancel() {
modalState.editId = '';
modalState.openByEdit = false;
modalState.openByOAM = false;
modalState.openByBackConf = false;
modalState.visibleByEdit = false;
modalState.visibleByOAM = false;
modalState.visibleByBackConf = false;
}
/**
@@ -334,7 +334,7 @@ function fnRecordMore(type: string | number, row: Record<string, any>) {
case 'oam':
modalState.neId = row.neId;
modalState.neType = row.neType;
modalState.openByOAM = !modalState.openByOAM;
modalState.visibleByOAM = !modalState.visibleByOAM;
break;
case 'backConfExport':
backConf.value.exportConf(row.neType, row.neId);
@@ -342,7 +342,7 @@ function fnRecordMore(type: string | number, row: Record<string, any>) {
case 'backConfImport':
modalState.neId = row.neId;
modalState.neType = row.neType;
modalState.openByBackConf = !modalState.openByBackConf;
modalState.visibleByBackConf = !modalState.visibleByBackConf;
break;
default:
console.warn(type);
@@ -655,7 +655,7 @@ onMounted(() => {
</template>
</template>
<template #expandedRowRender="{ record }">
<a-row>
<a-row :gutter="16">
<a-col :offset="2" :lg="8" :md="8" :xs="8">
<a-divider orientation="left">
{{ t('views.ne.neInfo.info') }}
@@ -753,7 +753,7 @@ onMounted(() => {
<!-- 新增框或修改框 -->
<EditModal
v-model:open="modalState.openByEdit"
v-model:visible="modalState.visibleByEdit"
:edit-id="modalState.editId"
@ok="fnModalEditOk"
@cancel="fnModalEditCancel"
@@ -761,7 +761,7 @@ onMounted(() => {
<!-- OAM编辑框 -->
<OAMModal
v-model:open="modalState.openByOAM"
v-model:visible="modalState.visibleByOAM"
:ne-id="modalState.neId"
:ne-type="modalState.neType"
@cancel="fnModalEditCancel"
@@ -770,7 +770,7 @@ onMounted(() => {
<!-- 配置文件备份框 -->
<BackConfModal
ref="backConf"
v-model:open="modalState.openByBackConf"
v-model:visible="modalState.visibleByBackConf"
:ne-id="modalState.neId"
:ne-type="modalState.neType"
@cancel="fnModalEditCancel"
+14 -15
View File
@@ -1,7 +1,6 @@
<script setup lang="ts">
import { reactive, onMounted, toRaw, watch } from 'vue';
import { ProModal } from 'antdv-pro-modal';
import { Form, Modal, Upload, message } from 'ant-design-vue/es';
import { Form, Modal, Upload, message } from 'ant-design-vue/lib';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import {
@@ -9,16 +8,16 @@ import {
getNeLicense,
getNeLicenseByTypeAndID,
} from '@/api/ne/neLicense';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { FileType } from 'ant-design-vue/es/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import { FileType } from 'ant-design-vue/lib/upload/interface';
import { uploadFile } from '@/api/tool/file';
import { useClipboard } from '@vueuse/core';
import saveAs from 'file-saver';
const { copy } = useClipboard({ legacy: true });
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
open: {
visible: {
type: Boolean,
default: false,
},
@@ -46,7 +45,7 @@ const props = defineProps({
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**标题 */
title: string;
/**表单数据 */
@@ -67,7 +66,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByEdit: false,
visibleByEdit: false,
title: '授权文件',
from: {
id: '',
@@ -137,12 +136,12 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalState.confirmLoading = false;
modalStateFrom.resetFields();
modalState.uploadFiles = [];
emit('cancel');
emit('update:open', false);
emit('update:visible', false);
}
/**表单上传前检查或转换压缩 */
@@ -228,7 +227,7 @@ function fnModalVisibleById(id: string) {
modalState.from.licensePath = '';
modalState.from.reload = props.reload;
modalState.title = t('views.ne.neLicense.updateTtile');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
message.error(res.msg, 3);
}
@@ -253,7 +252,7 @@ function fnModalVisibleByTypeAndId(neType: string, neId: string) {
modalState.from.licensePath = '';
modalState.from.reload = props.reload;
modalState.title = t('views.ne.neLicense.updateTtile');
modalState.openByEdit = true;
modalState.visibleByEdit = true;
} else {
message.error(res.msg, 3);
}
@@ -266,7 +265,7 @@ function fnModalVisibleByTypeAndId(neType: string, neId: string) {
/**监听是否显示,初始数据 */
watch(
() => props.open,
() => props.visible,
val => {
if (val) {
if (props.editId) {
@@ -289,7 +288,7 @@ onMounted(() => {});
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:visible="modalState.visibleByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@@ -302,7 +301,7 @@ onMounted(() => {});
:label-col="{ span: 6 }"
:labelWrap="true"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item
:label-col="{ span: 12 }"
@@ -1,17 +1,16 @@
<script setup lang="ts">
import { reactive, onMounted, watch, PropType, h } from 'vue';
import { message, notification, Upload } from 'ant-design-vue/es';
import { message, notification, Upload } from 'ant-design-vue/lib';
import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { FileType } from 'ant-design-vue/es/upload/interface';
import { ProModal } from 'antdv-pro-modal';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import { FileType } from 'ant-design-vue/lib/upload/interface';
import { uploadFile } from '@/api/tool/file';
import { changeNeLicense } from '@/api/ne/neLicense';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const emit = defineEmits(['ok', 'cancel', 'update:open']);
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
const props = defineProps({
open: {
visible: {
type: Boolean,
default: false,
},
@@ -25,7 +24,7 @@ const props = defineProps({
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByUploadFile: boolean;
visibleByUploadFile: boolean;
/**标题 */
title: string;
/**授权文件路径 */
@@ -38,7 +37,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByUploadFile: false,
visibleByUploadFile: false,
licensePath: '',
uploadFiles: [],
title: '授权文件',
@@ -118,12 +117,12 @@ async function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByUploadFile = false;
modalState.visibleByUploadFile = false;
modalState.confirmLoading = false;
modalState.licensePath = '';
modalState.uploadFiles = [];
emit('cancel');
emit('update:open', false);
emit('update:visible', false);
}
/**表单上传前检查或转换压缩 */
@@ -173,11 +172,11 @@ function fnUploadFile(up: UploadRequestOption) {
/**监听是否显示,初始数据 */
watch(
() => props.open,
() => props.visible,
val => {
if (val) {
modalState.title = t('views.ne.neLicense.updateTtile');
modalState.openByUploadFile = true;
modalState.visibleByUploadFile = true;
}
}
);
@@ -191,7 +190,7 @@ onMounted(() => {});
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByUploadFile"
:visible="modalState.visibleByUploadFile"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
:cancel-button-props="{ disabled: modalState.confirmLoading }"
+16 -16
View File
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw, defineAsyncComponent } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { Modal, TableColumnsType, 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 { Modal, TableColumnsType, message } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import useNeInfoStore from '@/store/modules/neinfo';
import useI18n from '@/hooks/useI18n';
import useDictStore from '@/store/modules/dict';
@@ -208,7 +208,7 @@ function fnGetList(pageNum?: number) {
/**对话框对象信息状态类型 */
type ModalStateType = {
/**新增框或修改框是否显示 */
openByEdit: boolean;
visibleByEdit: boolean;
/**授权记录ID */
licenseId: string;
/**确定按钮 loading */
@@ -217,7 +217,7 @@ type ModalStateType = {
/**对话框对象信息状态 */
let modalState: ModalStateType = reactive({
openByEdit: false,
visibleByEdit: false,
licenseId: '',
confirmLoading: false,
});
@@ -228,7 +228,7 @@ let modalState: ModalStateType = reactive({
*/
function fnModalVisibleByEdit(licenseId: string) {
modalState.licenseId = licenseId;
modalState.openByEdit = true;
modalState.visibleByEdit = true;
}
/**
@@ -245,7 +245,7 @@ function fnModalOk() {
* 进行表达规则校验
*/
function fnModalCancel() {
modalState.openByEdit = false;
modalState.visibleByEdit = false;
modalState.licenseId = '';
}
@@ -413,7 +413,7 @@ onMounted(() => {
:loading="modalState.confirmLoading"
@click.prevent="fnRecordStateBatch()"
>
<template #icon><CloudSyncOutlined /></template>
<template #icon><SecurityScanOutlined /></template>
{{ t('views.ne.neLicense.reloadBatch') }}
</a-button>
</a-space>
@@ -505,19 +505,19 @@ onMounted(() => {
</template>
<template v-if="column.key === 'id'">
<a-space :size="8" align="center">
<a-tooltip placement="topRight">
<template #title>{{ t('views.ne.neLicense.reload') }}</template>
<a-button type="link" @click.prevent="fnRecordState(record)">
<template #icon><CloudSyncOutlined /> </template>
</a-button>
</a-tooltip>
<a-tooltip placement="topRight">
<template #title>{{ t('views.ne.neLicense.change') }}</template>
<a-button
type="link"
@click.prevent="fnModalVisibleByEdit(record.id)"
>
<template #icon><CloudUploadOutlined /> </template>
<template #icon><InteractionOutlined /> </template>
</a-button>
</a-tooltip>
<a-tooltip placement="topRight">
<template #title>{{ t('views.ne.neLicense.reload') }}</template>
<a-button type="link" @click.prevent="fnRecordState(record)">
<template #icon><SecurityScanOutlined /> </template>
</a-button>
</a-tooltip>
</a-space>
@@ -528,7 +528,7 @@ onMounted(() => {
<!-- 文件上传框 -->
<EditModal
v-model:open="modalState.openByEdit"
v-model:visible="modalState.visibleByEdit"
:edit-id="modalState.licenseId"
@ok="fnModalOk"
@cancel="fnModalCancel"
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { Form, Modal, message } from 'ant-design-vue/es';
import { Form, Modal, message } from 'ant-design-vue/lib';
import { onMounted, reactive, toRaw } from 'vue';
import { addNeInfo, getNeInfoByTypeAndID, updateNeInfo } from '@/api/ne/neInfo';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
@@ -344,7 +344,7 @@ onMounted(() => {
:label-col="{ span: 6 }"
:labelWrap="true"
>
<a-row>
<a-row :gutter="16">
<a-col :lg="6" :md="6" :xs="24" :offset="6">
<a-form-item
:label="t('views.ne.common.neType')"
@@ -368,7 +368,7 @@ onMounted(() => {
<template #title>
{{ t('views.ne.common.neTypeTip') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit;" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -392,7 +392,7 @@ onMounted(() => {
<template #title>
{{ t('views.ne.common.neIdTip') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit;" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -400,7 +400,7 @@ onMounted(() => {
</a-col>
</a-row>
<a-row>
<a-row :gutter="16">
<a-col :lg="6" :md="6" :xs="24" :offset="6">
<a-form-item
:label="t('views.ne.common.ipAddr')"
@@ -422,7 +422,7 @@ onMounted(() => {
{{ t('views.ne.common.ipAddrTip') }}
</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit;" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input>
@@ -447,7 +447,7 @@ onMounted(() => {
<template #title>
<div>{{ t('views.ne.common.portTip') }}</div>
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit;" />
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
</a-tooltip>
</template>
</a-input-number>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { Modal, message } from 'ant-design-vue/es';
import { Modal, message } from 'ant-design-vue/lib';
import { defineAsyncComponent, onMounted, reactive, toRaw } from 'vue';
import { fnToStepName, stepState } from '../hooks/useStep';
import useI18n from '@/hooks/useI18n';
@@ -10,7 +10,7 @@ import {
} from '@/constants/result-constants';
import { listNeSoftware, newNeVersion } from '@/api/ne/neSoftware';
import { parseDateToStr } from '@/utils/date-utils';
import { ColumnsType } from 'ant-design-vue/es/table';
import { ColumnsType } from 'ant-design-vue/lib/table';
const { t } = useI18n();
const EditModal = defineAsyncComponent(
() => import('../../../ne/neSoftware/components/EditModal.vue')
@@ -152,7 +152,7 @@ type StateType = {
/**文件操作类型 上传 or 选择 */
optionType: 'upload' | 'option';
/**文件上传 */
openByFile: boolean;
visibleByFile: boolean;
/**网元拓展包列表类型 */
depType: string[];
/**软件包信息数据 */
@@ -172,7 +172,7 @@ type StateType = {
let state: StateType = reactive({
stepNext: false,
optionType: 'option',
openByFile: false,
visibleByFile: false,
depType: [],
from: {
id: undefined,
@@ -200,7 +200,7 @@ function fnOptionTypeChange() {
/**对话框弹出 */
function fnModalOpen() {
state.openByFile = !state.openByFile;
state.visibleByFile = !state.visibleByFile;
}
/**对话框弹出确认执行函数*/
@@ -210,7 +210,7 @@ function fnModalOk(e: any) {
/**对话框弹出关闭执行函数*/
function fnModalCancel() {
state.openByFile = false;
state.visibleByFile = false;
}
/**版本安装 */
@@ -382,7 +382,7 @@ onMounted(() => {
<!-- 文件上传框 -->
<EditModal
v-model:open="state.openByFile"
v-model:visible="state.visibleByFile"
@ok="fnModalOk"
@cancel="fnModalCancel"
></EditModal>
Loaded 100 of 172 files, more files were not shown because too many files have changed in this diff. Show more