579 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
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
TsMask
c1187383b6 fix: 系统引导跳转不重复引导 2024-08-03 10:09:16 +08:00
lai
8d8605e0cd 调整网元配置模块 2024-08-02 18:55:53 +08:00
TsMask
8af48936e5 chore: 更新版本号 2.240801 2024-08-02 10:11:42 +08:00
TsMask
e21a8dc898 perf: 优化快速安装配置公共参数页面 2024-08-01 17:34:16 +08:00
TsMask
3c1ee63359 fix: 开站网元安装信息保存触发操作不一致 2024-07-30 18:23:51 +08:00
TsMask
bc3940016a perf: 网元公共参数合并到网元快速安装,移除相关多语言翻译 2024-07-30 18:22:32 +08:00
TsMask
6ab4fbea6f fix: UDM签约数据cnType改5GC Flag 2024-07-30 11:27:12 +08:00
TsMask
c73fcbd91c chore: 更新版本号 2.240729 2024-07-29 18:27:15 +08:00
TsMask
023e317b0d feat: 网元配置备份操作权限控制删除/编辑按钮 2024-07-29 14:36:19 +08:00
lai
543a2b7434 新增 统一配置网元 2024-07-29 10:38:14 +08:00
TsMask
4ae9051411 style: 系统设置LOGO和文档判断是否开启语言切换显示控件 2024-07-27 15:01:56 +08:00
TsMask
532546c3f5 chore: 更新版本号 2.240727 2024-07-27 10:28:23 +08:00
TsMask
ab0d26513c perf: 网元备份导入导出弹窗表单重构 2024-07-26 18:27:15 +08:00
TsMask
8e9498ec83 feat: 网元备份文件表格页面 2024-07-26 18:25:15 +08:00
TsMask
ca048f223c feat: UDM鉴权文件导入K4文件支持 2024-07-26 15:28:45 +08:00
TsMask
e9ff6493dd fix: 看板UPF流量吞吐初始查询和ws监听12_neId 2024-07-25 18:48:01 +08:00
TsMask
396fb0b124 fix: KPI接收指定对应neId,实时数据不支持搜索 2024-07-25 18:23:28 +08:00
TsMask
3a854be8fe fix: 查询IMS在线用户数接口数据格式兼容 2024-07-25 10:50:54 +08:00
TsMask
c1f34f56ac fix: 对使用手册,官网进行限制 2024-07-24 18:10:38 +08:00
lai
b80bae0126 Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-07-24 17:18:18 +08:00
lai
6c383b58c8 对使用手册,官网进行限制 2024-07-24 17:18:15 +08:00
TsMask
06db1344c3 fix: 日志事件cm结果多语言显示错误 2024-07-23 14:48:53 +08:00
TsMask
fac47279b5 fix: 日志IMS-CDR类型查询默认空进行全查询,表格宽度增加 2024-07-23 14:26:09 +08:00
TsMask
a36a12f783 fix: 日志事件类型查询默认空进行全查询 2024-07-23 14:25:08 +08:00
TsMask
acd19ebdbd style: 看板基站数量分开展示避免分不清数 2024-07-19 14:41:40 +08:00
TsMask
d53c4c34f0 style: 新增网元信息时ssh默认密码初始 2024-07-18 15:44:35 +08:00
TsMask
2d9011cf6b fix: 看板资源图无网元状体数据取值异常 2024-07-17 18:11:22 +08:00
TsMask
fcf53d0995 fix: 网元删除记录自动移除不要刷新列表 2024-07-17 18:06:59 +08:00
TsMask
a2d93ddafe fix: 系统名称横向滚动衔接动画 2024-07-16 11:21:16 +08:00
TsMask
79920542c1 chore: 更新版本号240712 2024-07-12 21:23:12 +08:00
TsMask
6efd9cb61a fix: 根据浏览器地址栏hostname加33030端口连接后端服务 2024-07-11 17:56:24 +08:00
TsMask
4dc6699974 style: UDM用户数据限制imsi长度输入 2024-07-11 15:02:53 +08:00
TsMask
3bdae264e1 fix: 网元信息单行更新局部信息变更失效 2024-07-10 15:47:28 +08:00
TsMask
9e0a99d160 style: 数据CDR的表头宽度调整 2024-07-09 19:02:54 +08:00
TsMask
5ac0ca41eb style: 签约用户IMSI编辑时禁止修改,cnType添加提示 2024-07-09 18:36:27 +08:00
TsMask
a7de701d4d fix: 支持kvdb依赖包安装,db_ip默认0.0.0.0 2024-07-09 16:11:58 +08:00
TsMask
f0561242ca fix: fetch请求拼接地址栏参数不区分请求方法 2024-07-09 10:04:46 +08:00
TsMask
6102972373 fix: 网元公共配置OMC的IP去除覆盖 2024-07-05 14:42:45 +08:00
TsMask
d095531952 style: 系统角色分配标题多语言翻译 2024-07-04 17:02:33 +08:00
TsMask
d49dc9ebfd chore: 更新版本号240704 2024-07-04 10:24:01 +08:00
TsMask
43a99e9328 fix: 系统管理员角色用system表示避免admin混用 2024-07-03 15:13:41 +08:00
TsMask
d333221620 style: 在线用户列表文字靠左对齐 2024-07-03 14:50:25 +08:00
TsMask
481734cfe1 fix: 看板MME资源内存溢出100% 2024-07-03 14:49:11 +08:00
TsMask
1fa8601675 fix: UDM Object下拉数据显示错误 2024-07-01 16:02:12 +08:00
TsMask
c1aabdbe42 fix: 网元信息新增时刷新列表,编辑时局部更新信息 2024-06-28 14:55:40 +08:00
TsMask
953a36f142 style: 网元软件上传按钮文本多语言处理 2024-06-28 12:01:07 +08:00
TsMask
c5f62e8d76 fix: 网元信息新增OMC配置应该没有telnet 2024-06-28 11:11:41 +08:00
TsMask
946139facb fix: 用户无操作一段时间后进行锁屏 2024-06-27 20:46:58 +08:00
TsMask
95931b2b6e fix: 用户无操作一段时间后进行锁屏 2024-06-27 20:45:26 +08:00
TsMask
e31c85835d chore: 更新版本号240627 2024-06-27 18:32:02 +08:00
TsMask
847bae4c77 fix: SMF UE在线信息兼容旧数据 2024-06-27 18:31:22 +08:00
TsMask
e69f43a0c2 style: SMFCDR多语言smfSubscriptionID订阅 ID 2024-06-27 18:02:16 +08:00
TsMask
d96e1ad259 fix: SMF UE在线信息固定翻页50条 2024-06-27 17:28:23 +08:00
TsMask
3829d339e7 fix: SMF UE在线信息固定翻页50条 2024-06-27 17:10:30 +08:00
TsMask
cd4073bec3 fix: 网元主机信息默认填写固定用户名 2024-06-27 14:59:45 +08:00
TsMask
e67126c57a style: 调整SMFCDR输入框lg:6 2024-06-27 14:58:41 +08:00
TsMask
2f651b5d1f style: 快速开站系统admin密码默认Abcd@1234.. 2024-06-26 21:09:30 +08:00
TsMask
525854604f fix: 网元信息新增OMC配置应该没有telnet 2024-06-26 16:48:46 +08:00
TsMask
d42a8701da style: 参数配置规则校验示例写法 2024-06-26 16:47:45 +08:00
TsMask
2b680d6d20 fix: 参数配置可选项按id升序 2024-06-26 11:59:00 +08:00
TsMask
de79760a0e chore: 更新版本号240626 2024-06-26 10:50:19 +08:00
TsMask
a5b5269b91 chore: 更新依赖版本 2024-06-26 10:45:06 +08:00
TsMask
8a2d0ccfa1 style: 调整网元软件批量上传框标题统一为上传软件 2024-06-26 10:44:32 +08:00
TsMask
650b02dc30 style: 调整网元软件单上传框宽度650 2024-06-26 10:43:50 +08:00
TsMask
b42d8cb370 style: 多语言翻译网元版本Update Softwares改成Batch Upload 2024-06-26 10:43:12 +08:00
TsMask
a213be0d64 fix: 网元软件多文件上传文件删除副本记录 2024-06-25 17:54:50 +08:00
TsMask
2a2b441e09 fix: 系统重置框倒计时无变化 2024-06-25 17:53:45 +08:00
TsMask
84bdb44286 fix: 网元操作接口超时时间60s 2024-06-25 15:37:58 +08:00
TsMask
06b6175a76 fix: 用户管理刷新不应重置页数1 2024-06-24 17:11:49 +08:00
TsMask
11b790e140 fix: 告警帮助文档高度调整88vh 2024-06-24 10:12:32 +08:00
TsMask
296a9ba02b feat: UDM签约数据添加CN Type可选类型 2024-06-21 20:49:34 +08:00
TsMask
1801a46396 style:: 操作日志多语言变更 2024-06-20 14:45:33 +08:00
TsMask
f6644a0d97 style: 全局配置消息距离顶部的位置 2024-06-20 14:41:02 +08:00
TsMask
57f575aa84 fix: 用户账号规则修改允许数字开头至少6位 2024-06-20 10:16:04 +08:00
TsMask
68cbbe7133 chore: 更新版本号240619 2024-06-19 17:58:17 +08:00
TsMask
c11d814312 fix: 模态框的footer底部按钮null会显示的处理 2024-06-19 17:29:59 +08:00
TsMask
e1548d2c98 fix: UE事件MME 看板推送显示/类型结果保持和AMF一致 2024-06-19 16:57:07 +08:00
TsMask
1ec374eb26 style: UE在线数据临时模拟数据 2024-06-19 16:55:02 +08:00
TsMask
0955a79965 style: 移除无用console输出 2024-06-19 14:51:28 +08:00
TsMask
374a9bde7e fix: 用户管理不能改自己状态,权限控制分配岗位 2024-06-19 14:02:24 +08:00
TsMask
639a4f0b1f feat: 用户数据保存userId信息做判断 2024-06-19 12:03:02 +08:00
TsMask
d1b9d7b9ba style: 网元公共参数同步窗口最小高度不设置 2024-06-19 12:01:10 +08:00
TsMask
3298203f60 fix: 用户部门默认选取自身拥有的 2024-06-18 19:12:44 +08:00
TsMask
8f3cce52c0 fix: UDM鉴权重载提示不关闭 2024-06-18 15:41:47 +08:00
TsMask
ce06a88e89 fix: 主页饼图颜色显示问题 2024-06-18 14:30:53 +08:00
TsMask
749a04972d style: UDM签约用户编辑框top0 2024-06-18 11:01:17 +08:00
TsMask
a311f0a09b fix: 移除拖拽组件,全局注册ProModal替换默认AModal 2024-06-18 10:26:38 +08:00
TsMask
c74d311537 chore: 升级依赖库 2024-06-18 10:24:12 +08:00
TsMask
1492f18791 style: 字典类型数据结构体变更 2024-06-18 10:23:09 +08:00
TsMask
cbc81643a5 chore: 更新版本号240617 2024-06-17 17:43:37 +08:00
TsMask
c18b557c97 fix: mocn页面引用函数异常导致编译错误 2024-06-17 17:42:48 +08:00
TsMask
b6bd9bc3d5 fix: 角色编辑修改框销毁后新建避免菜单勾选失败 2024-06-17 17:03:12 +08:00
TsMask
199607e322 style: 告警网元类型下拉自动提示输入 2024-06-17 11:35:11 +08:00
TsMask
ee10119d77 feat: 看板用户行为添加MME的UE事件 2024-06-17 11:21:44 +08:00
TsMask
1b1a56e49b feat: MME用户事件日志页面功能实现 2024-06-15 18:41:39 +08:00
TsMask
afdc188e17 fix: 调整tcpdump接口 2024-06-15 14:47:53 +08:00
TsMask
5de7d0a73f fix: 调整WS数据通道类型指定 2024-06-15 14:29:38 +08:00
TsMask
8f73d80a42 chore: 更新版本号240615 2024-06-15 10:41:01 +08:00
TsMask
5a85f245b0 style: 系统名称超出范围进行滚动 2024-06-15 10:37:55 +08:00
TsMask
ff600c49f6 chore: 编译类型错误提示 2024-06-14 19:00:38 +08:00
TsMask
4c7e99fdd7 fix: 引用UDM数据列表接口错误 2024-06-14 18:58:45 +08:00
TsMask
a6037a9737 del: 移除旧的UDM用户数据接口 2024-06-14 17:22:45 +08:00
TsMask
1d55c092b1 feat: UDM用户数据接口调整,页面优化加载等待 2024-06-14 17:02:33 +08:00
TsMask
8bdfd7ea28 style: 终端telnet编辑窗口单行120个字符 2024-06-14 16:46:51 +08:00
TsMask
39ad75fbd3 style: 多语言锁屏输入提示enUs 2024-06-14 14:33:29 +08:00
TsMask
7ef775209d fix: 网元信息更新记录显示状态变更,不刷新列表 2024-06-13 14:36:07 +08:00
TsMask
a8e0f36562 fix: UDM签约数据Template输入长度16改为50 2024-06-12 14:42:16 +08:00
TsMask
be50fc9c5c style: 代码格式化 2024-06-12 14:36:16 +08:00
TsMask
375f236e32 feat: 重构锁屏功能 2024-06-12 14:35:07 +08:00
TsMask
c9eb0240d8 fix: 网元信息更新删除不刷新列表,进行单个更新并清除网元列表缓存 2024-06-12 10:16:35 +08:00
TsMask
b67d591d0a feat: 锁屏页面 2024-06-11 18:31:26 +08:00
TsMask
7275a87fba style: CDR页面多语言处理 2024-06-11 18:30:53 +08:00
TsMask
c103222b65 fix: 轻量化upf不需要配置pci和mac 2024-06-11 17:00:34 +08:00
TsMask
5133d09ec2 feat: SMF CDR数据列表展示和导出,未进行多语言处理 2024-06-11 16:23:57 +08:00
TsMask
d88cec34df chore: 更新版本号240611 2024-06-11 10:29:24 +08:00
TsMask
eadd4709ee fix: 开站网元信息无终端配置时不显示,没有则新建个默认的占位 2024-06-11 10:28:16 +08:00
TsMask
04cbdc6b11 fix: 网元信息多选删除id取值异常 2024-06-11 10:26:46 +08:00
TsMask
233496e184 feat: 网元数据CDR支持导出功能 2024-06-07 19:50:02 +08:00
TsMask
919f8ef2a5 Merge remote-tracking branch 'origin/main' into lichang 2024-06-07 10:35:40 +08:00
lai
8f8d056f45 smf cdr 2024-06-06 22:28:46 +08:00
lai
8fcd7974e4 与smf协商后 暂且不进行中英文翻译 2024-06-06 22:28:03 +08:00
TsMask
cb7fc418a5 fix: 网元版本OMC安装遮罩和提示多语言 2024-06-06 15:13:45 +08:00
TsMask
e6d4a898a8 fix: 开站系统logo类型选择回显 2024-06-06 14:34:34 +08:00
TsMask
be4fc896d7 style: 网元公共参数EMS->OMC 2024-06-06 11:51:49 +08:00
TsMask
e5a5ef6f96 style: 多语言-部门状态 2024-06-05 17:00:24 +08:00
TsMask
530662bf5d fix: 开站网元授权文件变更成功提示 2024-06-03 11:57:35 +08:00
TsMask
2e7514d3ca feat: 全局布局组件升级到3.3.5 2024-06-03 11:42:42 +08:00
TsMask
1db61a5d4e chore: 更新依赖版本 2024-06-03 11:41:04 +08:00
TsMask
618499e777 style: 网元公共参数EMS_IP标记必填红 2024-06-01 16:18:50 +08:00
TsMask
71c0306587 fix: 文件切片操作超时时间统一60s 2024-06-01 15:11:46 +08:00
TsMask
a3cd8f05fb style: 编译类型声明 2024-05-31 19:17:54 +08:00
TsMask
d8ca0ca5ef feat: 网元安装IMS预输入mf包参数 2024-05-31 19:06:42 +08:00
TsMask
da08e1cc5b style: 开战公共参数保存提示成功 2024-05-31 17:36:09 +08:00
TsMask
8e4c5d0b90 feat: 网元信息配置文件导入导出 2024-05-31 15:08:55 +08:00
TsMask
467c93f710 fix: 锁屏重启检查404时重试 2024-05-31 11:05:03 +08:00
TsMask
22ced8bdb2 fix: 网元公共参数初始数据组件回填,adb绑定0.00.0 2024-05-30 21:20:10 +08:00
TsMask
2ee26a6958 Merge remote-tracking branch 'origin/main' into lichang 2024-05-30 18:07:52 +08:00
TsMask
c63e892544 style: 系统操作日志去除请求方法列 2024-05-30 18:00:50 +08:00
TsMask
cce3088f73 Merge remote-tracking branch 'origin/main' into lichang 2024-05-30 17:55:22 +08:00
TsMask
2211896768 Merge remote-tracking branch 'origin/main' into lichang 2024-05-30 17:53:51 +08:00
TsMask
5bb3cd814c fix: 网元参数配置属性监听异常 2024-05-30 17:53:26 +08:00
lai
266d816a21 修改文件默认名 2024-05-30 17:49:39 +08:00
TsMask
90c64c029a Merge remote-tracking branch 'origin/main' into lichang 2024-05-30 17:29:45 +08:00
TsMask
d06e2da72e chore: 更新版本240530 2024-05-30 17:23:49 +08:00
TsMask
7714d506c4 feat: 网元参数配置smf选择upfId 2024-05-30 17:08:55 +08:00
lai
0b7a198235 Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-05-30 15:44:41 +08:00
TsMask
68362ba3e3 feat: 网元参数配置可收起左侧菜单 2024-05-30 15:41:17 +08:00
lai
a9633e652f Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-05-30 15:34:27 +08:00
TsMask
6592561bca style: 参数校验多语言翻译 2024-05-30 15:32:42 +08:00
lai
09e0353053 增加事件告警 2024-05-30 15:25:08 +08:00
lai
c1e95fd1e9 仪表盘去除事件告警 2024-05-30 14:49:45 +08:00
TsMask
89857e0c1b style: 开站页面样式居中 2024-05-30 11:38:36 +08:00
TsMask
7aa37ee330 chore: 更新版本号240530 2024-05-30 11:00:57 +08:00
TsMask
4c16888184 fix: 网元快速安装授权检查是否可用后在进行文件上传 2024-05-29 18:06:26 +08:00
TsMask
a61716d40d feat: 网元公共参数配置表单组件 2024-05-29 16:32:11 +08:00
TsMask
3f02cb628b feat: 网元软件包支持携带依赖进行记录 2024-05-28 15:31:41 +08:00
TsMask
22805924fb fix: 网元软件多上传同开站逻辑 2024-05-28 15:29:45 +08:00
TsMask
e00229e5ff revt: 回退网元软件包类型支持adb,mf,rtproxy 2024-05-27 18:49:41 +08:00
TsMask
939a235a87 style: 网元软件代码优化 2024-05-27 18:33:46 +08:00
TsMask
cd49162dfc fix: 网元安装去除默认agtuser输入 2024-05-27 18:31:33 +08:00
TsMask
b7f2df5d1c fix: 网元版本升级勾选逐个进行,多语言翻译 2024-05-27 18:28:15 +08:00
TsMask
8b24bc55b9 fix: 网元授权上传进行重启网元 2024-05-27 17:09:39 +08:00
TsMask
9f2b80718e fix: 网元软件包类型支持adb,mf,rtproxy 2024-05-27 17:08:56 +08:00
TsMask
38cb406687 chore: 更新版本号240524 2024-05-24 20:54:55 +08:00
TsMask
c25fe63a26 style: 开站安装关闭按钮禁用 2024-05-24 20:54:37 +08:00
TsMask
b84d6bb9fc fix: 开站网元信息删除无id触发undefined 2024-05-24 17:54:39 +08:00
TsMask
b325cde5c0 fix: 国际化切换选择控件根据配置隐藏 2024-05-24 17:53:36 +08:00
TsMask
34266da44e style: 移除无效引用 2024-05-24 17:42:28 +08:00
TsMask
d82d6b7b47 fix: 网元授权勾选重置 2024-05-24 17:41:47 +08:00
TsMask
b1c7a068cf perf: 网元授权勾选多上传更新 2024-05-24 17:41:08 +08:00
TsMask
c155160cf7 style: 开站网元安装多语言翻译 2024-05-24 16:21:44 +08:00
TsMask
2ae4559958 fix: 开站软件安装逐个进行避免dpkg look错误 2024-05-24 16:21:08 +08:00
TsMask
782283bba6 pref: 网元软件多上传选择弹窗组件 2024-05-24 16:19:53 +08:00
TsMask
1b50708786 fix: 移除无用loding和危险操作高亮红色 2024-05-24 16:18:52 +08:00
TsMask
206d3755a0 fix: 网元公共参数设置omcIP进行更新 2024-05-24 16:15:09 +08:00
TsMask
6470effbda style: 网元相关页面多语言翻译 2024-05-24 09:41:56 +08:00
TsMask
f94b1ef44a style: 快速开站多语言翻译 2024-05-24 09:41:20 +08:00
TsMask
7c78eab431 style: 快速开站多语言翻译 2024-05-21 17:10:45 +08:00
TsMask
814b7b0058 feat: 网元快速安装多语言翻译 2024-05-20 20:18:00 +08:00
TsMask
624f67ecca feat: 网元公共配置多语言翻译 2024-05-20 16:20:58 +08:00
TsMask
c1a9497b77 feat: 网元信息表单多语言翻译 2024-05-20 16:10:13 +08:00
TsMask
1ad2ed2d26 feat: 网元信息表单多语言翻译 2024-05-20 15:14:23 +08:00
TsMask
48f278997f feat: 网元信息OAM多语言翻译 2024-05-20 11:58:25 +08:00
TsMask
9b9d6222e1 feat: 网元信息多语言翻译 2024-05-20 10:56:55 +08:00
TsMask
2e8a878365 Merge remote-tracking branch 'origin/main' into lichang 2024-05-17 20:23:52 +08:00
TsMask
bc59dc67e6 style: IMS用户话单表格宽度 2024-05-17 18:15:16 +08:00
TsMask
df6022b4a8 Merge remote-tracking branch 'origin/main' into lichang 2024-05-17 18:11:53 +08:00
TsMask
f2c67d087b chore: 更新版本240517 2024-05-17 18:02:22 +08:00
TsMask
7a0298a419 feat: IMS用户话单支持号码查询 2024-05-17 18:00:56 +08:00
TsMask
b40e798090 feat: AMF用户事件支持IMSI查询 2024-05-17 18:00:28 +08:00
TsMask
d48d5d6c95 feat: 网元软件多语言翻译 2024-05-17 17:14:14 +08:00
TsMask
69f3347a4d feat: 网元版本多语言翻译 2024-05-17 16:04:44 +08:00
TsMask
85ae7dc5ea fix: 网元授权多语言翻译 2024-05-17 15:18:01 +08:00
TsMask
531cd6d03d fix: 开站网元信息telnet不显示 2024-05-17 11:32:30 +08:00
TsMask
9fd8c4597a fix: 开站网元信息telnet默认值 2024-05-17 11:06:19 +08:00
TsMask
7060a3d887 fix: 网元授权文件变更提供重启功能,排除OMC类型 2024-05-17 11:04:59 +08:00
TsMask
c12ffa583c fix: 开站时网元主机可不填备注 2024-05-16 19:21:06 +08:00
TsMask
05aabb8c61 chore: 更新版本号240516 2024-05-16 14:46:59 +08:00
TsMask
6b461ead7c fix: 网元信息编辑添加备注输入 2024-05-16 14:43:51 +08:00
TsMask
7c54e372e5 feat: 开站网元授权状态标签字典 2024-05-16 14:43:18 +08:00
TsMask
5be95a7af6 feat: 网元版本状态标签字典 2024-05-16 14:42:10 +08:00
TsMask
08515541b4 style: 网元公共参数配置初始值 2024-05-16 10:00:50 +08:00
TsMask
3948924f61 del: 删除旧系统页面 2024-05-15 19:21:49 +08:00
TsMask
ce1944881a style: 隐藏IP地址区域信息 2024-05-15 19:21:24 +08:00
lai
f6122c0758 调整为活动告警 2024-05-15 14:44:35 +08:00
lai
3d3f4c2cc6 看板微调 2024-05-15 14:43:07 +08:00
TsMask
e8e5b92a57 Merge remote-tracking branch 'origin/main' into lichang 2024-05-14 19:14:13 +08:00
TsMask
4ad704398d fix: 网元授权安装结果遍历message提示 2024-05-14 19:13:58 +08:00
TsMask
26289b7787 fix: 文件上传接口超时60s 2024-05-14 19:13:21 +08:00
TsMask
7ad8c1706e fix: 网元OAM端口输入限制5 2024-05-14 19:12:54 +08:00
TsMask
424a596613 fix: 看板定时器初始化前清除后设置 2024-05-14 19:12:16 +08:00
TsMask
6d5b9f417c fix: 网元特定排序添加SMSC 2024-05-14 17:24:50 +08:00
TsMask
7278e24dce Merge remote-tracking branch 'origin/main' into lichang 2024-05-14 15:02:11 +08:00
TsMask
76839ae18a fix: 系统重置操作等待遮罩 2024-05-14 15:01:30 +08:00
TsMask
c8a6aa3210 feat: 锁屏遮罩添加系统重置等待 2024-05-14 14:58:35 +08:00
TsMask
9b4bbcedc5 fix: 黄金指标图表项数据切换重复累积问题 2024-05-14 14:47:09 +08:00
TsMask
3b793c107c style: 角色键值输入提示变更多语言 2024-05-14 12:01:23 +08:00
lai
a076e6d079 疑似{}引发的问题 2024-05-14 10:02:43 +08:00
TsMask
fb2a7c51f9 Merge remote-tracking branch 'origin/main' into lichang 2024-05-13 09:41:19 +08:00
TsMask
1e2c2b5170 fix: 拓扑信息首个非OMC的异常显示问题 2024-05-11 18:03:49 +08:00
lai
56833b654e 更改提示语 2024-05-11 16:59:40 +08:00
lai
f50e02e6e7 为dnn,st添加星号 2024-05-11 16:58:22 +08:00
TsMask
52cc24813f Merge remote-tracking branch 'origin/main' into lichang 2024-05-11 16:42:13 +08:00
TsMask
c8a0d4c3f7 fix: 网元主机ssh私钥长度3000限制 2024-05-11 16:41:51 +08:00
TsMask
7560f21f11 style: 注释修改 2024-05-11 10:45:34 +08:00
TsMask
8a5f80fe47 feat: 网元配置OAM弹窗表单 2024-05-11 10:45:13 +08:00
TsMask
29eb1f08b1 del: 移除旧的参数配置页面 2024-05-10 14:54:36 +08:00
TsMask
9981de2271 del: 移除旧在线会话页面 2024-05-10 14:49:37 +08:00
TsMask
207acb3f3d fix: 网元信息IP地址输入校验 2024-05-10 14:43:57 +08:00
TsMask
873a76f48f fix: 开站排除omc类型选择 2024-05-10 14:42:26 +08:00
TsMask
4ca700092a fix: 登录后重定向页面 2024-05-10 14:19:30 +08:00
TsMask
ad9f8574bd del: 移除网元无用接口 2024-05-10 10:17:11 +08:00
TsMask
75faae6d7c Merge remote-tracking branch 'origin/main' into lichang 2024-05-09 19:26:20 +08:00
TsMask
c88c146a5e style: 网元版本页面多语言翻译 2024-05-09 19:25:14 +08:00
TsMask
c65cda1468 fix: 网元快速安装页面初始表单简化 2024-05-09 19:24:51 +08:00
TsMask
d8059341fe fix: 网元公共参数配置页面补充mme_ip 2024-05-09 19:22:03 +08:00
TsMask
ad86bee5f9 fix: 开站页面同步公共参数配置,优化页面样式 2024-05-09 19:18:21 +08:00
TsMask
f44cc44a1b style: 网元类型列表排序 2024-05-09 18:29:08 +08:00
TsMask
ad93588796 fix: 参数配置方法权限控制post,put,delete 2024-05-09 18:27:32 +08:00
TsMask
b5f6a5d24a feat: 网元公共参数配置数据名称调整 2024-05-09 15:54:48 +08:00
TsMask
fa4be253f7 fix: 系统配置重置操作多语言翻译 2024-05-08 16:09:39 +08:00
TsMask
2db0220c98 chore: 更新版本240508 2024-05-08 11:35:52 +08:00
TsMask
05fd678ce2 fix: SMF在线用户模拟数据变更/RAT Type文字换行 2024-05-08 11:35:33 +08:00
TsMask
165b28bab1 style: 开站页面样式调整 2024-05-08 11:05:35 +08:00
TsMask
dc67cdc262 fix: 看站系统配置新增管理员账号变更 2024-05-08 11:04:17 +08:00
TsMask
c97394a0ed fix: 看站完成确认提示 2024-05-08 11:03:03 +08:00
TsMask
6b9297d30e style: 看站开始页面样式调整 2024-05-08 11:02:30 +08:00
TsMask
ace7f26b53 style: 引导接口函数变更 2024-05-08 11:01:11 +08:00
TsMask
976f72f79a fix: 网元授权接口变更字段属性调整 2024-05-07 18:39:56 +08:00
TsMask
530e7fd43f feat: 系统引导重置操作 2024-05-07 16:28:10 +08:00
TsMask
b76fed7dcf feat: 系统引导使用接口变更 2024-05-07 16:27:45 +08:00
TsMask
60a26dd015 Merge remote-tracking branch 'origin/main' into lichang 2024-05-07 12:10:07 +08:00
TsMask
7bdfc257c1 chore: 依赖更新 2024-05-07 12:06:38 +08:00
TsMask
e3395b47cf feat: 更新xterm依赖库@xterm/xterm 2024-05-07 12:06:03 +08:00
TsMask
4c9b4de12f fix: 看板用户行为初始查询数据排序 2024-05-07 12:01:04 +08:00
lai
1cfe5e2777 主页饼图无感更新数据 2024-05-07 11:21:57 +08:00
TsMask
0cae26a1ee pref: 网元快速安装页面重构 2024-05-07 10:33:52 +08:00
TsMask
ed4d556384 pref: 网元授权页面的组件重构 2024-05-07 10:28:14 +08:00
TsMask
6d9d7362a4 fix: 网元公共配置参数文件页面 2024-05-07 09:59:42 +08:00
TsMask
5a40733f20 Merge remote-tracking branch 'origin/main' into lichang 2024-04-30 20:25:27 +08:00
TsMask
45ee884529 style: 查询网元信息接口函数命名 2024-04-30 20:08:55 +08:00
TsMask
7de3f7f05d fix: 网元软件上传窗口响应引用无效 2024-04-30 20:08:05 +08:00
TsMask
97bb4db1eb pref: 重构网元安装页面流程 2024-04-30 20:07:21 +08:00
TsMask
fc6dfe9894 style: 开站网元信息函数命名 2024-04-30 20:03:55 +08:00
TsMask
607660124a fix: 开站步骤hooks移除无用属性 2024-04-30 20:03:12 +08:00
TsMask
c50b3add95 feat: 网元安装授权页面 2024-04-30 20:02:24 +08:00
TsMask
2f7f0e9e20 feat: 网元安装配置页面 2024-04-30 20:00:56 +08:00
TsMask
6875ffd113 feat: 网元安装信息编辑页面 2024-04-30 19:59:45 +08:00
TsMask
44844bfa7f feat: 网元安装检查页面组件 2024-04-30 19:59:06 +08:00
TsMask
21ab066761 fix: 网元授权编辑弹出窗优化支持类型查询 2024-04-30 19:58:22 +08:00
TsMask
83bdf289fa feat: 网元信息免密直连授权操作 2024-04-30 19:56:17 +08:00
lai
d7aa0fc91a 更正-详情信息添加upState字段 2024-04-30 10:22:43 +08:00
lai
a6be5190ec 详情信息添加upState字段 2024-04-30 10:15:02 +08:00
TsMask
03cd06e835 style: 开站安装网元改为下一步 2024-04-29 18:18:11 +08:00
TsMask
2d7fe5a73b feat: 网元授权文件支持勾选指定网元类型替换 2024-04-29 18:17:45 +08:00
TsMask
dd5604c8b7 perf: 重构网元公共文件编辑参数 2024-04-29 18:16:39 +08:00
TsMask
7bf2672981 fix: 移除OAM编辑也慢慢 2024-04-29 18:15:26 +08:00
TsMask
6e616c63f0 fix: UDM签约数据sst-sd格式无sd也带- 2024-04-28 11:46:30 +08:00
TsMask
3ded481cce docs: 补充参数说明 2024-04-28 10:24:31 +08:00
TsMask
1baff582d8 feat: 网元授权编辑查看弹出窗口 2024-04-28 10:24:09 +08:00
TsMask
957868cc27 feat: 开站网元安装步骤进度的显示 2024-04-28 10:23:14 +08:00
TsMask
efb98ac577 feat: 补充授权文件按类型多上传 2024-04-28 10:22:14 +08:00
TsMask
ff228daae7 fix: UE SMF状态查询Up State可选 2024-04-26 19:21:44 +08:00
TsMask
c93e693517 fix: pcf新增编辑表单数据组装异常,上传超时30s 2024-04-26 17:13:07 +08:00
TsMask
55863c1c58 fix: pcf新增表单数据新增回显问题 2024-04-26 12:15:01 +08:00
lai
8a2d6c91ba 中英文翻译 2024-04-25 19:54:00 +08:00
lai
86a939f206 中英文翻译修正 2024-04-25 19:53:35 +08:00
TsMask
2b86f724b1 style: 系统菜单图标选择编号icon-001 2024-04-25 19:37:03 +08:00
TsMask
68fbc45b7c feat: 新增oam配置文件读写接口 2024-04-25 17:19:05 +08:00
TsMask
4629ef28ff fix: 接口变更 2024-04-25 17:18:46 +08:00
lai
e3a11b0ede 增加一个搜索字段 2024-04-25 17:17:02 +08:00
lai
3df9ee4f3a QOS=>Qos 2024-04-25 17:16:12 +08:00
lai
e64d558c27 批量新增 2024-04-25 17:10:22 +08:00
lai
5a2aa383fe 图标名字为icon001一直往下 2024-04-25 14:32:53 +08:00
lai
fe9f458465 pcf动态提示 2024-04-25 14:30:59 +08:00
TsMask
8e2e9aec67 style: 开站网元软件信息高度70vh 2024-04-25 14:22:09 +08:00
TsMask
ad48e8e2e1 feat: 网元软件安装页面 2024-04-25 14:21:35 +08:00
TsMask
6f8b1000ba feat: 开站网元公告参数配置表单填写 2024-04-25 14:21:08 +08:00
TsMask
f5549992c2 style: 网元公共参数表单名称修改 2024-04-25 14:19:29 +08:00
TsMask
19771ea6dc fix: 网元版本勾选升级关闭提示信息 2024-04-25 14:19:05 +08:00
TsMask
5965737384 feat: 网元软件包勾选删除记录 2024-04-25 14:17:59 +08:00
TsMask
b3cb40fd8c fix: 文件上传后关闭窗口复位上传结果 2024-04-25 14:16:41 +08:00
TsMask
0ab5141369 chore: 版本日期240425 2024-04-25 11:59:19 +08:00
TsMask
a23284da4c fix: 鉴权用户sst-sd输入限制1-3,sd补零 2024-04-25 11:56:41 +08:00
TsMask
1c8cc13436 style: PCF批量操作点击展开 2024-04-24 16:04:22 +08:00
TsMask
e6a439faea feat: 开站目录变更quick-start 2024-04-24 15:57:03 +08:00
TsMask
f8b1b1f6c3 Merge remote-tracking branch 'origin/main' into lichang 2024-04-24 15:40:48 +08:00
TsMask
3844e07258 feat: 开站目录变更quick-start 2024-04-24 15:34:07 +08:00
TsMask
1fab9b3d97 feat: 开站页面的部分修改 2024-04-24 15:30:38 +08:00
TsMask
1bfacbf2e0 feat: 开站系统信息页面逻辑对接 2024-04-24 15:29:51 +08:00
TsMask
c01f9f3830 feat: 开站网元信息页面逻辑对接 2024-04-24 15:29:29 +08:00
TsMask
28f9d365fd style: 网元新增编辑操作信息 2024-04-24 15:28:11 +08:00
TsMask
1085fa16aa feat: 初始访问时跳转开站引导页面 2024-04-24 15:27:23 +08:00
TsMask
e351960229 feat: 网元公共参数页面同步操作改弹出窗显示操作信息 2024-04-24 15:25:56 +08:00
TsMask
03caa354da feat: 开站开始页面获取接口授权 2024-04-24 15:24:45 +08:00
TsMask
34754ea0b6 feat: 开站引导开始完成接口 2024-04-24 15:24:00 +08:00
TsMask
86e1f07f08 feat: 开站结束页面标记完成 2024-04-24 15:22:27 +08:00
TsMask
2add7547d6 style: 删除console 2024-04-23 16:03:39 +08:00
TsMask
ecb89e9f26 feat: 用户管理和个人信息手机号输入改为国际电话输入 2024-04-23 14:56:35 +08:00
TsMask
7a9b38dc66 feat: 国际手机号输入框 2024-04-23 14:55:57 +08:00
TsMask
979b18092d fix: 个人信息手机号提示翻译出错 2024-04-23 14:53:37 +08:00
TsMask
ba43a647dd style: 查询年月日控件改为年月日时分秒 2024-04-22 17:17:29 +08:00
TsMask
3be14590c6 style: 告警alarmSeq改Sequence Number 2024-04-22 17:16:09 +08:00
TsMask
857f8c4313 feat: 系统首次使用引导页面 2024-04-19 19:54:07 +08:00
TsMask
c9c39d2d4a fix: 网元信息新增默认amf示例,安装默认y 2024-04-19 19:52:19 +08:00
TsMask
845084f77f feat: 系统首次使用引导标记 2024-04-19 19:51:01 +08:00
TsMask
becba4919e style: 多语言翻译 2024-04-19 17:22:37 +08:00
lai
b797055df9 KB转换成MB 2024-04-19 16:05:14 +08:00
TsMask
8101c852c8 style: 告警前传日志alarmSeq改Sequence 2024-04-19 14:07:35 +08:00
TsMask
9bbeb9fc9a fix: 锁屏reload延迟解除防止二次重启导致服务失败 2024-04-18 09:34:25 +08:00
TsMask
19a9bd3f5c fix: 锁屏reload不解除问题 2024-04-17 18:20:37 +08:00
TsMask
399bddc635 Merge remote-tracking branch 'origin/main' into lichang 2024-04-17 15:39:33 +08:00
TsMask
5a67a1a51c chore: 控制台版本号240418 2024-04-17 15:32:42 +08:00
TsMask
9a168d2ba0 fix: 登录页无网络隐藏多言选择 2024-04-17 15:32:07 +08:00
TsMask
e42a620aed feat: 快速开始建站页面 2024-04-17 15:07:02 +08:00
TsMask
eb902594b8 style: 网元菜单表格调整 2024-04-17 15:05:17 +08:00
TsMask
817fd97496 fix: 表字段列排序组件首位排序无效问题 2024-04-17 14:32:06 +08:00
TsMask
96aab47003 Merge remote-tracking branch 'origin/main' into lichang 2024-04-17 10:54:26 +08:00
TsMask
432666b1ab fix: 看板Hooks数据复位 2024-04-17 10:48:53 +08:00
TsMask
662583c73b fix: 拓扑组件监听窗口变化 2024-04-17 10:47:21 +08:00
TsMask
f73c21e6e6 fix: 页面卸载前判断是否断开ws 2024-04-17 10:45:45 +08:00
TsMask
17e72f1db1 fix: 岗位搜索标签positionCode显示不对 2024-04-17 09:47:45 +08:00
TsMask
55d4a36efb fix: 终端telnet支持调整窗口行宽 2024-04-16 19:49:44 +08:00
TsMask
d3794ba904 feat: 网元公共配置文件配置页面 2024-04-16 19:38:16 +08:00
TsMask
832f18e2ee style: 移动网元快速安装到ne目录 2024-04-16 19:37:37 +08:00
TsMask
cd2e282624 fix: 网元软件包新增去除防重复校验 2024-04-16 11:44:29 +08:00
TsMask
3db88f1d3a style: 网元授权信息去除斑马纹样式 2024-04-16 11:43:38 +08:00
TsMask
f291bb0907 feat: 软件版本勾选多升级 2024-04-16 11:42:45 +08:00
TsMask
69c32b2593 feat: 软件包多文件上传 2024-04-16 11:41:59 +08:00
TsMask
1a2939ab01 fix: 网元管理OMC禁止start stop,开启重启等待 2024-04-16 11:12:54 +08:00
TsMask
8bf4a2a9ce Merge remote-tracking branch 'origin/main' into lichang 2024-04-15 20:18:59 +08:00
TsMask
efd389f98a fix: 查询时间搜索值为时间戳 2024-04-15 20:17:39 +08:00
TsMask
f1125cc042 Merge remote-tracking branch 'origin/main' into lichang 2024-04-15 10:08:43 +08:00
TsMask
f1a0e200dc del: 移除表格斑马纹 2024-04-15 10:08:04 +08:00
TsMask
70c025f0f5 Merge remote-tracking branch 'origin/main' into lichang 2024-04-12 21:49:11 +08:00
TsMask
b9f0a3923d feat: 网元版本记录多勾选 2024-04-12 20:27:11 +08:00
TsMask
5c942c9ef7 style: 更新接口注释 2024-04-12 20:19:04 +08:00
TsMask
4294fe82c5 fix: 网元版本操作升级回退 2024-04-12 20:18:46 +08:00
TsMask
4e7fb90544 fix: 网元服务操作接口 2024-04-12 20:18:01 +08:00
TsMask
f050e500e9 fix: pcf页面添加分页支持勾选删除 2024-04-12 17:47:52 +08:00
TsMask
6bc10babba feat: 软件包上传组件 2024-04-12 17:43:26 +08:00
TsMask
4d36f9952a fix: 网元安装接口参数变更 2024-04-12 17:42:43 +08:00
lai
b03f4bb1d6 PCF策略中英文翻译 2024-04-12 10:35:53 +08:00
TsMask
4aaedf0f77 style: 网元安装授权检查接受提示 2024-04-12 10:23:48 +08:00
TsMask
c1ea851705 style: 网元信息修改弹出窗口改为异步组件 2024-04-12 10:23:12 +08:00
TsMask
47103249ef fix: 网元快速安装页面接口变更 2024-04-11 20:09:24 +08:00
TsMask
2642f18204 fix: 网元软件/版本/授权页面 2024-04-11 17:36:38 +08:00
TsMask
e2e22eabf5 style: 下拉触发改为点击显示 2024-04-11 17:36:07 +08:00
TsMask
325ecc8029 fix: 软件包表字段更新 2024-04-11 17:35:37 +08:00
TsMask
dc6f4560d5 feat: 快速安装页面 2024-04-11 17:35:19 +08:00
TsMask
3970797d5b feat: BA需要的mocn数据看板 2024-04-11 11:58:34 +08:00
TsMask
73776ed0f9 feat: kpi指标跳转指定网元类型 2024-04-11 11:54:48 +08:00
TsMask
aca842f8c2 feat: 参数配置access只读属性支持['read-only', 'read', 'ro'] 2024-04-11 11:53:17 +08:00
TsMask
612fb77861 fix: 网元管理修改网元类型属性绑定 2024-04-11 10:16:42 +08:00
TsMask
6ba695ceaf fix: 下拉展开取消悬浮,支持点击 2024-04-10 19:52:12 +08:00
TsMask
070f77d3b8 feat: 配置-网元管理添加Column settings 2024-04-10 19:38:14 +08:00
TsMask
15de63212f style: 网元管理-Province改为Region 2024-04-10 19:37:27 +08:00
lai
2202540763 更新用户策略提示信息 2024-04-10 19:00:56 +08:00
TsMask
c674b9b3f9 fix: KPI排除不可用网元类型的选择 2024-04-10 18:54:36 +08:00
TsMask
43d30e7bfa fix: 性能任务激活停止放出,编辑删除放到更多 2024-04-10 18:42:12 +08:00
TsMask
cd0633d519 fix: 性能任务激活停止放出,编辑删除放到更多 2024-04-10 18:40:56 +08:00
TsMask
b8bff2a159 style: 网元信息拓展信息显示横向排版 2024-04-10 16:50:56 +08:00
TsMask
638f890228 style: 移除多语言=暂无网元列表数据 2024-04-10 16:49:46 +08:00
TsMask
4460f7201c style: 网元配置类型可选择或输入 2024-04-10 16:47:40 +08:00
TsMask
d0bbfafedc fix: 系统日志的删除多语言提示 2024-04-09 19:41:12 +08:00
TsMask
16dc1c2e20 style: 中英文翻译父子联动->节点联动 2024-04-09 15:46:16 +08:00
TsMask
73ed5f5285 style: 网元新增初始参数 2024-04-09 15:39:04 +08:00
TsMask
50cb92a95b fix: 去除锁屏 2024-04-09 15:33:28 +08:00
TsMask
3888fd2bca fix: 软件管理下发激活回退关闭防重复提交判断 2024-04-09 15:25:34 +08:00
TsMask
4194d8cca6 fix: 用户昵称和手机号正则校验限长度 2024-04-08 15:03:53 +08:00
TsMask
ac84a0ca0a feat: 新增终端文本显示组件 2024-04-07 19:52:37 +08:00
265 changed files with 222798 additions and 18572 deletions

View File

@@ -5,13 +5,13 @@ VITE_HISTORY_HASH = false
VITE_HISTORY_BASE_URL = "/"
# 应用名称
VITE_APP_NAME = "Core Network EMS"
VITE_APP_NAME = "Core Network OMC"
# 应用标识
VITE_APP_CODE = "CN EMS"
VITE_APP_CODE = "OMC"
# 应用版本
VITE_APP_VERSION = "2.240330.1"
VITE_APP_VERSION = "2.241102"
# 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api"

View File

@@ -5,13 +5,13 @@ VITE_HISTORY_HASH = true
VITE_HISTORY_BASE_URL = "/"
# 应用名称
VITE_APP_NAME = "Core Network EMS"
VITE_APP_NAME = "Core Network OMC"
# 应用标识
VITE_APP_CODE = "CN EMS"
VITE_APP_CODE = "OMC"
# 应用版本
VITE_APP_VERSION = "2.240330.1"
VITE_APP_VERSION = "2.241102"
# 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api"

View File

@@ -2,21 +2,14 @@
## 简介
- 系统布局使用 [@ant-design-vue/pro-layout](https://github.com/vueComponent/pro-components)
- 图标来源 [@ant-design/icons-vue](https://ant.design/components/icon)
- 菜单图标使用自定义 iconfont `font_8d5l8fzk5b87iudi.js`图标文件
## 测试环境
```text
Jenkins: http://192.168.2.166:3185/
Nginx: http://192.168.2.166:3188/#/index
后端暴露端口: http://192.168.2.166:3186 \ http://192.168.2.166:3187
新网管192.168.5.13
旧网管192.168.5.14
登录账户manager/manager
后端暴露端口: http://192.168.2.166:33030
```
## 程序命令
@@ -60,23 +53,5 @@ export NODE_OPTIONS=--max-old-space-size=50000
```text
https://192.168.5.23/
admin
admin
```
## k8s
master 192.168.5.27 agtuser/admin123
https://192.168.5.27:31325/#/workloads?namespace=default
```text
eyJhbGciOiJSUzI1NiIsImtpZCI6ImZFVUhIb1puLW04M1dfSUYyRU8zWlZueXBpNUh4T0hTRVlzU19jNlVGQ0kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLW44ZzRtIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI2M2NmYjAyNS01ZmQ0LTQ0ZTgtOTdiNC0yYWRiYWIxNzc5M2MiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.R3GRygFOjngTj-mEMBAHDeBxm3lpsXZYvC6cdTxByONtLrcMXDebwNVeKtAZ1V9qh2OrjD8n9CIygjULGPdfV6S520vjMh7Oa2q68nOyW49DNWQyYD8xLo-dQ6sX07fI7X_I3H35YUWW80jJAXjJawqIGXBSMG5intlo4tLTUSXmjCfhoQvFsgeRWu0j76pDvhMAvLPcgEXfTCi9tyL3yqJBIKONcKwmMlJeaKSR3pQk3KiibqrBO0MZclRozpke6J0ulfzTemwDDyCqBZmLsRPZ2yDd5hVBIJ9bHEcK0a25NmSFFzmd8XWQPZwg3Y4IbbY-8UhByGq0p9xS-7pGCQ
```
```ssh
# https://blog.csdn.net/m0_54706625/article/details/129721121
sudo chmod 700 -/.ssh/
sudo chmod 700 /home/mask/.ssh #这个尤其容易忽视掉,我就是从这个坑里爬出来。有木有很高兴呀!
sudo chmod 600 ~/.ssh/authorized_keys
admin / admin
```

View File

@@ -1,7 +1,7 @@
{
"name": "ems_frontend_vue3",
"type": "module",
"description": "核心网管理平台",
"description": "Core Network EMS",
"author": "TsMask",
"engines": {
"node": ">=18.0.0"
@@ -14,43 +14,48 @@
"dependencies": {
"@ant-design/icons-vue": "^7.0.1",
"@antv/g6": "~4.8.24",
"@codemirror/lang-javascript": "^6.2.1",
"@codemirror/lang-yaml": "^6.0.0",
"@codemirror/merge": "^6.6.1",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-yaml": "^6.1.1",
"@codemirror/merge": "^6.6.3",
"@codemirror/theme-one-dark": "^6.1.2",
"@tato30/vue-pdf": "^1.9.6",
"@vueuse/core": "~10.9.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": "^3.2.20",
"antdv-pro-layout": "^3.2.6",
"antdv-pro-layout": "~3.3.5",
"antdv-pro-modal": "^3.1.0",
"codemirror": "^6.0.1",
"dayjs": "^1.11.10",
"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": "^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",
"p-queue": "~8.0.1",
"pinia": "^2.1.7",
"vue": "~3.3.13",
"vue-i18n": "~9.10.0",
"vue-router": "^4.2.5",
"vue-i18n": "^9.13.1",
"vue-router": "^4.4.0",
"vue3-smooth-dnd": "^0.0.6",
"xlsx": "^0.18.5",
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
"xlsx": "~0.18.5"
},
"devDependencies": {
"@types/crypto-js": "^4.2.2",
"@types/file-saver": "^2.0.7",
"@types/js-cookie": "^3.0.6",
"@types/node": "^18.0.0",
"@types/nprogress": "^0.2.3",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue": "^5.0.5",
"less": "^4.2.0",
"typescript": "^5.4.3",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.2.6",
"vite-plugin-compression": "^0.5.1",
"vue-tsc": "^1.8.27"
"typescript": "~5.4.5",
"unplugin-vue-components": "~0.26.0",
"vite": "~5.3.1",
"vite-plugin-compression": "~0.5.1",
"vue-tsc": "~2.0.22"
}
}

View File

@@ -11,8 +11,9 @@
*/
(function () {
// host = ip:port
const host = '192.168.8.100:33030';
// const host = '192.168.8.100:33030';
const host = `${window.location.hostname}:33030`;
// Service Address
sessionStorage.setItem('baseUrl', `http://${host}`);
// websocket Address

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

178925
public/wiregasm/wiregasm.data Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,166 @@
/**
* Wraps the WiregasmLib lib functionality and manages a single DissectSession
*/
class Wiregasm {
constructor() {
this.initialized = false;
this.session = null;
}
/**
* Initialize the wrapper and the Wiregasm module
*
* @param loader Loader function for the Emscripten module
* @param overrides Overrides
*/
async init(loader, overrides = {}, beforeInit = null) {
if (this.initialized) {
return;
}
this.lib = await loader(overrides);
this.uploadDir = this.lib.getUploadDirectory();
this.pluginsDir = this.lib.getPluginsDirectory();
if (beforeInit !== null) {
await beforeInit(this.lib);
}
this.lib.init();
this.initialized = true;
}
list_modules() {
return this.lib.listModules();
}
list_prefs(module) {
return this.lib.listPreferences(module);
}
apply_prefs() {
this.lib.applyPreferences();
}
set_pref(module, key, value) {
const ret = this.lib.setPref(module, key, value);
if (ret.code != PrefSetResult.PREFS_SET_OK) {
const message =
ret.error != '' ? ret.error : preferenceSetCodeToError(ret.code);
throw new Error(
`Failed to set preference (${module}.${key}): ${message}`
);
}
}
get_pref(module, key) {
const response = this.lib.getPref(module, key);
if (response.code != 0) {
throw new Error(`Failed to get preference (${module}.${key})`);
}
return response.data;
}
/**
* Check the validity of a filter expression.
*
* @param filter A display filter expression
*/
test_filter(filter) {
return this.lib.checkFilter(filter);
}
complete_filter(filter) {
const out = this.lib.completeFilter(filter);
return {
err: out.err,
fields: vectorToArray(out.fields),
};
}
reload_lua_plugins() {
this.lib.reloadLuaPlugins();
}
add_plugin(name, data, opts = {}) {
const path = this.pluginsDir + '/' + name;
this.lib.FS.writeFile(path, data, opts);
}
/**
* Load a packet trace file for analysis.
*
* @returns Response containing the status and summary
*/
load(name, data, opts = {}) {
if (this.session != null) {
this.session.delete();
}
const path = this.uploadDir + '/' + name;
this.lib.FS.writeFile(path, data, opts);
this.session = new this.lib.DissectSession(path);
return this.session.load();
}
/**
* Get Packet List information for a range of packets.
*
* @param filter Output those frames that pass this filter expression
* @param skip Skip N frames
* @param limit Limit the output to N frames
*/
frames(filter, skip = 0, limit = 0) {
return this.session.getFrames(filter, skip, limit);
}
/**
* Get full information about a frame including the protocol tree.
*
* @param number Frame number
*/
frame(num) {
return this.session.getFrame(num);
}
follow(follow, filter) {
return this.session.follow(follow, filter);
}
destroy() {
if (this.initialized) {
if (this.session !== null) {
this.session.delete();
this.session = null;
}
this.lib.destroy();
this.initialized = false;
}
}
/**
* Returns the column headers
*/
columns() {
const vec = this.lib.getColumns();
// convert it from a vector to array
return vectorToArray(vec);
}
}
/**
* Converts a Vector to a JS array
*
* @param vec Vector
* @returns JS array of the Vector contents
*/
function vectorToArray(vec) {
return new Array(vec.size()).fill(0).map((_, id) => vec.get(id));
}
function preferenceSetCodeToError(code) {
switch (code) {
case PrefSetResult.PREFS_SET_SYNTAX_ERR:
return 'Syntax error in string';
case PrefSetResult.PREFS_SET_NO_SUCH_PREF:
return 'No such preference';
case PrefSetResult.PREFS_SET_OBSOLETE:
return 'Preference used to exist but no longer does';
default:
return 'Unknown error';
}
}
if (typeof exports === 'object' && typeof module === 'object') {
module.exports = Wiregasm;
module.exports = vectorToArray;
} else if (typeof define === 'function' && define['amd']) {
define([], function () {
return Wiregasm;
});
define([], function () {
return vectorToArray;
});
} else if (typeof exports === 'object') {
exports['loadWiregasm'] = Wiregasm;
exports['vectorToArray'] = vectorToArray;
}

162
public/wiregasm/worker.js Normal file
View File

@@ -0,0 +1,162 @@
// load the Wiregasm library
importScripts(
'/wiregasm/wiregasm_new.js', // self-compilation es5
'/wiregasm/wiregasm_load.js'
// 'https://cdn.jsdelivr.net/npm/@goodtools/wiregasm/dist/wiregasm.js'
);
const wg = new Wiregasm();
const inflateRemoteBuffer = async url => {
const res = await fetch(url);
return await res.arrayBuffer();
};
const fetchPackages = async () => {
console.log('Fetching packages');
let [wasmBuffer, dataBuffer] = await Promise.all([
await inflateRemoteBuffer(
'/wiregasm/wiregasm.wasm'
// 'https://cdn.jsdelivr.net/npm/@goodtools/wiregasm/dist/wiregasm.wasm'
),
await inflateRemoteBuffer(
'/wiregasm/wiregasm.data'
// 'https://cdn.jsdelivr.net/npm/@goodtools/wiregasm/dist/wiregasm.data'
),
]);
return { wasmBuffer, dataBuffer };
};
// Load the Wiregasm Wasm data
fetchPackages()
.then(({ wasmBuffer, dataBuffer }) => {
return wg.init(loadWiregasm, {
wasmBinary: wasmBuffer,
getPreloadedPackage() {
return dataBuffer;
},
handleStatus: (type, status) => {
postMessage({ type: 'status', code: type, status: status });
},
printErr: error => {
postMessage({ type: 'error', error: error });
},
});
})
.then(() => {
postMessage({ type: 'init' });
})
.catch(e => {
postMessage({ type: 'error', error: e });
});
/**Converts a Vector to a JS array */
function replacer(key, value) {
if (value.constructor.name.startsWith('Vector')) {
return vectorToArray(value);
}
return value;
}
// Event listener to receive messages from the main script
this.onmessage = ev => {
const data = ev.data;
switch (data.type) {
case 'close':
wg.destroy();
break;
case 'columns':
const columns = wg.columns();
if (Array.isArray(columns)) {
this.postMessage({ type: 'columns', data: columns });
}
break;
case 'select': // select a frame
const number = data.number;
const frameData = wg.frame(number);
const frameDataToJSON = JSON.parse(JSON.stringify(frameData, replacer));
this.postMessage({
type: 'selected',
data: frameDataToJSON,
});
break;
case 'frames': // get frames list
const skip = data.skip;
const limit = data.limit;
const filter = data.filter;
const framesData = wg.frames(filter, skip, limit);
const framesDataToJSON = JSON.parse(JSON.stringify(framesData, replacer));
this.postMessage({
type: 'frames',
data: framesDataToJSON,
});
break;
case 'process-data':
const loadData = wg.load(data.name, new Uint8Array(data.data));
this.postMessage({ type: 'processed', data: loadData });
break;
case 'process':
const f = data.file;
const reader = new FileReader();
reader.addEventListener('load', event => {
// XXX: this blocks the worker thread
const loadData = wg.load(f.name, new Uint8Array(event.target.result));
postMessage({ type: 'processed', data: loadData });
});
reader.readAsArrayBuffer(f);
break;
case 'check-filter':
const filterStr = data.filter;
const checkFilterRes = wg.lib.checkFilter(filterStr);
this.postMessage({ type: 'filter', data: checkFilterRes });
break;
}
if (data.type === 'reload-quick') {
if (wg.session) {
// TODO: this is a hack, we should be able to reload the session
const name = data.name;
const res = wg.session.load();
postMessage({ type: 'processed', name: name, data: res });
}
} else if (data.type === 'module-tree') {
const res = wg.list_modules();
// send it to the correct port
event.ports[0].postMessage({
result: JSON.parse(JSON.stringify(res, replacer)),
});
} else if (data.type === 'module-prefs') {
const res = wg.list_prefs(data.name);
// send it to the correct port
event.ports[0].postMessage({
result: JSON.parse(JSON.stringify(res, replacer)),
});
} else if (data.type === 'upload-file') {
const f = data.file;
const reader = new FileReader();
reader.addEventListener('load', e => {
// XXX: this blocks the worker thread
const path = '/uploads/' + f.name;
wg.lib.FS.writeFile(path, Buffer.from(e.target.result));
event.ports[0].postMessage({ result: path });
});
reader.readAsArrayBuffer(f);
} else if (data.type === 'update-pref') {
try {
console.log(`set_pref(${data.module}, ${data.key}, ${data.value})`);
wg.set_pref(data.module, data.key, data.value);
event.ports[0].postMessage({ result: 'ok' });
} catch (e) {
console.error(
`set_pref(${data.module}, ${data.key}, ${data.value}) failed: ${e.message}`
);
event.ports[0].postMessage({ error: e.message });
}
} else if (data.type === 'apply-prefs') {
console.log(`apply_prefs()`);
wg.apply_prefs();
event.ports[0].postMessage({ result: 'ok' });
}
};

View File

@@ -4,6 +4,7 @@ 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 'dayjs/locale/zh-cn';
import { ref, watch } from 'vue';
import useAppStore from '@/store/modules/app';
@@ -11,6 +12,7 @@ import useI18n from '@/hooks/useI18n';
const { t, currentLocale } = useI18n();
const appStore = useAppStore();
dayjs.extend(advancedFormat);
dayjs.locale('zh-cn'); // 默认中文
usePrimaryColor(); // 载入用户自定义主题色
@@ -50,10 +52,11 @@ console.info(
</ConfigProvider>
</template>
<style>
<style lang="css">
#app {
height: 100%;
}
body .ant-pro-basicLayout {
display: flex;
flex-direction: column;
@@ -61,10 +64,6 @@ body .ant-pro-basicLayout {
min-height: 100vh;
}
.ant-pro-sider {
z-index: 20;
}
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,

View File

@@ -1,55 +0,0 @@
import {
RESULT_CODE_ERROR,
RESULT_CODE_SUCCESS,
RESULT_MSG_ERROR,
} from '@/constants/result-constants';
import { language, request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
/**
* 查询配置详细
* @param tag 配置ID
* @returns object
*/
export async function getConfigInfo(tag: string) {
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/omc_db/config`,
method: 'get',
params: {
SQL: `SELECT * FROM config WHERE config_tag = '${tag}'`,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
let data = result.data.data[0];
return Object.assign(result, {
data: parseObjLineToHump(data['config'][0]),
});
}
return result;
}
/**
* 修改配置
* @param data 配置对象
* @returns object
*/
export async function updateConfig(tag: string, data: Record<string, any>) {
const result = await request({
url: `/api/rest/databaseManagement/v1/omc_db/config?WHERE=config_tag='${tag}'`,
method: 'put',
data: { data },
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && result.data.data) {
let rows = result.data.data.affectedRows;
if (rows) {
delete result.data;
return result;
} else {
return { code: RESULT_CODE_ERROR, msg: RESULT_MSG_ERROR[language] };
}
}
return result;
}

View File

@@ -2,437 +2,8 @@ import {
RESULT_CODE_ERROR,
RESULT_CODE_SUCCESS,
RESULT_MSG_ERROR,
RESULT_MSG_SUCCESS,
} from '@/constants/result-constants';
import { language, request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
/**
* 查询配置参数标签栏
* @param neType 网元类型
* @returns object
*/
export async function getParamConfigTopTab(neType: string) {
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/elementType/omc_db/objectType/param_config`,
method: 'get',
params: {
SQL: `SELECT top_display,top_tag,method FROM param_config WHERE ne_type = '${neType}'`,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
let data = result.data.data[0];
data = data['param_config'];
if (Array.isArray(data)) {
return Object.assign(result, {
data: parseObjLineToHump(data),
});
}
return Object.assign(result, {
data: [],
});
}
return result;
}
/**
* 查询配置参数标签栏对应信息
* @param neType 网元类型
* @param topTag
* @param neId
* @returns object { wrRule, dataArr }
*/
async function getParamConfigInfo(
neType: string,
topTag: string,
neId: string
) {
return await Promise.allSettled([
// 获取参数规则
request({
url: `/api/rest/databaseManagement/v1/elementType/omc_db/objectType/param_config`,
method: 'get',
params: {
SQL: `SELECT param_json FROM param_config WHERE ne_type = '${neType}' AND top_tag='${topTag}'`,
},
timeout: 1_000,
}),
// 获取对应信息
request({
url: `/api/rest/systemManagement/v1/elementType/${neType.toLowerCase()}/objectType/config/${topTag}`,
method: 'get',
params: {
ne_id: neId,
},
timeout: 1_000,
}),
]).then(resArr => {
let wrRule: Record<string, any> = {};
// 规则数据
if (resArr[0].status === 'fulfilled') {
const itemV = resArr[0].value;
// 解析数据
if (
itemV.code === RESULT_CODE_SUCCESS &&
Array.isArray(itemV.data?.data)
) {
let itemData = itemV.data.data;
const data = itemData[0]['param_config'];
if (Array.isArray(data)) {
const v = data[0]['param_json'];
try {
itemData = parseObjLineToHump(JSON.parse(v));
wrRule = itemData;
} catch (error) {
console.error(error);
}
}
}
}
let dataArr: Record<string, any>[] = [];
// 对应信息
if (resArr[1].status === 'fulfilled') {
const itemV = resArr[1].value;
// 解析数据
if (
itemV.code === RESULT_CODE_SUCCESS &&
Array.isArray(itemV.data?.data)
) {
let itemData = itemV.data.data;
dataArr = parseObjLineToHump(itemData);
}
}
return { wrRule, dataArr };
});
}
/**
* 查询配置参数标签栏对应信息-表格处理
* @param neType 网元类型
* @param topTag
* @param neId
* @returns object
*/
export async function getParamConfigInfoTable(
neType: string,
topTag: string,
neId: string
) {
const { wrRule, dataArr } = await getParamConfigInfo(neType, topTag, neId);
// UPF参数不统一
// if (neType === 'UPF') {
// if (Reflect.has(wrRule, 'list')) {
// for (const arr of wrRule['list']) {
// arr['name'] = parseFirstLower(arr['name']);
// }
// for (const item of dataArr) {
// for (const k in item) {
// item[parseFirstLower(k)] = item[k];
// Reflect.deleteProperty(item, k);
// }
// }
// }
// if (Reflect.has(wrRule, 'array')) {
// for (const arr of wrRule['array']) {
// if (Array.isArray(arr['array'])) {
// for (const child of arr['array']) {
// child['name'] = parseFirstLower(child['name']);
// }
// }
// arr['name'] = parseFirstLower(arr['name']);
// }
// for (const item of dataArr) {
// for (const k in item) {
// // 处理子列表
// if (Array.isArray(item[k])) {
// for (const child of item[k]) {
// for (const childKey in child) {
// child[parseFirstLower(childKey)] = child[childKey];
// Reflect.deleteProperty(child, childKey);
// }
// }
// }
// item[parseFirstLower(k)] = item[k];
// Reflect.deleteProperty(item, k);
// }
// }
// }
// }
// 拼装数据
const result = {
code: RESULT_CODE_SUCCESS,
msg: RESULT_MSG_SUCCESS,
data: {
type: 'list' as 'list' | 'array',
data: [] as any[],
dataRule: {},
columns: [] as any[],
},
};
// kv单列表
if (Reflect.has(wrRule, 'list')) {
result.data.type = 'list';
const ruleArr = Object.freeze(wrRule['list']);
// 列表项数据
let dataList = [];
for (const item of dataArr) {
for (const key of Object.keys(item)) {
// 规则为准
for (const rule of ruleArr) {
if (rule['name'] === key) {
const ruleItem = Object.assign({ optional: 'true' }, rule, {
value: item[key],
});
dataList.push(ruleItem);
break;
}
}
}
}
result.data.data = dataList;
// 列表字段
result.data.columns = [
{
title: 'Key',
dataIndex: 'display',
align: 'left',
width: '30%',
},
{
title: 'Value',
dataIndex: 'value',
align: 'left',
width: '70%',
},
];
}
// 多列表
if (Reflect.has(wrRule, 'array')) {
result.data.type = 'array';
const ruleArr = Object.freeze(wrRule['array']);
// 列表项数据
const dataArray = [];
for (const item of dataArr) {
let record: Record<string, any> = {};
for (const key of Object.keys(item)) {
// 规则为准
for (const rule of ruleArr) {
if (rule['name'] === key) {
const ruleItem = Object.assign({ optional: 'true' }, rule, {
value: item[key],
});
record[ruleItem.name] = ruleItem;
break;
}
}
}
dataArray.push(record);
}
result.data.data = dataArray;
// 无数据时,用于新增
let dataRule: Record<string, any> = {};
for (const rule of ruleArr) {
dataRule[rule.name] = rule;
}
result.data.dataRule = dataRule;
// 列表字段
const columns: Record<string, any>[] = [];
for (const rule of ruleArr) {
columns.push({
title: rule.display,
dataIndex: rule.name,
align: 'left',
width: 5,
});
}
result.data.columns = columns;
}
return result;
}
/**
* 查询配置参数标签栏对应信息-表单结构处理
* @param neType 网元类型
* @param topTag
* @param neId
* @returns object
*/
export async function getParamConfigInfoForm(
neType: string,
topTag: string,
neId: string
) {
const { wrRule, dataArr } = await getParamConfigInfo(neType, topTag, neId);
// 拼装数据
const result = {
code: RESULT_CODE_SUCCESS,
msg: RESULT_MSG_SUCCESS,
data: {
type: 'list' as 'list' | 'array',
data: [] as Record<string, any>[],
dataRule: {},
},
};
// kv单列表
if (Reflect.has(wrRule, 'list')) {
result.data.type = 'list';
const ruleArr = Object.freeze(wrRule['list']);
// 列表项数据
const dataList = [];
for (const item of dataArr) {
for (const key in item) {
// 规则为准
for (const rule of ruleArr) {
if (rule['name'] === key) {
const ruleItem = Object.assign({ optional: 'true' }, rule, {
value: item[key],
});
dataList.push(ruleItem);
break;
}
}
}
}
result.data.data = dataList;
}
// 多列表
if (Reflect.has(wrRule, 'array')) {
result.data.type = 'array';
const ruleArr = Object.freeze(wrRule['array']);
// 列表项数据
const dataArray = [];
for (const item of dataArr) {
const index = item['index'];
let record: Record<string, any>[] = [];
for (const key in item) {
// 规则为准
for (const rule of ruleArr) {
if (rule['name'] === key) {
const ruleItem = Object.assign({ optional: 'true' }, rule, {
value: item[key],
});
record.push(ruleItem);
break;
}
}
}
dataArray.push({ title: `Index-${index}`, key: index, record });
}
result.data.data = dataArray;
// 无数据时,用于新增
result.data.dataRule = { title: `Index-0`, key: 0, record: ruleArr };
}
return result;
}
/**
* 查询配置参数标签栏对应信息子节点
* @param neType 网元类型
* @param topTag
* @param neId
* @param loc 子节点index/字段) 1/dnnList
* @returns
*/
export async function getParamConfigInfoChild(
neType: string,
topTag: string,
neId: string,
loc: string
) {
// 发起请求
const result = await request({
url: `/api/rest/systemManagement/v1/elementType/${neType.toLowerCase()}/objectType/config/${topTag}`,
method: 'get',
params: {
ne_id: neId,
loc: loc,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
return Object.assign(result, {
data: parseObjLineToHump(result.data.data),
});
}
return result;
}
/**
* 修改配置参数标签栏对应信息
* @param args 对象 {neType,neId,topTag,loc}
* @param data 对象 {修改的数据kv}
* @returns object
*/
export function updateParamConfigInfo(
type: 'list' | 'array',
args: Record<string, any>,
data: Record<string, any>
) {
let url = `/api/rest/systemManagement/v1/elementType/${args.neType.toLowerCase()}/objectType/config/${
args.topTag
}?ne_id=${args.neId}`;
// 多列表需要loc
if (type === 'array') {
url += `&loc=${args.loc}`;
}
return request({
url,
method: 'put',
data: data,
});
}
/**
* 新增配置参数标签栏对应信息
* @param args 对象 {neType,neId,topTag,loc}
* @param data 行记录对象
* @returns object
*/
export function addParamConfigInfo(
args: Record<string, any>,
data: Record<string, any>
) {
return request({
url: `/api/rest/systemManagement/v1/elementType/${args.neType.toLowerCase()}/objectType/config/${
args.topTag
}?ne_id=${args.neId}&loc=${args.loc}`,
method: 'post',
data: data,
});
}
/**
* 删除配置参数标签栏对应信息
* @param args 对象 {neType,neId,topTag,loc}
* loc 多层表的定位信息{index0}/{paraName1}/{index1}
* @param data 行记录对象
* @returns object
*/
export function delParamConfigInfo(args: Record<string, any>) {
return request({
url: `/api/rest/systemManagement/v1/elementType/${args.neType.toLowerCase()}/objectType/config/${
args.topTag
}?ne_id=${args.neId}&loc=${args.loc}`,
method: 'delete',
});
}
/**
* 更新网元配置重新载入
@@ -462,3 +33,53 @@ export async function updateNeConfigReload(neType: string, neId: string) {
}
return result;
}
/**
* 从参数配置PCF中获取对应信息提供给PCC用户策略输入框
* @param neId
* @returns object {pccRules,sessionRules,qosTemplate,headerEnrichTemplate,serviceAreaRestriction}
*/
export async function getPCCRule(neId: any) {
const paramNameArr = [
'pccRules',
'sessionRules',
'qosTemplate',
'headerEnrichTemplate',
'serviceAreaRestriction',
];
const reqArr = [];
for (const paramName of paramNameArr) {
reqArr.push(
request({
url: `/ne/config/data`,
params: { neType: 'PCF', neId, paramName },
method: 'get',
})
);
}
return await Promise.allSettled(reqArr).then(resArr => {
// 规则数据
const obj: any = {};
resArr.forEach((item, i: number) => {
if (item.status === 'fulfilled') {
const res = item.value;
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
const key = paramNameArr[i];
obj[key] = res.data.map((item: any) => {
if ('qosTemplate' === key) {
return { value: item.qosId, label: item.qosId };
}
if ('headerEnrichTemplate' === key) {
return { value: item.templateName, label: item.templateName };
}
if ('serviceAreaRestriction' === key) {
return { value: item.name, label: item.name };
}
return { value: item.ruleId, label: item.ruleId };
});
}
}
});
return obj;
});
}

View File

@@ -1,72 +0,0 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
/**
* 查询软件列表
* @param query 查询参数
* @returns object
*/
export async function listLicense(query: Record<string, any>) {
let totalSQL = 'select count(id) as total from ne_license ';
let rowsSQL = ' select * from ne_license ';
// 查询
let querySQL = 'where 1=1';
if (query.neType) {
querySQL += ` and ne_type like '%${query.neType}%' `;
}
// 分页
const pageNum = (query.pageNum - 1) * query.pageSize;
const limtSql = ` order by created_at desc limit ${pageNum},${query.pageSize} `;
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/select/omc_db/ne_license`,
method: 'get',
params: {
totalSQL: totalSQL + querySQL,
rowsSQL: rowsSQL + querySQL + limtSql,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
const data: DataList = {
total: 0,
rows: [],
code: result.code,
msg: result.msg,
};
result.data.data.forEach((item: any) => {
const itemData = item['ne_license'];
if (Array.isArray(itemData)) {
if (itemData.length === 1 && itemData[0]['total'] >= 0) {
data.total = itemData[0]['total'];
} else {
data.rows = itemData.map(v => parseObjLineToHump(v));
}
}
});
return data;
}
return result;
}
/**
* 上传文件
* @param data 表单数据对象
* @returns object
*/
export function uploadLicense(data: FormData) {
return request({
url: `/api/rest/systemManagement/v1/elementType/${data.get(
'nfType'
)}/objectType/license?neId=${data.get('nfId')}`,
method: 'post',
data,
dataType: 'form-data',
timeout: 180_000,
});
}

View File

@@ -5,6 +5,7 @@ import {
} from '@/constants/result-constants';
import { language, request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
import { NE_TYPE_LIST } from '@/constants/ne-constants';
/**
* 查询网元列表
@@ -15,24 +16,6 @@ export async function listNeInfo(query: Record<string, any>) {
let totalSQL = 'select count(*) as total from ne_info where 1=1 ';
let rowsSQL = 'select * from ne_info where 1=1 ';
// 系统特定顺序
const specificOrder = [
'OMC',
'MME',
'AMF',
'AUSF',
'UDM',
'SMF',
'PCF',
'UPF',
'NRF',
'NSSF',
'IMS',
'N3IWF',
'NEF',
'LMF',
];
// 查询
let querySQL = '';
if (query.neType) {
@@ -70,8 +53,8 @@ export async function listNeInfo(query: Record<string, any>) {
data.rows = itemData.map(v => parseObjLineToHump(v));
//通过sort进行冒泡排序
data.rows.sort((a: any, b: any) => {
const typeA = specificOrder.indexOf(a.neType);
const typeB = specificOrder.indexOf(b.neType);
const typeA = NE_TYPE_LIST.indexOf(a.neType);
const typeB = NE_TYPE_LIST.indexOf(b.neType);
if (typeA === -1) return 1; // 如果不在特定顺序中,排到后面
if (typeB === -1) return -1; // 如果不在特定顺序中,排到后面
return typeA - typeB;
@@ -156,7 +139,7 @@ export async function delNeInfo(data: Record<string, any>) {
/**
* 导出网元配置文件
* @param
* @param data data {neType neId}
* @returns bolb
*/
export function exportSet(data: Record<string, any>) {

View File

@@ -111,6 +111,7 @@ export async function sendNeSoftware(data: Record<string, any>) {
url: `/api/rest/systemManagement/v1/${data.neType}/software/${data.version}/${data.neId}`,
method: 'post',
timeout: 180_000,
repeatSubmit: false,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
@@ -130,6 +131,7 @@ export async function runNeSoftware(data: Record<string, any>) {
url: `/api/rest/systemManagement/v1/${data.neType}/software/${data.version}/${data.neId}`,
method: 'put',
timeout: 180_000,
repeatSubmit: false,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
@@ -149,6 +151,7 @@ export async function backNeSoftware(data: Record<string, any>) {
url: `/api/rest/systemManagement/v1/${data.neType}/software/${data.version}/${data.neId}`,
method: 'PATCH',
timeout: 180_000,
repeatSubmit: false,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {

View File

@@ -241,6 +241,7 @@ export function listSync() {
return request({
url: `/api/rest/faultManagement/v1/elementType/all/objectType/alarms`,
method: 'get',
timeout: 180_000,
});
}
@@ -294,7 +295,7 @@ export async function exportAll(query: Record<string, any>) {
* @returns bolb
*/
export async function origGet() {
let totalSQL = `select count(*) as value,orig_severity as name from alarm group by orig_severity`;
let totalSQL = `select count(*) as value,orig_severity as name from alarm WHERE alarm_status='1' and orig_severity!='Event' group by orig_severity`;
// 发起请求
const result = await request({
@@ -329,10 +330,10 @@ export async function origGet() {
* @returns object
*/
export async function top3Sel(filterFlag?: string) {
let filter = ` WHERE orig_severity='${filterFlag}'`;
if (!filterFlag) filter = '';
let filter = ` WHERE alarm_status='1'and orig_severity='${filterFlag}'`;
if (!filterFlag) filter = "WHERE alarm_status='1'";
let top3SQL = `select count(*) as value,ne_type as name from alarm ${filter} group by ne_type ORDER BY value desc limit 0,3 `;
let top3SQL = `select count(*) as value,ne_type as name from alarm ${filter} and orig_severity!='Event' group by ne_type ORDER BY value desc limit 0,3 `;
// 发起请求
const result = await request({

View File

@@ -0,0 +1,124 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
import { parseDateToStr } from '@/utils/date-utils';
import useUserStore from '@/store/modules/user';
/**
* 查询列表
* @param query 查询参数
* @returns object
*/
export async function listAct(query: Record<string, any>) {
let totalSQL = `select count(*) as total from alarm_event where 1=1 `;
let rowsSQL = `select * from alarm_event where 1=1 `;
// 查询
let querySQL = '';
if (query.alarmCode) {
querySQL += ` and alarm_code = '${query.alarmCode}' `;
}
if (query.alarmType) {
querySQL += ` and alarm_type = '${query.alarmType}' `;
}
if (query.pvFlag) {
querySQL += ` and pv_flag = '${query.pvFlag}' `;
}
if (query.neId) {
querySQL += ` and ne_id like '%${query.neId}%' `;
}
if (query.neName) {
querySQL += ` and ne_name like '%${query.neName}%' `;
}
if (query.neType) {
querySQL += ` and ne_type like '%${query.neType}%' `;
}
if (query.beginTime && query.endTime) {
querySQL += ` and event_time BETWEEN '${query.beginTime}' and ' ${query.endTime}'`;
}
// 分页
const pageNum = (query.pageNum - 1) * query.pageSize;
const limtSql = ` order by event_time desc limit ${pageNum},${query.pageSize} `;
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/select/omc_db/alarm_event`,
method: 'get',
params: {
SQL: totalSQL + querySQL,
rowsSQL: rowsSQL + querySQL + limtSql,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
const data: DataList = {
total: 0,
rows: [],
code: result.code,
msg: result.msg,
};
result.data.data.forEach((item: any) => {
const itemData = item['alarm_event'];
if (Array.isArray(itemData)) {
if (itemData.length === 1 && itemData[0]['total'] >= 0) {
data.total = itemData[0]['total'];
} else {
data.rows = itemData.map(v => parseObjLineToHump(v));
}
}
});
return data;
}
return result;
}
/**
* 事件告警导出
* @param query 查询参数
* @returns bolb
*/
export async function exportAll(query: Record<string, any>) {
let rowsSQL = `select * from alarm_event where 1=1`;
// 查询
let querySQL = '';
querySQL += query.alarm_code
? ` and alarm_code = '${query.alarm_code}' `
: '';
querySQL += query.alarm_type
? ` and alarm_type = '${query.alarm_type}' `
: '';
querySQL += query.pv_flag ? ` and pv_flag = '${query.pv_flag}' ` : '';
querySQL += query.orig_severity
? ` and orig_severity in('${query.orig_severity}' )`
: '';
querySQL += query.ne_id ? ` and ne_id like '%${query.ne_id}%' ` : '';
querySQL += query.ne_name ? ` and ne_name like '%${query.ne_name}%' ` : '';
querySQL += query.ne_type ? ` and ne_type like '%${query.ne_type}%' ` : '';
querySQL +=
query.beginTime && query.endTime
? ` and event_time BETWEEN '${query.beginTime}' and ' ${query.endTime}'`
: '';
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/select/omc_db/alarm_event`,
method: 'get',
params: {
rowsSQL: rowsSQL + querySQL,
},
});
if (result.code === RESULT_CODE_SUCCESS) {
let v = result.data.data[0];
const vArr = parseObjLineToHump(v['alarm_event']);
result.data = vArr == null ? [] : vArr;
}
return result;
}

View File

@@ -1,29 +1,14 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch';
import { parseDateToStr } from '@/utils/date-utils';
import { NE_TYPE_LIST } from '@/constants/ne-constants';
/**
* 查询公告列表
* @param query 查询参数
* @returns object
*/
export async function listMain() {
// 系统特定顺序
const specificOrder = [
'OMC',
'MME',
'AMF',
'AUSF',
'UDM',
'SMF',
'PCF',
'UPF',
'NRF',
'NSSF',
'IMS',
'N3IWF',
'NEF',
'LMF',
];
const result = await request({
url: '/api/rest/systemManagement/v1/elementType/all/objectType/systemState',
method: 'get',
@@ -39,7 +24,6 @@ export async function listMain() {
const serialNum = (value as any).serialNum;
const version = (value as any).version;
const errCode = systemState && systemState['errorCode'];
var time = new Date();
// console.log(key, value);
@@ -59,7 +43,7 @@ export async function listMain() {
ipAddress,
serialNum,
name: key.split('/').join('_'),
expiryDate:'-',
expiryDate: '-',
status: 'Abnormal',
};
}
@@ -67,8 +51,8 @@ export async function listMain() {
});
//通过sort进行冒泡排序
mergedData.sort((a: any, b: any) => {
const typeA = specificOrder.indexOf(a.name.split('_')[0]);
const typeB = specificOrder.indexOf(b.name.split('_')[0]);
const typeA = NE_TYPE_LIST.indexOf(a.name.split('_')[0]);
const typeB = NE_TYPE_LIST.indexOf(b.name.split('_')[0]);
if (typeA === -1) return 1; // 如果不在特定顺序中,排到后面
if (typeB === -1) return -1; // 如果不在特定顺序中,排到后面
return typeA - typeB;
@@ -104,5 +88,6 @@ export function getSysConf() {
return request({
url: `/sys-conf`,
method: 'get',
whithToken: false,
});
}

View File

@@ -0,0 +1,53 @@
import { request } from '@/plugins/http-fetch';
/**
* 获取下拉框数据
* @returns object
*/
export function getBakFile() {
return request({
url: '/lm/table/list',
method: 'get',
});
}
/**
* 获取对应类型的文件列表
* @param query 查询参数
* @returns object
*/
export function getBakFileList(query: Record<string, any>) {
return request({
url: '/lm/file/list',
method: 'get',
params: query,
});
}
/**
* 下载远端文件
* @param query 查询参数
* @returns object
*/
export function downFile(query: Record<string, any>) {
return request({
url: `/lm/file/${query.fileName}`,
method: 'get',
params: query,
responseType: 'blob',
timeout: 180_000,
});
}
/**
* 删除远端获取文件
* @param query 查询参数
* @returns object
*/
export function delFile(query: Record<string, any>) {
return request({
url: `/lm/file/${query.fileName}`,
method: 'delete',
params: query,
});
}

View File

@@ -7,6 +7,7 @@ export function login(data: Record<string, string>) {
method: 'post',
data: data,
whithToken: false,
crypto: true,
});
}
@@ -21,6 +22,7 @@ export function register(data: Record<string, any>) {
method: 'post',
data: data,
whithToken: false,
crypto: true,
});
}

View File

@@ -6,5 +6,6 @@ export function getLoad(query: Record<string, any>) {
url: '/monitor/load',
method: 'get',
params: query,
timeout: 60_000,
});
}

View File

@@ -1,93 +0,0 @@
import {
RESULT_CODE_ERROR,
RESULT_CODE_SUCCESS,
RESULT_MSG_ERROR,
} from '@/constants/result-constants';
import { language, request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
/**
* 查询用户会话列表
* @param query 查询参数
* @returns object
*/
export async function listSession(query: Record<string, any>) {
let totalSQL = 'select count(*) as total from session where 1=1 ';
let rowsSQL = 'select * from session where 1=1 ';
// 查询
let querySQL = '';
if (query.accountId) {
querySQL += ` and account_id like '%${query.accountId}%' `;
}
if (query.ip) {
querySQL += ` and host like '%${query.ip}%' `;
}
// 分页
const pageNum = (query.pageNum - 1) * query.pageSize;
const limtSql = ` limit ${pageNum},${query.pageSize} `;
// 排序
let sortSql = ' order by login_time ';
if (query.sortOrder === 'desc') {
sortSql += ' desc ';
} else {
sortSql += ' asc ';
}
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/omc_db/session`,
method: 'get',
params: {
totalSQL: totalSQL + querySQL,
rowsSQL: rowsSQL + querySQL + sortSql + limtSql,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
const data: DataList = {
total: 0,
rows: [],
code: result.code,
msg: result.msg,
};
result.data.data.forEach((item: any) => {
const itemData = item['session'];
if (Array.isArray(itemData)) {
if (itemData.length === 1 && itemData[0]['total'] >= 0) {
data.total = itemData[0]['total'];
} else {
data.rows = itemData.map(v => parseObjLineToHump(v));
}
}
});
return data;
}
return result;
}
/**
* 强退用户会话
* @param tokenId 授权标识
* @returns object
*/
export async function logoutSession(id: string) {
const result = await request({
url: `/api/rest/databaseManagement/v1/omc_db/session?WHERE=id='${id}'`,
method: 'delete',
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && result.data.data) {
let rows = result.data.data.affectedRows;
if (rows) {
delete result.data;
return result;
} else {
return { code: RESULT_CODE_ERROR, msg: RESULT_MSG_ERROR[language] };
}
}
return result;
}

View File

@@ -5,5 +5,6 @@ export function getSystemInfo() {
return request({
url: '/monitor/system-info',
method: 'get',
timeout: 60_000,
});
}

66
src/api/ne/neConfig.ts Normal file
View File

@@ -0,0 +1,66 @@
import { request } from '@/plugins/http-fetch';
/**
* 网元参数配置可用属性值列表指定网元类型全部无分页
* @param query 查询参数
* @returns object
*/
export function getAllNeConfig(neType: string) {
return request({
url: `/ne/config/list/${neType}`,
method: 'get',
timeout: 60_000,
});
}
/**
* 网元参数配置数据信息
* @param params 数据 {neType,neId,paramName}
* @returns object
*/
export function getNeConfigData(params: Record<string, any>) {
return request({
url: `/ne/config/data`,
params,
method: 'get',
});
}
/**
* 网元参数配置数据更新
* @param data 数据 {neType,neId,paramName:"参数名",paramData:{参数},loc:"层级index仅array"}
* @returns object
*/
export function editNeConfigData(data: Record<string, any>) {
return request({
url: `/ne/config/data`,
method: 'put',
data: data,
});
}
/**
* 网元参数配置数据新增array
* @param data 数据 {neType,neId,paramName:"参数名",paramData:{参数},loc:"层级index"}
* @returns object
*/
export function addNeConfigData(data: Record<string, any>) {
return request({
url: `/ne/config/data`,
method: 'post',
data: data,
});
}
/**
* 网元参数配置数据删除array
* @param params 数据 {neType,neId,paramName:"参数名",loc:"层级index"}
* @returns object
*/
export function delNeConfigData(params: Record<string, any>) {
return request({
url: `/ne/config/data`,
method: 'delete',
params,
});
}

View File

@@ -0,0 +1,83 @@
import { request } from '@/plugins/http-fetch';
/**
* 网元配置文件备份记录列表
* @param query 查询参数
* @returns object
*/
export function listNeConfigBackup(query: Record<string, any>) {
return request({
url: '/ne/config/backup/list',
method: 'get',
params: query,
});
}
/**
* 网元配置文件备份记录修改
* @param data 数据 { id, name, remark }
* @returns object
*/
export function updateNeConfigBackup(data: Record<string, any>) {
return request({
url: '/ne/config/backup',
method: 'put',
data: data,
});
}
/**
* 网元配置文件备份记录下载
* @param id 记录ID
* @returns object
*/
export async function downNeConfigBackup(id: string) {
return await request({
url: '/ne/config/backup/download',
method: 'get',
params: { id },
responseType: 'blob',
timeout: 180_000,
});
}
/**
* 网元配置文件备份记录删除
* @param id 记录ID
* @returns object
*/
export async function delNeConfigBackup(id: string) {
return request({
url: '/ne/config/backup',
method: 'delete',
params: { id },
});
}
/**
* 网元配置文件备份导出
* @param data 数据 { neType, neId }
* @returns object
*/
export function exportNeConfigBackup(data: Record<string, any>) {
return request({
url: '/ne/config/backup/export',
method: 'post',
data: data,
responseType: 'blob',
timeout: 180_000,
});
}
/**
* 网元配置文件备份导入
* @param data 数据 { neType, neId, type, path }
* @returns object
*/
export function importNeConfigBackup(data: Record<string, any>) {
return request({
url: '/ne/config/backup/import',
method: 'post',
data: data,
});
}

View File

@@ -36,6 +36,8 @@ export function addNeInfo(data: Record<string, any>) {
url: `/ne/info`,
method: 'post',
data: data,
crypto: true,
timeout: 30_000,
});
}
@@ -49,6 +51,8 @@ export function updateNeInfo(data: Record<string, any>) {
url: `/ne/info`,
method: 'put',
data: data,
crypto: true,
timeout: 30_000,
});
}
@@ -67,7 +71,7 @@ export function delNeInfo(infoIds: string | number) {
/**
* 查询网元列表全部无分页
* @param query 查询参数 neType neId bandStatus
* @param query 查询参数 neType neId bandStatus bandHost
* @returns object
*/
export function listAllNeInfo(query: Record<string, any>) {
@@ -99,7 +103,7 @@ export function stateNeInfo(neType: string, neId: string) {
* @param neId 网元ID
* @returns object
*/
export function getTypeAndIDNeInfo(neType: string, neId: string) {
export function getNeInfoByTypeAndID(neType: string, neId: string) {
return request({
url: '/ne/info/byTypeAndID',
method: 'get',
@@ -108,29 +112,72 @@ export function getTypeAndIDNeInfo(neType: string, neId: string) {
}
/**
* 网元端配置文件读取
* 网元端OAM配置文件读取
* @param neType 网元类型
* @param neId 网元ID
* @param filePath 不带文件时重新覆盖返回目录列表
* @returns object
*/
export function getConfigFile(neType: string, neId: string, filePath: string) {
export function getOAMFile(neType: string, neId: string) {
return request({
url: '/ne/info/configFile',
url: '/ne/info/oamFile',
method: 'get',
params: { neType, neId, filePath },
params: { neType, neId },
});
}
/**
* 网元端配置文件写入
* @param data neType网元类型 neId网元ID filePath文件 content内容 sync同步到网元
* @param neType 网元类型
* @param neId 网元ID
* @param content 用json对象
* @param sync 同步到网元
* @returns object
*/
export function saveConfigFile(data: Record<string, any>) {
export function saveOAMFile(data: Record<string, any>) {
return request({
url: `/ne/info/configFile`,
url: `/ne/info/oamFile`,
method: 'put',
data: data,
timeout: 60_000,
});
}
/**
* 网元端公共配置文件读取
* @returns object
*/
export function getPara5GFilee() {
return request({
url: '/ne/info/para5GFile',
method: 'get',
});
}
/**
* 网元端公共配置文件写入
* @param content txt内容为字符串 其他文件格式都用json对象
* @param syncNe 同步到网元端 NeType@ NeId
* @returns object
*/
export function savePara5GFile(data: Record<string, any>) {
return request({
url: `/ne/info/para5GFile`,
method: 'put',
data: data,
timeout: 60_000,
});
}
/**
* 网元服务操作
* @param data 对象 {neType,neId,action}
* @returns object
*/
export function serviceNeAction(data: Record<string, any>) {
return request({
url: `/ne/action/service`,
method: 'put',
data: data,
timeout: 60_000,
});
}

View File

@@ -27,41 +27,16 @@ export function getNeLicense(licenseId: string | number) {
}
/**
* 网元授权新增
* @param data 网元对象
* 网元neType和neID查询
* @param neType 网元类型
* @param neId 网元ID
* @returns object
*/
export function addNeLicense(data: Record<string, any>) {
export function getNeLicenseByTypeAndID(neType: string, neId: string) {
return request({
url: `/ne/license`,
method: 'post',
data: data,
});
}
/**
* 网元授权修改
* @param data 网元对象
* @returns object
*/
export function updateNeLicense(data: Record<string, any>) {
return request({
url: `/ne/license`,
method: 'put',
data: data,
});
}
/**
* 网元授权删除
* @param id 信息ID
* @returns object
*/
export function delNeLicense(licenseIds: string | number) {
return request({
url: `/ne/license/${licenseIds}`,
method: 'delete',
timeout: 60_000,
url: `/ne/license/byTypeAndID`,
method: 'get',
params: { neType, neId },
});
}
@@ -81,7 +56,7 @@ export function codeNeLicense(neType: string, neId: string) {
/**
* 网元授权激活授权文件替换
* @param data 网元对象
* @param data 网元对象 {"neType": "", "neId": "", "licensePath": "", "reload": true}
* @returns object
*/
export function changeNeLicense(data: Record<string, any>) {

View File

@@ -36,6 +36,7 @@ export function addNeSoftware(data: Record<string, any>) {
url: `/ne/software`,
method: 'post',
data: data,
repeatSubmit: false,
});
}
@@ -66,15 +67,14 @@ export function delNeSoftware(softwareIds: string | number) {
}
/**
* 网元软件包安装检查
* @param data 网元对象
* 网元软件包设为网元新版本
* @param data data { "version": "2.2404.18", "neType": "SMF", "name": "smf-r2.2404.18-ub22.deb"}
* @returns object
*/
export function checkInstallNeSoftware(data: Record<string, any>) {
export function newNeVersion(data: Record<string, any>) {
return request({
url: `/ne/software/checkInstall`,
url: `/ne/software/newNeVersion`,
method: 'post',
data: data,
timeout: 180_000,
});
}
}

View File

@@ -27,40 +27,15 @@ export function getNeVersion(versionId: string | number) {
}
/**
* 网元版本新增
* @param data 网元对象
* 网元版本操作
* @param data {neType,neId,preinput:{参数},action:"upgrade"}
* @returns object
*/
export function addNeVersion(data: Record<string, any>) {
export function operateNeVersion(data: Record<string, any>) {
return request({
url: `/ne/version`,
url: `/ne/version/operate`,
method: 'post',
data: data,
});
}
/**
* 网元版本修改
* @param data 网元对象
* @returns object
*/
export function updateNeVersion(data: Record<string, any>) {
return request({
url: `/ne/version`,
method: 'put',
data: data,
});
}
/**
* 网元版本删除
* @param id 信息ID
* @returns object
*/
export function delNeVersion(versionIds: string | number) {
return request({
url: `/ne/version/${versionIds}`,
method: 'delete',
timeout: 60_000,
timeout: 180_000,
});
}

View File

@@ -19,10 +19,24 @@ export function listAMFDataUE(query: Record<string, any>) {
* @returns object
*/
export function delAMFDataUE(ueIds: string | number) {
return request({
url: `/neData/amf/ue/${ueIds}`,
method: 'delete',
timeout: 60_000,
});
}
return request({
url: `/neData/amf/ue/${ueIds}`,
method: 'delete',
timeout: 60_000,
});
}
/**
* AMF-UE会话列表导出
* @param data 查询列表条件
* @returns object
*/
export function exportAMFDataUE(data: Record<string, any>) {
return request({
url: '/neData/amf/ue/export',
method: 'post',
data,
responseType: 'blob',
timeout: 60_000,
});
}

View File

@@ -19,10 +19,24 @@ export function listIMSDataCDR(query: Record<string, any>) {
* @returns object
*/
export function delIMSDataCDR(cdrIds: string | number) {
return request({
url: `/neData/ims/cdr/${cdrIds}`,
method: 'delete',
timeout: 60_000,
});
}
return request({
url: `/neData/ims/cdr/${cdrIds}`,
method: 'delete',
timeout: 60_000,
});
}
/**
* IMS-CDR会话列表导出
* @param data 查询列表条件
* @returns object
*/
export function exportIMSDataCDR(data: Record<string, any>) {
return request({
url: '/neData/ims/cdr/export',
method: 'post',
data,
responseType: 'blob',
timeout: 60_000,
});
}

42
src/api/neData/mme.ts Normal file
View File

@@ -0,0 +1,42 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询MME-UE会话事件列表
* @param query 查询参数
* @returns object
*/
export function listMMEDataUE(query: Record<string, any>) {
return request({
url: '/neData/mme/ue/list',
method: 'get',
params: query,
});
}
/**
* MME-UE会话删除
* @param id 信息ID
* @returns object
*/
export function delMMEDataUE(ueIds: string | number) {
return request({
url: `/neData/mme/ue/${ueIds}`,
method: 'delete',
timeout: 60_000,
});
}
/**
* MME-UE会话列表导出
* @param data 查询列表条件
* @returns object
*/
export function exportMMEDataUE(data: Record<string, any>) {
return request({
url: '/neData/mme/ue/export',
method: 'post',
data,
responseType: 'blob',
timeout: 60_000,
});
}

55
src/api/neData/smf.ts Normal file
View File

@@ -0,0 +1,55 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询SMF-CDR会话事件
* @param query 查询参数
* @returns object
*/
export function listSMFDataCDR(query: Record<string, any>) {
return request({
url: '/neData/smf/cdr/list',
method: 'get',
params: query,
});
}
/**
* SMF-CDR会话删除
* @param id 信息ID
* @returns object
*/
export function delSMFDataCDR(cdrIds: string | number) {
return request({
url: `/neData/smf/cdr/${cdrIds}`,
method: 'delete',
timeout: 60_000,
});
}
/**
* SMF-CDR会话列表导出
* @param data 查询列表条件
* @returns object
*/
export function exportSMFDataCDR(data: Record<string, any>) {
return request({
url: '/neData/smf/cdr/export',
method: 'post',
data,
responseType: 'blob',
timeout: 60_000,
});
}
/**
* SMF-在线订阅用户列表信息
* @param query 查询参数
* @returns object
*/
export function listSMFSubscribers(query: Record<string, any>) {
return request({
url: '/neData/smf/subscribers',
method: 'get',
params: query,
});
}

42
src/api/neData/smsc.ts Normal file
View File

@@ -0,0 +1,42 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询SMSC-CDR会话事件
* @param query 查询参数
* @returns object
*/
export function listSMSCDataCDR(query: Record<string, any>) {
return request({
url: '/neData/smsc/cdr/list',
method: 'get',
params: query,
});
}
/**
* SMSC-CDR会话删除
* @param id 信息ID
* @returns object
*/
export function delSMSCDataCDR(cdrIds: string | number) {
return request({
url: `/neData/smsc/cdr/${cdrIds}`,
method: 'delete',
timeout: 60_000,
});
}
/**
* SMSC-CDR会话列表导出
* @param data 查询列表条件
* @returns object
*/
export function exportSMSCDataCDR(data: Record<string, any>) {
return request({
url: '/neData/smsc/cdr/export',
method: 'post',
data,
responseType: 'blob',
timeout: 60_000,
});
}

141
src/api/neData/udm_auth.ts Normal file
View File

@@ -0,0 +1,141 @@
import { request } from '@/plugins/http-fetch';
/**
* UDM鉴权用户重载数据
* @param neId 网元ID
* @returns object
*/
export function resetUDMAuth(neId: string) {
return request({
url: `/neData/udm/auth/resetData/${neId}`,
method: 'put',
timeout: 180_000,
});
}
/**
* UDM鉴权用户列表
* @param query 查询参数
* @returns object
*/
export function listUDMAuth(query: Record<string, any>) {
return request({
url: '/neData/udm/auth/list',
method: 'get',
params: query,
});
}
/**
* UDM鉴权用户信息
* @param neId 网元ID
* @param imsi IMSI
* @returns object
*/
export function getUDMAuth(neId: string, imsi: string) {
return request({
url: `/neData/udm/auth/${neId}/${imsi}`,
method: 'get',
});
}
/**
* UDM鉴权用户新增
* @param data 鉴权对象
* @returns object
*/
export function addUDMAuth(data: Record<string, any>) {
return request({
url: `/neData/udm/auth/${data.neId}`,
method: 'post',
data: data,
timeout: 180_000,
});
}
/**
* UDM鉴权用户批量新增
* @param data 鉴权对象
* @param num 数量
* @returns object
*/
export function batchAddUDMAuth(data: Record<string, any>, num: number) {
return request({
url: `/neData/udm/auth/${data.neId}/${num}`,
method: 'post',
data: data,
timeout: 180_000,
});
}
/**
* UDM鉴权用户修改
* @param data 鉴权对象
* @returns object
*/
export function updateUDMAuth(data: Record<string, any>) {
return request({
url: `/neData/udm/auth/${data.neId}`,
method: 'put',
data: data,
timeout: 180_000,
});
}
/**
* UDM鉴权用户删除
* @param neId 网元ID
* @param imsi IMSI
* @returns object
*/
export function delUDMAuth(neId: string, imsi: string) {
return request({
url: `/neData/udm/auth/${neId}/${imsi}`,
method: 'delete',
timeout: 180_000,
});
}
/**
* UDM鉴权用户批量删除
* @param neId 网元ID
* @param imsi IMSI
* @param num 数量
* @returns object
*/
export function batchDelUDMAuth(neId: string, imsi: string, num: number) {
return request({
url: `/neData/udm/auth/${neId}/${imsi}/${num}`,
method: 'delete',
timeout: 180_000,
});
}
/**
* UDM鉴权用户导入
* @param data 表单数据对象
* @returns object
*/
export function importUDMAuth(data: Record<string, any>) {
return request({
url: `/neData/udm/auth/import`,
method: 'post',
data,
timeout: 180_000,
});
}
/**
* UDM鉴权用户导出
* @param data 数据参数
* @returns bolb
*/
export function exportUDMAuth(data: Record<string, any>) {
return request({
url: '/neData/udm/auth/export',
method: 'post',
data,
responseType: 'blob',
timeout: 180_000,
});
}

140
src/api/neData/udm_sub.ts Normal file
View File

@@ -0,0 +1,140 @@
import { request } from '@/plugins/http-fetch';
/**
* UDM签约用户重载数据
* @param neId 网元ID
* @returns object
*/
export function resetUDMSub(neId: string) {
return request({
url: `/neData/udm/sub/resetData/${neId}`,
method: 'put',
timeout: 180_000,
});
}
/**
* UDM签约用户列表
* @param query 查询参数
* @returns object
*/
export function listUDMSub(query: Record<string, any>) {
return request({
url: '/neData/udm/sub/list',
method: 'get',
params: query,
});
}
/**
* UDM签约用户信息
* @param neId 网元ID
* @param imsi IMSI
* @returns object
*/
export function getUDMSub(neId: string, imsi: string) {
return request({
url: `/neData/udm/sub/${neId}/${imsi}`,
method: 'get',
});
}
/**
* UDM签约用户新增
* @param data 签约对象
* @returns object
*/
export function addUDMSub(data: Record<string, any>) {
return request({
url: `/neData/udm/sub/${data.neId}`,
method: 'post',
data: data,
timeout: 180_000,
});
}
/**
* UDM签约用户批量新增
* @param data 签约对象
* @param num 数量
* @returns object
*/
export function batchAddUDMSub(data: Record<string, any>, num: number) {
return request({
url: `/neData/udm/sub/${data.neId}/${num}`,
method: 'post',
data: data,
timeout: 180_000,
});
}
/**
* UDM签约用户修改
* @param data 签约对象
* @returns object
*/
export function updateUDMSub(data: Record<string, any>) {
return request({
url: `/neData/udm/sub/${data.neId}`,
method: 'put',
data: data,
timeout: 180_000,
});
}
/**
* UDM签约用户删除
* @param data 签约对象
* @returns object
*/
export function delUDMSub(neId: string, imsi: string) {
return request({
url: `/neData/udm/sub/${neId}/${imsi}`,
method: 'delete',
timeout: 180_000,
});
}
/**
* UDM签约用户批量删除
* @param neId 网元ID
* @param imsi IMSI
* @param num 数量
* @returns object
*/
export function batchDelUDMSub(neId: string, imsi: string, num: number) {
return request({
url: `/neData/udm/sub/${neId}/${imsi}/${num}`,
method: 'delete',
timeout: 180_000,
});
}
/**
* UDM签约用户导出
* @param data 数据参数
* @returns bolb
*/
export function exportUDMSub(data: Record<string, any>) {
return request({
url: '/neData/udm/sub/export',
method: 'post',
data,
responseType: 'blob',
timeout: 180_000,
});
}
/**
* UDM签约用户导入
* @param data 表单数据对象
* @returns object
*/
export function importUDMSub(data: Record<string, any>) {
return request({
url: `/neData/udm/sub/import`,
method: 'post',
data,
timeout: 180_000,
});
}

View File

@@ -1,138 +0,0 @@
import { request } from '@/plugins/http-fetch';
/**
* 签约鉴权导出
* @param query 查询参数
* @returns bolb
*/
export function exportAuth(query: Record<string, any>) {
return request({
url: '/ne/udm/auth/export',
method: 'post',
data: query,
responseType: 'blob',
timeout: 180_000,
});
}
/**
* 导入鉴权数据
* @param neId 网元ID
* @param data 表单数据对象
* @returns object
*/
export function importAuthData(data: FormData) {
return request({
url: `/ne/udm/auth/import`,
method: 'post',
data,
dataType: 'form-data',
timeout: 180_000,
});
}
/**
* 查询鉴权列表
* @param query 查询参数
* @returns object
*/
export function listAuth(query: Record<string, any>) {
return request({
url: '/ne/udm/auth/list',
method: 'get',
params: query,
});
}
/**
* 查询重新更新加载全部
* @param neId 网元ID
* @returns object
*/
export function loadAuth(neId: string) {
return request({
url: `/ne/udm/auth/resetData/${neId}`,
method: 'put',
timeout: 180_000,
});
}
/**
* 查询鉴权详细
* @param neId 网元ID
* @returns object
*/
export function getAuth(neId: string, imsi: string) {
return request({
url: `/ne/udm/auth/${neId}/${imsi}`,
method: 'get',
});
}
/**
* 修改鉴权
* @param data 鉴权对象
* @returns object
*/
export function updateAuth(data: Record<string, any>) {
return request({
url: `/ne/udm/auth/${data.neId}`,
method: 'put',
data: data,
timeout: 180_000,
});
}
/**
* 新增鉴权
* @param data 鉴权对象
* @returns object
*/
export function addAuth(data: Record<string, any>) {
return request({
url: `/ne/udm/auth/${data.neId}`,
method: 'post',
data: data,
timeout: 180_000,
});
}
/**
* 批量新增鉴权
* @param data 鉴权对象
* @returns object
*/
export function batchAuth(data: Record<string, any>) {
return request({
url: `/ne/udm/auth/${data.neID}/${data.num}`,
method: 'post',
data: data,
timeout: 180_000,
});
}
/**
* 删除鉴权
* @param data 鉴权对象
* @returns object
*/
export function delAuth(neId: string, imsi: string) {
return request({
url: `/ne/udm/auth/${neId}/${imsi}`,
method: 'delete',
timeout: 180_000,
});
}
/**
* 批量删除鉴权
* @param data 鉴权对象
* @returns object
*/
export function batchDelAuth(data: Record<string, any>) {
return request({
url: `/ne/udm/auth/${data.neID}/${data.imsi}/${data.num}`,
method: 'delete',
timeout: 180_000,
});
}

View File

@@ -25,8 +25,10 @@ export async function listBase5G(query: Record<string, any>) {
data.total = rows.length;
data.rows = rows;
}
// 模拟数据
// data.rows =[{"address":"192.168.1.137:38412","id":"217","name":"attach-enb-100000-20","ueNum":0}]
// data.rows = [{"address":"192.168.1.137:38412","id":"217","name":"attach-enb-100000-20","ueNum":0}]
// data.rows = [{address: "192.168.8.223", id: 257, name: "SmallCell", ueNum: 0}]
return data;
}

View File

@@ -52,9 +52,11 @@ export async function listUENumByIMS(neId: String) {
method: 'get',
});
if (result.code === RESULT_CODE_SUCCESS) {
return Object.assign(result, {
data: result.data['ueNum'],
});
let num = result.data['ueNum'] || 0;
if (num === 0) {
num = result.data.data['ueNum'] || 0;
}
return Object.assign(result, { data: num });
}
// 模拟数据

View File

@@ -136,6 +136,7 @@ export async function batchUpdateRule(data: Record<string, any>) {
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
method: 'put',
data: data,
timeout: 60_000,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
@@ -164,6 +165,7 @@ export async function addRule(data: Record<string, any>) {
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${data.neId}`,
method: 'post',
data: data,
timeout: 60_000,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && result.data?.status) {
@@ -186,6 +188,7 @@ export async function batchAddRule(data: Record<string, any>) {
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
method: 'post',
data: data,
timeout: 60_000,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
@@ -209,10 +212,11 @@ export async function batchAddRule(data: Record<string, any>) {
* @param data 规则对象
* @returns object
*/
export function delRule(neId: string, data: Record<string, any>) {
export function delRule(neId: string, imsi: string) {
return request({
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${neId}&imsi=${data.imsi}`,
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${neId}&imsi=${imsi}`,
method: 'delete',
timeout: 60_000,
});
}
@@ -225,5 +229,6 @@ export async function batchDelRule(data: Record<string, any>) {
return request({
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}&imsi=${data.imsi}`,
method: 'delete',
timeout: 60_000,
});
}

View File

@@ -1,6 +1,5 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
/**
* 查询列表
@@ -21,39 +20,66 @@ export async function listUEInfoBySMF(query: Record<string, any>) {
msg: result.msg,
};
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
const rows = parseObjLineToHump(result.data.data);
data.total = rows.length;
data.rows = rows;
if (result.code === RESULT_CODE_SUCCESS && result.data) {
if (Array.isArray(result.data.data)) {
const rows = result.data.data;
data.total = rows.length;
data.rows = rows;
} else {
Object.assign(data, result.data);
}
}
// 模拟数据
// data.code = RESULT_CODE_SUCCESS;
// data.total = 2;
// data.rows = [
// {
// imsi: 'imsi-460029004200044',
// msisdn: 'msisdn-12346002044',
// imsi: 'imsi-460000100000090',
// msisdn: 'msisdn-12307550090',
// pduSessionInfo: [
// {
// activeTime: '2023-11-29 18:39:06',
// activeTime: '2024-06-19 14:35:26',
// dnn: 'ims',
// ipv4: '10.10.48.97',
// ipv4: '10.10.48.8',
// ipv6: '',
// pduSessionID: 6,
// ranN3IP: '192.168.8.223',
// ranN3IP: '192.168.1.137',
// sstSD: '1-000001',
// tai: '46000-0001',
// tai: '46000-001124',
// upState: 'Active',
// upfN3IP: '192.168.1.161',
// },
// {
// activeTime: '2023-11-29 18:39:05',
// activeTime: '2024-06-19 14:35:26',
// dnn: 'cmnet',
// ipv4: '10.10.48.62',
// ipv4: '10.10.48.9',
// ipv6: '2001:4860:4860::/64',
// pduSessionID: 7,
// ranN3IP: '192.168.1.137',
// sstSD: '1-000001',
// tai: '46000-001124',
// upState: 'Active',
// upfN3IP: '192.168.1.161',
// },
// ],
// ratType: 'NR',
// },
// {
// imsi: 'imsi-460602072701180',
// msisdn: 'msisdn-123460600080',
// pduSessionInfo: [
// {
// activeTime: '2024-06-19 14:31:09',
// dnn: 'cmnet',
// ipv4: '10.10.48.4',
// ipv6: '',
// pduSessionID: 5,
// ranN3IP: '192.168.8.223',
// sstSD: '1-000001',
// tai: '46000-0001',
// upfN3IP: '192.168.1.163',
// tai: '46060-0001',
// upState: 'Active',
// upfN3IP: '192.168.1.161',
// },
// ],
// ratType: 'EUTRAN',

View File

@@ -1,139 +0,0 @@
import { request } from '@/plugins/http-fetch';
/**
* 签约列表导出
* @param query 查询参数
* @returns bolb
*/
export function exportSub(query: Record<string, any>) {
return request({
url: '/ne/udm/sub/export',
method: 'post',
data: query,
responseType: 'blob',
timeout: 180_000,
});
}
/**
* 导入签约数据
* @param neId 网元ID
* @param data 表单数据对象
* @returns object
*/
export function importSubData(data: FormData) {
return request({
url: `/ne/udm/sub/import`,
method: 'post',
data,
dataType: 'form-data',
timeout: 180_000,
});
}
/**
* 查询重新更新加载全部
* @param neId 网元ID
* @returns object
*/
export function loadSub(neId: string) {
return request({
url: `/ne/udm/sub/resetData/${neId}`,
method: 'put',
timeout: 180_000,
});
}
/**
* 查询签约列表
* @param query 查询参数
* @returns object
*/
export function listSub(query: Record<string, any>) {
return request({
url: '/ne/udm/sub/list',
method: 'get',
params: query,
});
}
/**
* 查询签约详细
* @param neId 网元ID
* @returns object
*/
export function getSub(neId: string, imsi: string) {
return request({
url: `/ne/udm/sub/${neId}/${imsi}`,
method: 'get',
});
}
/**
* 修改签约
* @param data 签约对象
* @param neId 网元ID
* @returns object
*/
export function updateSub(neId: string, data: Record<string, any>) {
return request({
url: `/ne/udm/sub/${neId}`,
method: 'put',
data: data,
timeout: 180_000,
});
}
/**
* 新增签约
* @param data 签约对象
* @returns object
*/
export function addSub(neID: string, data: Record<string, any>) {
return request({
url: `/ne/udm/sub/${neID}`,
method: 'post',
data: data,
timeout: 180_000,
});
}
/**
* 批量新增新增签约
* @param data 签约对象
* @returns object
*/
export function batchAddSub(data: Record<string, any>) {
return request({
url: `/ne/udm/sub/${data.neID}/${data.num}`,
method: 'post',
data: data,
timeout: 180_000,
});
}
/**
* 删除签约
* @param data 签约对象
* @returns object
*/
export function delSub(neId: string, imsi: string) {
return request({
url: `/ne/udm/sub/${neId}/${imsi}`,
method: 'delete',
timeout: 180_000,
});
}
/**
* 批量删除签约
* @param data 签约对象
* @returns object
*/
export function batchDelSub(data: Record<string, any>) {
return request({
url: `/ne/udm/sub/${data.neID}/${data.imsi}/${data.num}`,
method: 'delete',
timeout: 180_000,
});
}

View File

@@ -0,0 +1,19 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
import { parseDateToStr } from '@/utils/date-utils';
/**
* 新 查询自定义指标数据
* @param query 查询参数
* @returns object
*/
export async function listCustomData(query: Record<string, any>) {
// 发起请求
const result = await request({
url: `/pm/kpiC/report`,
method: 'get',
params: query,
});
return result;
}

View File

@@ -8,57 +8,72 @@ import { parseDateToStr } from '@/utils/date-utils';
* @param query 查询参数
* @returns object
*/
export async function listCustom(query: Record<string, any>) {
let totalSQL = 'select count(*) as total from pm_custom_title where 1=1 ';
let rowsSQL = 'select * from pm_custom_title where 1=1 ';
// export async function listCustom(query: Record<string, any>) {
// let totalSQL = 'select count(*) as total from pm_custom_title where 1=1 ';
// let rowsSQL = 'select * from pm_custom_title where 1=1 ';
// 查询
let querySQL = '';
if (query.neType) {
querySQL += ` and ne_type like '%${query.neType}%' `;
}
// // 查询
// let querySQL = '';
// if (query.neType) {
// querySQL += ` and ne_type like '%${query.neType}%' `;
// }
// 排序
let sortSql = ' order by update_time ';
if (query.sortOrder === 'asc') {
sortSql += ' asc ';
} else {
sortSql += ' desc ';
}
// 分页
const pageNum = (query.pageNum - 1) * query.pageSize;
const limtSql = ` limit ${pageNum},${query.pageSize} `;
// // 排序
// let sortSql = ' order by update_time ';
// if (query.sortOrder === 'asc') {
// sortSql += ' asc ';
// } else {
// sortSql += ' desc ';
// }
// // 分页
// const pageNum = (query.pageNum - 1) * query.pageSize;
// const limtSql = ` limit ${pageNum},${query.pageSize} `;
// // 发起请求
// const result = await request({
// url: `/api/rest/databaseManagement/v1/select/omc_db/pm_custom_title`,
// method: 'get',
// params: {
// totalSQL: totalSQL + querySQL,
// rowsSQL: rowsSQL + querySQL + sortSql + limtSql,
// },
// });
// // 解析数据
// if (result.code === RESULT_CODE_SUCCESS) {
// const data: DataList = {
// total: 0,
// rows: [],
// code: result.code,
// msg: result.msg,
// };
// result.data.data.forEach((item: any) => {
// const itemData = item['pm_custom_title'];
// if (Array.isArray(itemData)) {
// if (itemData.length === 1 && itemData[0]['total'] >= 0) {
// data.total = itemData[0]['total'];
// } else {
// data.rows = itemData.map(v => parseObjLineToHump(v));
// }
// }
// });
// return data;
// }
// return result;
// }
/**
* 新 查询自定义指标
* @param query 查询参数
* @returns object
*/
export async function listCustom(query?: Record<string, any>) {
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/select/omc_db/pm_custom_title`,
url: `/pm/kpiC/title/totalList`,
method: 'get',
params: {
totalSQL: totalSQL + querySQL,
rowsSQL: rowsSQL + querySQL + sortSql + limtSql,
},
params: query,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
const data: DataList = {
total: 0,
rows: [],
code: result.code,
msg: result.msg,
};
result.data.data.forEach((item: any) => {
const itemData = item['pm_custom_title'];
if (Array.isArray(itemData)) {
if (itemData.length === 1 && itemData[0]['total'] >= 0) {
data.total = itemData[0]['total'];
} else {
data.rows = itemData.map(v => parseObjLineToHump(v));
}
}
});
return data;
}
return result;
}
@@ -68,22 +83,10 @@ export async function listCustom(query: Record<string, any>) {
* @returns object
*/
export async function getCustom(id: string | number) {
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/select/omc_db/pm_custom_title`,
return request({
url: `/pm/kpiC/title/${id}`,
method: 'get',
params: {
SQL: `select * from pm_custom_title where id = ${id}`,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
let data = result.data.data[0];
return Object.assign(result, {
data: parseObjLineToHump(data['pm_custom_title'][0]),
});
}
return result;
}
/**
@@ -92,21 +95,10 @@ export async function getCustom(id: string | number) {
* @returns object
*/
export function addCustom(data: Record<string, any>) {
let obj: any = {
title: data.title,
ne_type: data.neType,
kpi_id: data.kpiId,
object_type: data.objectType,
expression: data.expression,
period: data.period,
description: data.description,
kpi_set: data.kpiSet,
};
return request({
url: `/api/rest/databaseManagement/v1/omc_db/pm_custom_title`,
url: `/pm/kpiC/title`,
method: 'post',
data: { 'data': [obj] },
data: data,
});
}
@@ -116,20 +108,10 @@ export function addCustom(data: Record<string, any>) {
* @returns object
*/
export function updateCustom(data: Record<string, any>) {
let obj: any = {
title: data.title,
ne_type: data.neType,
kpi_id: data.kpiId,
object_type: data.objectType,
expression: data.expression,
period: data.period,
description: data.description,
kpi_set: data.kpiSet,
};
return request({
url: `/api/rest/databaseManagement/v1/omc_db/pm_custom_title?WHERE=id=${data.id}`,
url: `/pm/kpiC/title/${data.id}`,
method: 'put',
data: { data: obj },
data: data,
});
}
@@ -139,8 +121,7 @@ export function updateCustom(data: Record<string, any>) {
*/
export async function delCustom(data: Record<string, any>) {
return request({
url: `/api/rest/databaseManagement/v1/omc_db/pm_custom_title?WHERE=id=${data.id}`,
url: `/pm/kpiC/title/${data.id}`,
method: 'delete',
});
}

View File

@@ -0,0 +1,52 @@
import { request } from '@/plugins/http-fetch';
/**
* 首次引导开始
* @returns object
*/
export function bootloaderStart() {
return request({
url: `/bootloader`,
method: 'post',
whithToken: false,
repeatSubmit: false,
});
}
/**
* 首次引导完成
* @returns object
*/
export function bootloaderDone() {
return request({
url: `/bootloader`,
method: 'put',
});
}
/**
* 引导系统数据重置
* @returns object
*/
export function bootloaderReset() {
return request({
url: `/bootloader`,
method: 'delete',
timeout: 180_000
});
}
/**
* 管理员账号变更
* @returns object
*/
export function bootloaderAccount(username: string, password: string) {
return request({
url: `/bootloader/account`,
method: 'put',
data: {
username,
password,
},
});
}

View File

@@ -18,6 +18,7 @@ export async function downloadFile(filePath: string, range?: string) {
method: 'get',
headers: range ? { range } : {},
responseType: 'blob',
timeout: 60_000,
});
}
@@ -79,6 +80,7 @@ export function uploadFile(data: FormData) {
method: 'post',
data,
dataType: 'form-data',
timeout: 180_000,
});
}
@@ -169,6 +171,7 @@ export function chunkCheck(identifier: string, fileName: string) {
url: '/file/chunkCheck',
method: 'post',
data: { identifier, fileName },
timeout: 60_000,
});
}
@@ -188,6 +191,7 @@ export function chunkMerge(
url: '/file/chunkMerge',
method: 'post',
data: { identifier, fileName, subPath },
timeout: 60_000,
});
}
@@ -202,6 +206,7 @@ export function chunkUpload(data: FormData) {
method: 'post',
data,
dataType: 'form-data',
timeout: 60_000,
});
}
@@ -214,6 +219,7 @@ export function transferStaticFile(data: Record<string, any>) {
url: `/file/transferStaticFile`,
method: 'post',
data,
timeout: 60_000,
});
}
@@ -241,6 +247,7 @@ export async function uploadFileToNE(
neType,
neId,
},
timeout: 60_000,
});
return transferToNeFileRes;
}

20
src/api/tool/iperf.ts Normal file
View File

@@ -0,0 +1,20 @@
import { request } from '@/plugins/http-fetch';
// iperf 版本信息
export function iperfV(data: Record<string, string>) {
return request({
url: '/tool/iperf/v',
method: 'get',
params: data,
});
}
// iperf 软件安装
export function iperfI(data: Record<string, string>) {
return request({
url: '/tool/iperf/i',
method: 'post',
data: data,
timeout: 60_000,
});
}

View File

@@ -1,7 +1,7 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询文件列表列表
* 查询网元端文件列表
* @param query 查询参数
* @returns object
*/
@@ -14,7 +14,7 @@ export function listNeFiles(query: Record<string, any>) {
}
/**
* 从网元获取文件
* 从网元到本地获取文件
* @param query 查询参数
* @returns object
*/
@@ -27,3 +27,24 @@ export function getNeFile(query: Record<string, any>) {
timeout: 180_000,
});
}
// 从网元到本地获取目录压缩为ZIP
export function getNeDirZip(data: Record<string, any>) {
return request({
url: '/ne/action/pullDirZip',
method: 'get',
params: data,
responseType: 'blob',
timeout: 60_000,
});
}
// 查看网元端文件内容
export function getNeViewFile(data: Record<string, any>) {
return request({
url: '/ne/action/viewFile',
method: 'get',
params: data,
timeout: 60_000,
});
}

10
src/api/tool/ping.ts Normal file
View File

@@ -0,0 +1,10 @@
import { request } from '@/plugins/http-fetch';
// ping 网元端版本信息
export function pingV(data: Record<string, string>) {
return request({
url: '/tool/ping/v',
method: 'get',
params: data,
});
}

64
src/api/trace/packet.ts Normal file
View File

@@ -0,0 +1,64 @@
import { request } from '@/plugins/http-fetch';
/**
* 信令跟踪网卡设备列表
* @returns
*/
export function packetDevices() {
return request({
url: '/trace/packet/devices',
method: 'get',
});
}
/**
* 信令跟踪开始
* @param data 对象
* @returns
*/
export function packetStart(data: Record<string, any>) {
return request({
url: '/trace/packet/start',
method: 'post',
data: data,
});
}
/**
* 信令跟踪结束
* @param data 对象
* @returns
*/
export function packetStop(taskNo: string) {
return request({
url: '/trace/packet/stop',
method: 'post',
data: { taskNo },
});
}
/**
* 信令跟踪过滤
* @param data 对象
* @returns
*/
export function packetFilter(taskNo: string, expr: string) {
return request({
url: '/trace/packet/filter',
method: 'put',
data: { taskNo, expr },
});
}
/**
* 信令跟踪续期保活
* @param data 对象
* @returns
*/
export function packetKeep(taskNo: string, duration: number = 120) {
return request({
url: '/trace/packet/keep-alive',
method: 'put',
data: { taskNo, duration },
});
}

View File

@@ -3,26 +3,29 @@ import { request } from '@/plugins/http-fetch';
// 网元抓包PACP 开始
export function dumpStart(data: Record<string, string>) {
return request({
url: '/tcpdump/start',
url: '/trace/tcpdump/start',
method: 'post',
data: data,
timeout: 60_000,
});
}
// 网元抓包PACP 结束
export function dumpStop(data: Record<string, string>) {
return request({
url: '/tcpdump/stop',
url: '/trace/tcpdump/stop',
method: 'post',
data: data,
timeout: 60_000,
});
}
// UPF标准版内部抓包
export function traceUPF(data: Record<string, string>) {
return request({
url: '/tcpdump/traceUPF',
url: '/trace/tcpdump/upf',
method: 'post',
data: data,
timeout: 60_000,
});
}

104
src/api/trace/task.ts Normal file
View File

@@ -0,0 +1,104 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
/**
* 查询跟踪任务列表
* @param query 查询参数
* @returns object
*/
export async function listTraceTask(query: Record<string, any>) {
return request({
url: '/trace/task/list',
method: 'get',
params: query,
});
}
/**
* 查询跟踪任务信息
* @param id 网元ID
* @returns object
*/
export async function getTraceTask(id: string | number) {
return request({
url: `/trace/task/${id}`,
method: 'get',
});
}
/**
* 新增任务
* @param data 网元对象
* @returns object
*/
export function addTraceTask(data: Record<string, any>) {
return request({
url: `/trace/task`,
method: 'post',
data: data,
});
}
/**
* 修改任务
* @param data 网元对象
* @returns object
*/
export function updateTraceTask(data: Record<string, any>) {
return request({
url: `/trace/task`,
method: 'put',
data: data,
});
}
/**
* 跟踪任务删除
* @param ids ID多个逗号分隔
* @returns object
*/
export async function delTraceTask(ids: string) {
return request({
url: `/trace/task/${ids}`,
method: 'delete',
});
}
/**
* 跟踪任务文件
* @param query 对象
* @returns object
*/
export function filePullTask(traceId: string) {
return request({
url: '/trace/task/filePull',
method: 'get',
params: { traceId },
responseType: 'blob',
timeout: 60_000,
});
}
/**
* 获取网元跟踪接口列表
* @returns object
*/
export async function getNeTraceInterfaceAll() {
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/elementType/omc_db/objectType/ne_info`,
method: 'get',
params: {
SQL: `SELECT ne_type,interface FROM trace_info GROUP BY ne_type,interface`,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
let data = result.data.data[0];
return Object.assign(result, {
data: parseObjLineToHump(data['trace_info']),
});
}
return result;
}

83
src/api/trace/taskHLR.ts Normal file
View File

@@ -0,0 +1,83 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询跟踪任务列表
* @param query 查询参数
* @returns object
*/
export function listTaskHLR(query: Record<string, any>) {
return request({
url: '/trace/task/hlr/list',
method: 'get',
params: query,
});
}
/**
* 跟踪任务删除
* @param ids 任务ID
* @returns object
*/
export function delTaskHLR(ids: string | number) {
return request({
url: `/trace/task/hlr/${ids}`,
method: 'delete',
timeout: 60_000,
});
}
/**
* 跟踪任务创建
* @param data 对象
* @returns object
*/
export function startTaskHLR(data: Record<string, any>) {
return request({
url: '/trace/task/hlr/start',
method: 'post',
data: data,
timeout: 60_000,
});
}
/**
* 跟踪任务停止
* @param data 对象
* @returns object
*/
export function stopTaskHLR(data: Record<string, any>) {
return request({
url: '/trace/task/hlr/stop',
method: 'post',
data: data,
timeout: 60_000,
});
}
/**
* 跟踪任务文件
* @param data 对象
* @returns object
*/
export function fileTaskHLR(data: Record<string, any>) {
return request({
url: '/trace/task/hlr/file',
method: 'post',
data: data,
});
}
/**
* 跟踪任务文件从网元到本地
* @param query 对象
* @returns object
*/
export function filePullTaskHLR(query: Record<string, any>) {
return request({
url: '/trace/task/hlr/filePull',
method: 'get',
params: query,
responseType: 'blob',
timeout: 60_000,
});
}

View File

@@ -1,154 +0,0 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch';
import { parseObjLineToHump } from '@/utils/parse-utils';
/**
* 查询任务列表
* @param query 查询参数
* @returns object
*/
export async function listTraceTask(query: Record<string, any>) {
let totalSQL = 'select count(*) as total from trace_task where 1=1 ';
let rowsSQL = 'select * from trace_task where 1=1 ';
// 查询
let querySQL = '';
if (query.imsi) {
querySQL += ` and imsi like '%${query.imsi}%' `;
}
if (query.beginTime) {
querySQL += ` and start_time >= '${query.beginTime}' `;
}
if (query.endTime) {
querySQL += ` and end_time <= '${query.endTime}' `;
}
// 分页
const pageNum = (query.pageNum - 1) * query.pageSize;
const limtSql = ` limit ${pageNum},${query.pageSize} `;
// 排序
let sortSql = ' order by start_time ';
if (query.sortOrder === 'asc') {
sortSql += ' asc ';
} else {
sortSql += ' desc ';
}
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/select/omc_db/trace_task`,
method: 'get',
params: {
totalSQL: totalSQL + querySQL,
rowsSQL: rowsSQL + querySQL + sortSql + limtSql,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
const data: DataList = {
total: 0,
rows: [],
code: result.code,
msg: result.msg,
};
result.data.data.forEach((item: any) => {
const itemData = item['trace_task'];
if (Array.isArray(itemData)) {
if (itemData.length === 1 && itemData[0]['total'] >= 0) {
data.total = itemData[0]['total'];
} else {
data.rows = itemData.map(v => parseObjLineToHump(v));
}
}
});
return data;
}
return result;
}
/**
* 查询任务详细
* @param id 网元ID
* @returns object
*/
export async function getTraceTask(id: string | number) {
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/select/omc_db/trace_task`,
method: 'get',
params: {
SQL: `select * from trace_task where id = ${id}`,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
let data = result.data.data[0];
return Object.assign(result, {
data: parseObjLineToHump(data['trace_task'][0]),
});
}
return result;
}
/**
* 新增任务
* @param data 网元对象
* @returns object
*/
export function addTraceTask(data: Record<string, any>) {
return request({
url: `/api/rest/traceManagement/v1/subscriptions`,
method: 'post',
data: data,
});
}
/**
* 修改任务
* @param data 网元对象
* @returns object
*/
export function updateTraceTask(data: Record<string, any>) {
return request({
url: `/api/rest/traceManagement/v1/subscriptions`,
method: 'put',
data: data,
});
}
/**
* 删除任务
* @param noticeId 网元ID
* @returns object
*/
export async function delTraceTask(id: string) {
return request({
url: `/api/rest/traceManagement/v1/subscriptions?id=${id}`,
method: 'delete',
});
}
/**
* 获取网元跟踪接口列表
* @returns object
*/
export async function getNeTraceInterfaceAll() {
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/elementType/omc_db/objectType/ne_info`,
method: 'get',
params: {
SQL: `SELECT ne_type,interface FROM trace_info GROUP BY ne_type,interface`,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
let data = result.data.data[0];
return Object.assign(result, {
data: parseObjLineToHump(data['trace_info']),
});
}
return result;
}

View File

@@ -0,0 +1,11 @@
/**
* worker文件-静态资源文件路径
*/
const baseUrl = import.meta.env.VITE_HISTORY_BASE_URL;
export const scriptUrl = `${
baseUrl.length === 1 && baseUrl.indexOf('/') === 0
? ''
: baseUrl.indexOf('/') === -1
? '/' + baseUrl
: baseUrl
}/wiregasm/worker.js`;

View File

@@ -1,9 +1,10 @@
<template>
<a-modal
<ProModal
:drag="true"
:destroyOnClose="true"
:title="t('components.CronModal.title')"
:visible="props.visible"
:body-style="{ padding: '0 24px' }"
:destroy-on-close="true"
@cancel="fnCronModal(false)"
@ok="fnCronModal(true)"
>
@@ -31,7 +32,7 @@
v-model:value="cronStr"
disabled
/>
</a-modal>
</ProModal>
</template>
<script lang="ts" setup>
import CronSecond from './components/Second.vue';

View File

@@ -1,13 +1,13 @@
<script setup lang="ts">
import { computed } from 'vue';
import { computed, PropType } from 'vue';
const props = defineProps({
/**数据 */
options: {
type: Array,
type: Array as PropType<DictType[]>,
},
/**当前的值对应数据中的项字段 */
valueField: {
type: String,
type: String as PropType<keyof DictType>,
default: 'value',
},
/**当前的值 */
@@ -16,7 +16,7 @@ const props = defineProps({
default: '',
},
/**数据默认值,当前值不存在时 */
valueOption: {
valueDefault: {
type: [Number, String],
},
});
@@ -24,13 +24,13 @@ const props = defineProps({
/**遍历找到对应值数据项 */
const item = computed(() => {
if (Array.isArray(props.options) && props.options.length > 0) {
let option = (props.options as any[]).find(
let option = props.options.find(
item => `${item[props.valueField]}` === `${props.value}`
);
// 数据默认值
if (props.valueOption != undefined && !option) {
option = (props.options as any[]).find(
item => `${item[props.valueField]}` === `${props.valueOption }`
if (!option && props.valueDefault != undefined) {
option = props.options.find(
item => `${item[props.valueField]}` === `${props.valueDefault}`
);
}
return option;
@@ -41,14 +41,10 @@ const item = computed(() => {
<template>
<template v-if="item">
<a-tag
v-if="item.elTagType"
:class="item.elTagClass"
:color="item.elTagType"
>
<a-tag v-if="item.tagType" :class="item.tagClass" :color="item.tagType">
{{ item.label }}
</a-tag>
<span v-else :class="item.elTagClass">
<span v-else :class="item.tagClass">
{{ item.label }}
</span>
</template>

View File

@@ -1,168 +0,0 @@
<script setup lang="ts">
import { ref, watch, watchEffect, CSSProperties, computed } from 'vue';
import { useDraggable } from '@vueuse/core';
const emit = defineEmits(['update:visible', 'ok', 'cancel']);
/**于a-modal保持一致 */
const props = defineProps({
/**是否弹出显示,必传 */
visible: {
type: Boolean,
required: true,
},
/**窗口标题 */
title: {
type: String,
default: '',
},
/**窗口宽度 */
width: {
type: [String, Number],
default: '520px',
},
bodyStyle: {
type: Object,
default: {},
},
keyboard: {
type: Boolean,
default: true,
},
mask: {
type: Boolean,
default: true,
},
maskClosable: {
type: Boolean,
default: true,
},
maskStyle: {
type: Object,
default: {},
},
destroyOnClose: {
type: Boolean,
default: false,
},
confirmLoading: {
type: Boolean,
default: false,
},
footer: {
type: Object as any,
},
});
// 对标题进行监听
const modalTitleRef = ref<HTMLElement | null>(null);
const { x, y, isDragging } = useDraggable(modalTitleRef);
const startX = ref<number>(0);
const startY = ref<number>(0);
const startedDrag = ref(false);
const transformX = ref(0);
const transformY = ref(0);
const preTransformX = ref(0);
const preTransformY = ref(0);
const dragRect = ref({ left: 0, right: 0, top: 0, bottom: 0 });
watch([x, y], () => {
if (!startedDrag.value) {
startX.value = x.value;
startY.value = y.value;
const bodyRect = document.body.getBoundingClientRect();
const titleRectEl = modalTitleRef.value;
if (titleRectEl) {
const titleRect = titleRectEl.getBoundingClientRect();
dragRect.value.right = bodyRect.width - (titleRect.width + 24);
dragRect.value.bottom = bodyRect.height - (titleRect.height + 16);
}
preTransformX.value = transformX.value;
preTransformY.value = transformY.value;
}
startedDrag.value = true;
});
watchEffect(() => {
if (!isDragging.value) {
startedDrag.value = false;
}
if (startedDrag.value) {
const dragRectX = Math.min(
Math.max(dragRect.value.left + 24, x.value),
dragRect.value.right
);
transformX.value = preTransformX.value + dragRectX - startX.value;
const dragRectY = Math.min(
Math.max(dragRect.value.top + 16, y.value),
dragRect.value.bottom
);
transformY.value = preTransformY.value + dragRectY - startY.value;
}
});
// 位移
const transformStyle = computed<CSSProperties>(() => {
return {
transform: `translate(${transformX.value}px, ${transformY.value}px)`,
};
});
/**监听是否显示,位置还原 */
watch(
() => props.visible,
val => {
if (val) {
transformX.value = 0;
transformY.value = 0;
}
}
);
</script>
<template>
<a-modal
wrapClassName="draggable-modal"
:width="props.width"
:keyboard="props.keyboard"
:mask="props.mask"
:mask-closable="props.maskClosable"
:visible="props.visible"
:confirm-loading="props.confirmLoading"
:body-style="props.bodyStyle"
:mask-style="props.maskStyle"
:destroy-on-close="props.destroyOnClose"
:footer="props.footer"
@ok="(e:any) => emit('ok', e)"
@cancel="(e:any) => emit('cancel', e)"
>
<template #title>
<div
ref="modalTitleRef"
class="draggable-modal-title"
v-text="title"
></div>
</template>
<template #modalRender="{ originVNode }">
<div :style="transformStyle">
<component :is="originVNode" />
</div>
</template>
<slot></slot>
</a-modal>
</template>
<style lang="less">
.draggable-modal {
// 穿透选择文字
// 给a-modal设置 get-container=".ant-pro-page-container"
// 防止跳转显示
// &.ant-modal-wrap {
// pointer-events: none;
// }
&-title {
width: 100%;
cursor: move;
}
}
</style>

View File

@@ -0,0 +1,141 @@
<script setup lang="ts">
import { onMounted, onUnmounted, computed } from 'vue';
import useI18n from '@/hooks/useI18n';
import useMaskStore from '@/store/modules/mask';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { useRoute, useRouter } from 'vue-router';
import { useThrottleFn } from '@vueuse/core';
import { getConfigKey } from '@/api/system/config';
const maskStore = useMaskStore();
const route = useRoute();
const router = useRouter();
const { t } = useI18n();
/**显示遮罩 */
const isVisible = computed(() => !['none', 'lock'].includes(maskStore.type));
// 用户无操作一段时间后进行锁屏
function idleTimeout(time: number, callback: Function) {
if (time === 0) return;
let timeoutId: any;
let idleTime = 0;
function resetIdleTime() {
idleTime = 0;
}
// 监听用户活动事件
document.addEventListener('mousemove', useThrottleFn(resetIdleTime, 1000));
document.addEventListener('keydown', useThrottleFn(resetIdleTime, 1000));
document.addEventListener('click', useThrottleFn(resetIdleTime, 1000));
// 定时检查用户是否长时间无操作
timeoutId = setInterval(() => {
idleTime += 1000;
if (idleTime >= time) {
clearTimeout(timeoutId);
callback();
}
}, 1000);
}
/**组件实例挂载之后调用 */
onMounted(() => {
// 本地锁定类型设置;
maskStore.handleMaskType(maskStore.type);
getConfigKey('sys.lockTime')
.then(res => {
if (res.code === RESULT_CODE_SUCCESS && res.data) {
maskStore.lockTimeout = +res.data;
}
maskStore.handleMaskType(maskStore.type);
// 是锁屏的调整到页面
if (maskStore.type === 'lock') {
maskStore.handleMaskType('lock');
router.push({ name: 'LockScreen', query: { redirect: route.path } });
}
})
.finally(() => {
// 无操作x秒后跳转锁屏
idleTimeout(maskStore.lockTimeout * 1000, () => {
if (route.name === 'LockScreen') return;
maskStore.handleMaskType('lock');
router.push({ name: 'LockScreen', query: { redirect: route.path } });
});
});
});
/**组件实例被卸载之后调用 */
onUnmounted(() => {});
</script>
<template>
<a-modal
v-model:visible="isVisible"
get-container="#app"
:footer="null"
:zIndex="1008"
:closable="false"
:keyboard="false"
:centered="true"
:maskClosable="false"
:maskStyle="{
backdropFilter: 'blur(10px)',
WebkitBackdropFilter: 'blur(10px)',
}"
wrapClassName="lock-screen"
:wrap-style="{
background: 'rgba(0, 0, 0, 0.85)',
}"
>
<!-- 锁屏-OMC重启升级 -->
<div class="lock-screen_reload" v-if="maskStore.type === 'reload'">
<LoadingOutlined style="font-size: 56px" />
<div class="text">
{{ t('components.LockScreen.backReload') }}
</div>
<div class="desc">
{{ t('components.LockScreen.backReload2') }}
</div>
</div>
<!-- 锁屏-OMC系统重置 -->
<div class="lock-screen_reload" v-if="maskStore.type === 'reset'">
<LoadingOutlined style="font-size: 56px" />
<div class="text">
{{ t('components.LockScreen.systemReset') }}
</div>
<div class="desc">
{{ t('components.LockScreen.systemReset2') }}
</div>
</div>
</a-modal>
</template>
<style lang="less" scoped>
.lock-screen_reload {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: transparent;
color: #fff;
& .text {
font-size: 24px;
font-weight: bold;
letter-spacing: 4px;
margin-top: 24px;
}
& .desc {
margin-top: 8px;
font-size: 16px;
}
}
</style>
<style lang="less">
.lock-screen {
.ant-modal-content {
background-color: transparent;
box-shadow: none;
}
}
</style>

View File

@@ -0,0 +1,252 @@
//* THIS FILE IS AUTO-GENERATED. DO NOT EDIT.
export default {
af: "Afghanistan",
ax: "Åland Islands",
al: "Albania",
dz: "Algeria",
as: "American Samoa",
ad: "Andorra",
ao: "Angola",
ai: "Anguilla",
aq: "Antarctica",
ag: "Antigua & Barbuda",
ar: "Argentina",
am: "Armenia",
aw: "Aruba",
au: "Australia",
at: "Austria",
az: "Azerbaijan",
bs: "Bahamas",
bh: "Bahrain",
bd: "Bangladesh",
bb: "Barbados",
by: "Belarus",
be: "Belgium",
bz: "Belize",
bj: "Benin",
bm: "Bermuda",
bt: "Bhutan",
bo: "Bolivia",
ba: "Bosnia & Herzegovina",
bw: "Botswana",
bv: "Bouvet Island",
br: "Brazil",
io: "British Indian Ocean Territory",
vg: "British Virgin Islands",
bn: "Brunei",
bg: "Bulgaria",
bf: "Burkina Faso",
bi: "Burundi",
kh: "Cambodia",
cm: "Cameroon",
ca: "Canada",
cv: "Cape Verde",
bq: "Caribbean Netherlands",
ky: "Cayman Islands",
cf: "Central African Republic",
td: "Chad",
cl: "Chile",
cn: "China",
cx: "Christmas Island",
cc: "Cocos (Keeling) Islands",
co: "Colombia",
km: "Comoros",
cg: "Congo - Brazzaville",
cd: "Congo - Kinshasa",
ck: "Cook Islands",
cr: "Costa Rica",
ci: "Côte dIvoire",
hr: "Croatia",
cu: "Cuba",
cw: "Curaçao",
cy: "Cyprus",
cz: "Czechia",
dk: "Denmark",
dj: "Djibouti",
dm: "Dominica",
do: "Dominican Republic",
ec: "Ecuador",
eg: "Egypt",
sv: "El Salvador",
gq: "Equatorial Guinea",
er: "Eritrea",
ee: "Estonia",
sz: "Eswatini",
et: "Ethiopia",
fk: "Falkland Islands",
fo: "Faroe Islands",
fj: "Fiji",
fi: "Finland",
fr: "France",
gf: "French Guiana",
pf: "French Polynesia",
tf: "French Southern Territories",
ga: "Gabon",
gm: "Gambia",
ge: "Georgia",
de: "Germany",
gh: "Ghana",
gi: "Gibraltar",
gr: "Greece",
gl: "Greenland",
gd: "Grenada",
gp: "Guadeloupe",
gu: "Guam",
gt: "Guatemala",
gg: "Guernsey",
gn: "Guinea",
gw: "Guinea-Bissau",
gy: "Guyana",
ht: "Haiti",
hm: "Heard & McDonald Islands",
hn: "Honduras",
hk: "Hong Kong SAR China",
hu: "Hungary",
is: "Iceland",
in: "India",
id: "Indonesia",
ir: "Iran",
iq: "Iraq",
ie: "Ireland",
im: "Isle of Man",
il: "Israel",
it: "Italy",
jm: "Jamaica",
jp: "Japan",
je: "Jersey",
jo: "Jordan",
kz: "Kazakhstan",
ke: "Kenya",
ki: "Kiribati",
kw: "Kuwait",
kg: "Kyrgyzstan",
la: "Laos",
lv: "Latvia",
lb: "Lebanon",
ls: "Lesotho",
lr: "Liberia",
ly: "Libya",
li: "Liechtenstein",
lt: "Lithuania",
lu: "Luxembourg",
mo: "Macao SAR China",
mg: "Madagascar",
mw: "Malawi",
my: "Malaysia",
mv: "Maldives",
ml: "Mali",
mt: "Malta",
mh: "Marshall Islands",
mq: "Martinique",
mr: "Mauritania",
mu: "Mauritius",
yt: "Mayotte",
mx: "Mexico",
fm: "Micronesia",
md: "Moldova",
mc: "Monaco",
mn: "Mongolia",
me: "Montenegro",
ms: "Montserrat",
ma: "Morocco",
mz: "Mozambique",
mm: "Myanmar (Burma)",
na: "Namibia",
nr: "Nauru",
np: "Nepal",
nl: "Netherlands",
nc: "New Caledonia",
nz: "New Zealand",
ni: "Nicaragua",
ne: "Niger",
ng: "Nigeria",
nu: "Niue",
nf: "Norfolk Island",
kp: "North Korea",
mk: "North Macedonia",
mp: "Northern Mariana Islands",
no: "Norway",
om: "Oman",
pk: "Pakistan",
pw: "Palau",
ps: "Palestinian Territories",
pa: "Panama",
pg: "Papua New Guinea",
py: "Paraguay",
pe: "Peru",
ph: "Philippines",
pn: "Pitcairn Islands",
pl: "Poland",
pt: "Portugal",
pr: "Puerto Rico",
qa: "Qatar",
re: "Réunion",
ro: "Romania",
ru: "Russia",
rw: "Rwanda",
ws: "Samoa",
sm: "San Marino",
st: "São Tomé & Príncipe",
sa: "Saudi Arabia",
sn: "Senegal",
rs: "Serbia",
sc: "Seychelles",
sl: "Sierra Leone",
sg: "Singapore",
sx: "Sint Maarten",
sk: "Slovakia",
si: "Slovenia",
sb: "Solomon Islands",
so: "Somalia",
za: "South Africa",
gs: "South Georgia & South Sandwich Islands",
kr: "South Korea",
ss: "South Sudan",
es: "Spain",
lk: "Sri Lanka",
bl: "St. Barthélemy",
sh: "St. Helena",
kn: "St. Kitts & Nevis",
lc: "St. Lucia",
mf: "St. Martin",
pm: "St. Pierre & Miquelon",
vc: "St. Vincent & Grenadines",
sd: "Sudan",
sr: "Suriname",
sj: "Svalbard & Jan Mayen",
se: "Sweden",
ch: "Switzerland",
sy: "Syria",
tw: "Taiwan",
tj: "Tajikistan",
tz: "Tanzania",
th: "Thailand",
tl: "Timor-Leste",
tg: "Togo",
tk: "Tokelau",
to: "Tonga",
tt: "Trinidad & Tobago",
tn: "Tunisia",
tr: "Turkey",
tm: "Turkmenistan",
tc: "Turks & Caicos Islands",
tv: "Tuvalu",
um: "U.S. Outlying Islands",
vi: "U.S. Virgin Islands",
ug: "Uganda",
ua: "Ukraine",
ae: "United Arab Emirates",
gb: "United Kingdom",
us: "United States",
uy: "Uruguay",
uz: "Uzbekistan",
vu: "Vanuatu",
va: "Vatican City",
ve: "Venezuela",
vn: "Vietnam",
wf: "Wallis & Futuna",
eh: "Western Sahara",
ye: "Yemen",
zm: "Zambia",
zw: "Zimbabwe",
};

View File

@@ -0,0 +1,4 @@
import countryTranslations from './countries';
import interfaceTranslations from './interface';
export default { ...countryTranslations, ...interfaceTranslations };

View File

@@ -0,0 +1,14 @@
//* English. Translated by: Jack O'Connor (jackocnr).
export default {
selectedCountryAriaLabel: "Selected country",
noCountrySelected: "No country selected",
countryListAriaLabel: "List of countries",
searchPlaceholder: "Search",
zeroSearchResults: "No results found",
oneSearchResult: "1 result found",
multipleSearchResults: "${count} results found",
// additional countries (not supported by country-list library)
ac: "Ascension Island",
xk: "Kosovo",
};

View File

@@ -0,0 +1,252 @@
//* THIS FILE IS AUTO-GENERATED. DO NOT EDIT.
export default {
al: "阿尔巴尼亚",
dz: "阿尔及利亚",
af: "阿富汗",
ar: "阿根廷",
ae: "阿拉伯联合酋长国",
aw: "阿鲁巴",
om: "阿曼",
az: "阿塞拜疆",
eg: "埃及",
et: "埃塞俄比亚",
ie: "爱尔兰",
ee: "爱沙尼亚",
ad: "安道尔",
ao: "安哥拉",
ai: "安圭拉",
ag: "安提瓜和巴布达",
at: "奥地利",
ax: "奥兰群岛",
au: "澳大利亚",
bb: "巴巴多斯",
pg: "巴布亚新几内亚",
bs: "巴哈马",
pk: "巴基斯坦",
py: "巴拉圭",
ps: "巴勒斯坦领土",
bh: "巴林",
pa: "巴拿马",
br: "巴西",
by: "白俄罗斯",
bm: "百慕大",
bg: "保加利亚",
mp: "北马里亚纳群岛",
mk: "北马其顿",
bj: "贝宁",
be: "比利时",
is: "冰岛",
pr: "波多黎各",
pl: "波兰",
ba: "波斯尼亚和黑塞哥维那",
bo: "玻利维亚",
bz: "伯利兹",
bw: "博茨瓦纳",
bt: "不丹",
bf: "布基纳法索",
bi: "布隆迪",
bv: "布韦岛",
kp: "朝鲜",
gq: "赤道几内亚",
dk: "丹麦",
de: "德国",
tl: "东帝汶",
tg: "多哥",
do: "多米尼加共和国",
dm: "多米尼克",
ru: "俄罗斯",
ec: "厄瓜多尔",
er: "厄立特里亚",
fr: "法国",
fo: "法罗群岛",
pf: "法属波利尼西亚",
gf: "法属圭亚那",
tf: "法属南部领地",
mf: "法属圣马丁",
va: "梵蒂冈",
ph: "菲律宾",
fj: "斐济",
fi: "芬兰",
cv: "佛得角",
fk: "福克兰群岛",
gm: "冈比亚",
cg: "刚果(布)",
cd: "刚果(金)",
co: "哥伦比亚",
cr: "哥斯达黎加",
gd: "格林纳达",
gl: "格陵兰",
ge: "格鲁吉亚",
gg: "根西岛",
cu: "古巴",
gp: "瓜德罗普",
gu: "关岛",
gy: "圭亚那",
kz: "哈萨克斯坦",
ht: "海地",
kr: "韩国",
nl: "荷兰",
bq: "荷属加勒比区",
sx: "荷属圣马丁",
hm: "赫德岛和麦克唐纳群岛",
me: "黑山",
hn: "洪都拉斯",
ki: "基里巴斯",
dj: "吉布提",
kg: "吉尔吉斯斯坦",
gn: "几内亚",
gw: "几内亚比绍",
ca: "加拿大",
gh: "加纳",
ga: "加蓬",
kh: "柬埔寨",
cz: "捷克",
zw: "津巴布韦",
cm: "喀麦隆",
qa: "卡塔尔",
ky: "开曼群岛",
cc: "科科斯(基林)群岛",
km: "科摩罗",
ci: "科特迪瓦",
kw: "科威特",
hr: "克罗地亚",
ke: "肯尼亚",
ck: "库克群岛",
cw: "库拉索",
lv: "拉脱维亚",
ls: "莱索托",
la: "老挝",
lb: "黎巴嫩",
lt: "立陶宛",
lr: "利比里亚",
ly: "利比亚",
li: "列支敦士登",
re: "留尼汪",
lu: "卢森堡",
rw: "卢旺达",
ro: "罗马尼亚",
mg: "马达加斯加",
im: "马恩岛",
mv: "马尔代夫",
mt: "马耳他",
mw: "马拉维",
my: "马来西亚",
ml: "马里",
mh: "马绍尔群岛",
mq: "马提尼克",
yt: "马约特",
mu: "毛里求斯",
mr: "毛里塔尼亚",
us: "美国",
um: "美国本土外小岛屿",
as: "美属萨摩亚",
vi: "美属维尔京群岛",
mn: "蒙古",
ms: "蒙特塞拉特",
bd: "孟加拉国",
pe: "秘鲁",
fm: "密克罗尼西亚",
mm: "缅甸",
md: "摩尔多瓦",
ma: "摩洛哥",
mc: "摩纳哥",
mz: "莫桑比克",
mx: "墨西哥",
na: "纳米比亚",
za: "南非",
aq: "南极洲",
gs: "南乔治亚和南桑威奇群岛",
ss: "南苏丹",
nr: "瑙鲁",
ni: "尼加拉瓜",
np: "尼泊尔",
ne: "尼日尔",
ng: "尼日利亚",
nu: "纽埃",
no: "挪威",
nf: "诺福克岛",
pw: "帕劳",
pn: "皮特凯恩群岛",
pt: "葡萄牙",
jp: "日本",
se: "瑞典",
ch: "瑞士",
sv: "萨尔瓦多",
ws: "萨摩亚",
rs: "塞尔维亚",
sl: "塞拉利昂",
sn: "塞内加尔",
cy: "塞浦路斯",
sc: "塞舌尔",
sa: "沙特阿拉伯",
bl: "圣巴泰勒米",
cx: "圣诞岛",
st: "圣多美和普林西比",
sh: "圣赫勒拿",
kn: "圣基茨和尼维斯",
lc: "圣卢西亚",
sm: "圣马力诺",
pm: "圣皮埃尔和密克隆群岛",
vc: "圣文森特和格林纳丁斯",
lk: "斯里兰卡",
sk: "斯洛伐克",
si: "斯洛文尼亚",
sj: "斯瓦尔巴和扬马延",
sz: "斯威士兰",
sd: "苏丹",
sr: "苏里南",
sb: "所罗门群岛",
so: "索马里",
tj: "塔吉克斯坦",
tw: "台湾",
th: "泰国",
tz: "坦桑尼亚",
to: "汤加",
tc: "特克斯和凯科斯群岛",
tt: "特立尼达和多巴哥",
tn: "突尼斯",
tv: "图瓦卢",
tr: "土耳其",
tm: "土库曼斯坦",
tk: "托克劳",
wf: "瓦利斯和富图纳",
vu: "瓦努阿图",
gt: "危地马拉",
ve: "委内瑞拉",
bn: "文莱",
ug: "乌干达",
ua: "乌克兰",
uy: "乌拉圭",
uz: "乌兹别克斯坦",
es: "西班牙",
eh: "西撒哈拉",
gr: "希腊",
sg: "新加坡",
nc: "新喀里多尼亚",
nz: "新西兰",
hu: "匈牙利",
sy: "叙利亚",
jm: "牙买加",
am: "亚美尼亚",
ye: "也门",
iq: "伊拉克",
ir: "伊朗",
il: "以色列",
it: "意大利",
in: "印度",
id: "印度尼西亚",
gb: "英国",
vg: "英属维尔京群岛",
io: "英属印度洋领地",
jo: "约旦",
vn: "越南",
zm: "赞比亚",
je: "泽西岛",
td: "乍得",
gi: "直布罗陀",
cl: "智利",
cf: "中非共和国",
cn: "中国",
mo: "中国澳门特别行政区",
hk: "中国香港特别行政区",
};

View File

@@ -0,0 +1,4 @@
import countryTranslations from './countries';
import interfaceTranslations from './interface';
export default { ...countryTranslations, ...interfaceTranslations };

View File

@@ -0,0 +1,15 @@
//* Chinese (Simplified). Translated by: Google Translate.
export default {
selectedCountryAriaLabel: "所选国家",
noCountrySelected: "未选择国家/地区",
countryListAriaLabel: "国家名单",
searchPlaceholder: "搜索",
zeroSearchResults: "未找到结果",
oneSearchResult: "找到 1 个结果",
multipleSearchResults: "找到 ${count} 个结果",
// additional countries (not supported by country-list library)
ac: "阿森松岛",
xk: "科索沃",
};

View File

@@ -0,0 +1,145 @@
<!-- https://github.com/jackocnr/intl-tel-input/blob/master/react/src/intl-tel-input/react.tsx -->
<script lang="ts" setup>
import intlTelInput, { Iti, SomeOptions } from 'intl-tel-input';
import 'intl-tel-input/build/css/intlTelInput.min.css';
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']);
const props = defineProps({
/**有效检验 */
preciseValidation: {
type: Boolean,
default: false,
},
/**手机号 */
value: {
type: String,
default: '',
},
/**禁用输入 */
disabled: {
type: Boolean,
default: false,
},
/**手机号输入提示 */
placeholder: {
type: String,
default: '',
},
/**手机号输入最大字符串长度 */
maxlength: {
type: Number,
default: 255,
},
/**允许清空手机号输入框 */
allowClear: {
type: Boolean,
},
});
const inputRef = ref<HTMLInputElement | null>(null);
const itiRef = ref<Iti | null>(null);
function fnChange() {
if (!itiRef.value) return;
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 = {
num,
countryIso,
validity: false,
errorCode: -1,
};
const isValid = props.preciseValidation
? itiRef.value.isValidNumberPrecise()
: itiRef.value.isValidNumber();
if (isValid) {
data.validity = true;
data.errorCode = 0;
} else {
const errorCode = itiRef.value.getValidationError();
data.validity = false;
data.errorCode = errorCode;
}
// console.log(data);
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) {
let i18n = undefined;
let initialCountry = 'us';
// 语言文件导入问题只能复制到项目内处理
// import fr from "intl-tel-input/i18n/fr";
if (currentLocale.value.startsWith('zh')) {
const { default: zh } = await import('./i18n/zh');
i18n = zh;
initialCountry = 'cn';
} else {
const { default: en } = await import('./i18n/en');
i18n = en;
initialCountry = 'us';
}
itiRef.value = intlTelInput(inputRef.value, {
initialCountry: initialCountry,
formatOnDisplay: true,
autoPlaceholder: 'polite',
i18n: i18n,
} as SomeOptions);
inputRef.value.addEventListener('countrychange', fnChange);
}
});
});
onBeforeUnmount(() => {
if (inputRef.value) {
inputRef.value.removeEventListener('countrychange', fnChange);
}
itiRef.value?.destroy();
});
</script>
<template>
<input
type="tel"
class="ant-input"
ref="inputRef"
:value="value"
:disabled="disabled"
:placeholder="placeholder"
:maxlength="maxlength"
:allow-clear="allowClear"
@input="fnChange"
/>
</template>
<style lang="css">
.iti {
display: block;
}
.iti .iti__country-container .iti__search-input {
padding: 4px 8px;
}
</style>

View File

@@ -1,217 +0,0 @@
<script setup lang="ts">
import { ref, toRaw, onMounted, onUnmounted } from 'vue';
import useI18n from '@/hooks/useI18n';
import { message } from 'ant-design-vue/lib';
import useUserStore from '@/store/modules/user';
import useLockedStore from '@/store/modules/locked';
import { getConfigKey } from '@/api/system/config';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { useRouter } from 'vue-router';
import { computed } from 'vue';
const lockedStore = useLockedStore();
const userStore = useUserStore();
const router = useRouter();
const { t } = useI18n();
const password = ref('');
/**设置定时器ID */
let timeoutDuration = 10 * 60 * 1000; // 设置超时时间为10分钟单位为毫秒
let timeoutId: any = null;
// 超时锁屏
function resetTimeout() {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(() => {
lockedStore.fnLock('lock');
}, timeoutDuration);
}
/**解锁 */
function handleUnlock() {
let lockFrom: any = {};
lockFrom.username = userStore.userName;
lockFrom.password = password.value;
userStore.fnLogin(toRaw(lockFrom)).then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success(t('components.LockScreen.validSucc'), 3);
password.value = '';
lockedStore.fnLock('none');
} else {
message.error(t('components.LockScreen.validError'), 3);
}
});
}
/**返回登录界面 */
function backLogin() {
lockedStore.fnLock('none');
userStore.fnLogOut().finally(() => router.push({ name: 'Login' }));
}
const isLocked = computed(() => lockedStore.type !== 'none');
onMounted(() => {
getConfigKey('sys.lockTime')
.then(res => {
if (res.code === RESULT_CODE_SUCCESS && res.data) {
lockedStore.lockTimeout = res.data;
timeoutDuration = res.data * 1000;
}
// 本地锁定类型设置
lockedStore.fnLock(lockedStore.type);
})
.finally(() => {
if (timeoutDuration !== 0) {
resetTimeout();
// 监听用户的操作,重置超时时间
window.addEventListener('mousemove', resetTimeout);
window.addEventListener('keydown', resetTimeout);
}
});
});
/**组件实例被卸载之后调用 */
onUnmounted(() => {
if (timeoutId) {
clearTimeout(timeoutId);
}
});
</script>
<template>
<a-modal
v-model:visible="isLocked"
get-container="#app"
:footer="null"
:zIndex="1008"
:closable="false"
:keyboard="false"
:centered="true"
:maskClosable="false"
:maskStyle="{
backdropFilter: 'blur(10px)',
WebkitBackdropFilter: 'blur(10px)',
}"
wrapClassName="lock-screen"
:wrap-style="{
background: 'rgba(0, 0, 0, 0.85)',
}"
>
<!-- 锁屏-登录 -->
<div class="lock-screen_login" v-if="lockedStore.type === 'lock'">
<div class="lock-screen_login-user">
<a-avatar
shape="circle"
:size="100"
:src="userStore.getAvatar"
:alt="userStore.userName"
></a-avatar>
<span class="nick">
{{ userStore.nickName }}
</span>
</div>
<div class="lock-screen_login-from">
<a-input-group compact>
<a-input
type="password"
v-model:value="password"
:placeholder="t('components.LockScreen.inputPlacePwd')"
:maxlength="32"
style="width: calc(100% - 50px)"
@keyup.enter="handleUnlock"
/>
<a-button type="primary" @click="handleUnlock">
<LoginOutlined />
</a-button>
</a-input-group>
<a-button type="text" class="logout" @click="backLogin">
{{ t('components.LockScreen.backLogin') }}
</a-button>
</div>
</div>
<!-- 锁屏-OMC重启升级 -->
<div class="lock-screen_reload" v-if="lockedStore.type === 'reload'">
<LoadingOutlined style="font-size: 56px" />
<div class="text">
{{ t('components.LockScreen.backReload') }}
</div>
<div class="desc">
{{ t('components.LockScreen.backReload2') }}
</div>
</div>
</a-modal>
</template>
<style lang="less" scoped>
.lock-screen_login {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: transparent;
&-user {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.nick {
font-size: 28px;
max-width: 164px;
white-space: nowrap;
text-align: start;
text-overflow: ellipsis;
overflow: hidden;
color: #fff;
}
}
&-from {
display: flex;
flex-flow: column;
width: 256px;
margin-top: 30px;
.logout {
margin-top: 8px;
color: rgba(255, 255, 255, 0.85);
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
&:hover {
color: var(--ant-primary-color);
}
}
}
}
.lock-screen_reload {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: transparent;
color: #fff;
& .text {
font-size: 24px;
font-weight: bold;
letter-spacing: 4px;
margin-top: 24px;
}
& .desc {
margin-top: 8px;
font-size: 16px;
}
}
</style>
<style lang="less">
.lock-screen {
.ant-modal-content {
background-color: transparent;
box-shadow: none;
}
}
</style>

View File

@@ -62,7 +62,7 @@ function fnTableColumnsCheckAllChange(e: any) {
/**表格字段列拖拽操作 */
function fnTableColumnsDrop(dropResult: any) {
const { removedIndex, addedIndex, payload } = dropResult;
if (!removedIndex || !addedIndex) {
if (removedIndex === null || addedIndex === null) {
return;
}
let itemToAdd = payload;
@@ -184,6 +184,7 @@ onMounted(() => {
<a-button
v-if="c.fixed !== undefined"
size="small"
:title="c.fixed ? `Fixed ${c.fixed} side` : ''"
:type="c.fixed ? 'primary' : 'dashed'"
@click="fnTableColumnsFixed(c)"
>

View File

@@ -1,8 +1,8 @@
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { FitAddon } from 'xterm-addon-fit';
import { Terminal } from 'xterm';
import 'xterm/css/xterm.css';
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();

View File

@@ -0,0 +1,242 @@
<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,
},
/**ws连接地址必传 如/ws/view */
url: {
type: String,
required: true,
},
/**网元类型,必传 */
neType: {
type: String,
required: true,
},
/**网元ID必传 */
neId: {
type: String,
required: true,
},
/**窗口单行字符数 */
cols: {
type: Number,
default: 80,
},
/**窗口行数 */
rows: {
type: Number,
default: 40,
},
/**ws发送requestId前缀 如ssh_id */
prefix: {
type: String,
default: 'ssh',
},
});
/**终端输入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: true, // 光标闪烁
cursorStyle: 'block',
scrollback: 1000, // 设置历史缓冲区大小为 1000 行
scrollSensitivity: 15,
tabStopWidth: 4,
disableStdin: true, // 禁止输入
});
// 挂载
xterm.open(container);
// 自适应尺寸
const fitAddon = new FitAddon();
xterm.loadAddon(fitAddon);
// 终端尺寸变化触发
xterm.onResize(({ cols, rows }) => {
// console.log('尺寸', cols, rows);
ws.send({
requestId: `resize_${props.id}`,
type: 'resize',
data: { cols, rows },
});
});
// 创建 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,
neType: props.neType,
neId: props.neId,
id: props.id,
});
});
}
/**连接错误后回调 */
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 ' + code;
terminal.value.write(`\x1b[31m${message}\x1b[m\r\n`);
}
// 关闭事件
emit('close', {
code: code,
neType: props.neType,
neId: props.neId,
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 (terminal.value != null) {
// 查找的开始输出标记
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(data);
}
}
onMounted(() => {
if (props.neType && props.neId) {
// 建立链接
const options: OptionsType = {
url: props.url,
params: {
neType: props.neType,
neId: props.neId,
cols: props.cols,
rows: props.rows,
},
onmessage: wsMessage,
onerror: wsError,
onopen: wsOpen,
onclose: wsClose,
};
ws.connect(options);
}
});
onBeforeUnmount(() => {
if (ws.state() === WebSocket.OPEN) ws.close();
});
// 给组件设置属性 ref="xxxTerminal"
// setup内使用 const xxxTerminal = ref();
defineExpose({
/**清除 */
clear: () => {
if (terminal.value != null) {
terminal.value.clear();
}
},
/**发送命令 */
send: (type: string, data: Record<string, any>) => {
ws.send({
requestId: `${props.prefix}_${props.id}`,
type,
data,
});
},
/**模拟按下 Ctrl+C */
ctrlC: () => {
ws.send({
requestId: `${props.prefix}_${props.id}`,
type: 'ctrl-c',
});
},
});
</script>
<template>
<div ref="terminalDom" :id="id" class="terminal"></div>
</template>
<style lang="css" scoped>
.terminal {
width: 100%;
height: 100%;
}
</style>

View File

@@ -1,9 +1,9 @@
<script lang="ts" setup>
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';
import 'xterm/css/xterm.css';
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();
@@ -19,6 +19,16 @@ const props = defineProps({
type: String,
required: true,
},
/**窗口单行字符数 */
cols: {
type: Number,
default: 120,
},
/**窗口行数 */
rows: {
type: Number,
default: 128,
},
/**禁止输入 */
disable: {
type: Boolean,
@@ -109,7 +119,7 @@ function fnAutoCompleteKeydown(evt: any) {
ws.send({
requestId: `telnet_${props.hostId}`,
type: 'telnet',
data: `${cmdStr}\r\n'`,
data: `${cmdStr}\r\n`,
});
terminalState.text = ' ';
@@ -145,6 +155,15 @@ function handleRanderXterm(container: HTMLElement | undefined) {
// 自适应尺寸
const fitAddon = new FitAddon();
xterm.loadAddon(fitAddon);
// 终端尺寸变化触发
xterm.onResize(({ cols, rows }) => {
// console.log('尺寸', cols, rows);
ws.send({
requestId: `telnet_resize_${props.hostId}`,
type: 'telnet_resize',
data: { cols, rows },
});
});
// 创建 ResizeObserver 实例
var observer = new ResizeObserver(entries => {
@@ -238,6 +257,8 @@ onMounted(() => {
url: '/ws/telnet',
params: {
hostId: props.hostId,
cols: props.cols,
rows: props.rows,
},
onmessage: wsMessage,
onerror: wsError,
@@ -268,7 +289,7 @@ defineExpose({
<template>
<div class="terminal">
<div ref="terminalDom" style="height: 78%" :id="id"></div>
<div ref="terminalDom" style="height: calc(100% - 36px)" :id="id"></div>
<a-auto-complete
v-model:value="terminalState.text"
:dropdown-match-select-width="500"

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>

View File

@@ -35,19 +35,22 @@ const props = defineProps({
/**弹框关闭事件 */
function fnModalClose() {
if(props.loading) return
if (props.loading) return;
emit('close');
}
/**上传前检查或转换压缩 */
function fnBeforeUpload(file: FileType) {
if (props.loading) return false;
// 检查文件大小
if (props.size > 0) {
// 检查文件大小
if (props.size > 0) {
const fileSize = file.size;
const isLtM = fileSize / 1024 / 1024 < props.size;
if (!isLtM) {
message.error(`${t('components.UploadModal.allowFilter')} ${props.size}MB`, 3);
message.error(
`${t('components.UploadModal.allowFilter')} ${props.size}MB`,
3
);
return false;
}
}
@@ -56,7 +59,10 @@ function fnBeforeUpload(file: FileType) {
const fileName = file.name;
const isAllowType = props.ext.some(v => fileName.endsWith(v));
if (!isAllowType) {
message.error(`${t('components.UploadModal.onlyAllow')} ${props.ext.join('、')}`, 3);
message.error(
`${t('components.UploadModal.onlyAllow')} ${props.ext.join('、')}`,
3
);
return false;
}
}
@@ -65,19 +71,20 @@ function fnBeforeUpload(file: FileType) {
/**上传请求发出 */
function fnUpload(up: UploadRequestOption) {
emit('upload', up.file)
emit('upload', up.file);
}
</script>
<template>
<a-modal
width="500px"
<ProModal
:drag="true"
:destroyOnClose="true"
:title="props.title"
:visible="props.visible"
:keyboard="false"
:mask-closable="false"
:confirm-loading="props.loading"
:footer="null"
:footer="false"
@cancel="fnModalClose"
>
<a-space :size="8" direction="vertical" style="width: 100%">
@@ -93,20 +100,26 @@ function fnUpload(up: UploadRequestOption) {
<p class="ant-upload-drag-icon">
<inbox-outlined></inbox-outlined>
</p>
<p class="ant-upload-text">{{t('components.UploadModal.uploadTip')}}</p>
<p class="ant-upload-text">
{{ t('components.UploadModal.uploadTip') }}
</p>
<p class="ant-upload-hint">
<div v-if="props.size > 0">
{{t('components.UploadModal.allowSize')}} {{ props.size }} MB
</div>
<div v-if="props.ext.length > 0">
{{t('components.UploadModal.allowFormat')}} {{ props.ext.join('') }}
</div>
<template v-if="props.size > 0">
<div>
{{ t('components.UploadModal.allowSize') }} {{ props.size }} MB
</div>
</template>
<template v-if="props.ext.length > 0">
<div>
{{ t('components.UploadModal.allowFormat') }}
{{ props.ext.join('、') }}
</div>
</template>
</p>
</a-upload-dragger>
<slot></slot>
</a-space>
</a-modal>
</ProModal>
</template>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,204 @@
<script lang="ts" setup>
import { reactive, ref, computed, unref, onUpdated, watchEffect } from 'vue';
const props = defineProps({
/**列表高度 */
height: {
type: Number,
default: 300,
},
/**列表项高度 */
itemHeight: {
type: Number,
default: 30,
},
/**数据 */
data: {
type: Array,
default: () => [],
},
/**预先兜底缓存数量 */
cache: {
type: Number,
default: 2,
},
/**是否动态加载 */
dynamic: {
type: Boolean,
default: false,
},
});
const state = reactive<any>({
start: 0,
end: 10,
scrollOffset: 0,
cacheData: [],
});
const virtualListRef = ref();
const getWrapperStyle = computed(() => {
const { height } = props;
return {
height: `${height}px`,
};
});
const getInnerStyle = computed(() => {
return {
height: `${unref(getTotalHeight)}px`,
width: '100%',
};
});
const getListStyle = computed(() => {
return {
willChange: 'transform',
transform: `translateY(${state.scrollOffset}px)`,
};
});
// 数据数量
const total = computed(() => {
return props.data.length;
});
// 总体高度
const getTotalHeight = computed(() => {
if (!props.dynamic) return unref(total) * props.itemHeight;
return getCurrentTop(unref(total));
});
// 当前屏幕显示的数量
const clientCount = computed(() => {
return Math.ceil(props.height / props.itemHeight);
});
// 当前屏幕显示的数据
const clientData = computed(() => {
return props.data.slice(state.start, state.end);
});
const onScroll = (e: any) => {
const { scrollTop } = e.target;
if (state.scrollOffset === scrollTop) return;
const { cache, dynamic, itemHeight } = props;
const cacheCount = Math.max(1, cache);
let startIndex = dynamic
? getStartIndex(scrollTop)
: Math.floor(scrollTop / itemHeight);
const endIndex = Math.max(
0,
Math.min(unref(total), startIndex + unref(clientCount) + cacheCount)
);
if (startIndex > cacheCount) {
startIndex = startIndex - cacheCount;
}
// 偏移量
const offset = dynamic
? getCurrentTop(startIndex)
: scrollTop - (scrollTop % itemHeight);
Object.assign(state, {
start: startIndex,
end: endIndex,
scrollOffset: offset,
});
};
// 二分法去查找对应的index
const getStartIndex = (scrollTop = 0): number => {
let low = 0;
let high = state.cacheData.length - 1;
while (low <= high) {
const middle = low + Math.floor((high - low) / 2);
const middleTopValue = getCurrentTop(middle);
const middleBottomValue = getCurrentTop(middle + 1);
if (middleTopValue <= scrollTop && scrollTop <= middleBottomValue) {
return middle;
} else if (middleBottomValue < scrollTop) {
low = middle + 1;
} else if (middleBottomValue > scrollTop) {
high = middle - 1;
}
}
return Math.min(
unref(total) - unref(clientCount),
Math.floor(scrollTop / props.itemHeight)
);
};
const getCurrentTop = (index: number) => {
const lastIndex = state.cacheData.length - 1;
if (Object.hasOwn(state.cacheData, index)) {
return state.cacheData[index].top;
} else if (Object.hasOwn(state.cacheData, index - 1)) {
return state.cacheData[index - 1].bottom;
} else if (index > lastIndex) {
return (
state.cacheData[lastIndex].bottom +
Math.max(0, index - state.cacheData[lastIndex].index) * props.itemHeight
);
} else {
return index * props.itemHeight;
}
};
onUpdated(() => {
if (!props.dynamic) return;
const childrenList = virtualListRef.value.children || [];
[...childrenList].forEach((node: any, index: number) => {
const height = node.getBoundingClientRect().height;
const currentIndex = state.start + index;
if (state.cacheData[currentIndex].height === height) return;
state.cacheData[currentIndex].height = height;
state.cacheData[currentIndex].top = getCurrentTop(currentIndex);
state.cacheData[currentIndex].bottom =
state.cacheData[currentIndex].top + state.cacheData[currentIndex].height;
});
});
watchEffect(() => {
clientData.value.forEach((_, index) => {
const currentIndex = state.start + index;
if (Object.hasOwn(state.cacheData, currentIndex)) return;
state.cacheData[currentIndex] = {
top: currentIndex * props.itemHeight,
height: props.itemHeight,
bottom: (currentIndex + 1) * props.itemHeight,
index: currentIndex,
};
});
});
</script>
<template>
<div
class="virtual-list-wrapper"
ref="wrapperRef"
:style="getWrapperStyle"
@scroll="onScroll"
>
<div class="virtual-list-inner" ref="innerRef" :style="getInnerStyle">
<div class="virtual-list" :style="getListStyle" ref="virtualListRef">
<div v-for="(item, index) in clientData" :key="index + state.start">
<slot name="default" :item="item"></slot>
</div>
</div>
</div>
</div>
</template>
<style lang="css" scoped>
.virtual-list-wrapper {
position: relative;
overflow-y: auto;
}
</style>

View File

@@ -1,5 +1,5 @@
/**管理员-系统指定角色KEY */
export const ADMIN_ROLE_KEY = 'admin';
/**系统管理员-系统指定角色KEY */
export const ADMIN_ROLE_KEY = 'system';
/**管理员-系统指定权限 */
/**系统管理员-系统指定权限 */
export const ADMIN_PERMISSION = '*:*:*';

View File

@@ -3,3 +3,6 @@ export const APP_REQUEST_HEADER_CODE = 'X-App-Code';
/**应用-请求头-系统版本 */
export const APP_REQUEST_HEADER_VERSION = 'X-App-Version';
/**应用-请求数据-密钥 */
export const APP_DATA_API_KEY = 'T9ox2DCzpLfJIPzkH9pKhsOTMOEMJcFv';

View File

@@ -10,8 +10,11 @@ export const CACHE_LOCAL_PRIMARY_COLOR = 'cache:local:primaryColor';
/**本地缓存-多语言 */
export const CACHE_LOCAL_I18N = 'cache:local:i18n';
/**本地缓存-锁屏设置 */
export const CACHE_LOCAL_LOCK = 'cache:local:Lock';
/**本地缓存-遮罩设置 */
export const CACHE_LOCAL_MASK = 'cache:local:mask';
/**本地缓存-锁屏密码 */
export const CACHE_LOCAL_LOCK_PASSWD = 'cache:local:lock:passwd';
/**数据缓存表-表格排序 */
export const CACHE_DB_TABLE_DND = 'tbl_dnd';

View File

@@ -1,18 +1,27 @@
/**网元列表,默认顺序 */
export const NE_TYPE_LIST = [
'OMC',
'MME',
'IMS',
'AMF',
'AUSF',
'UDM',
'SMF',
'PCF',
'UPF',
'NRF',
'NSSF',
'IMS',
'N3IWF',
'NEF',
'NRF',
'UPF',
'LMF',
'NEF',
'MME',
'N3IWF',
'MOCNGW',
'SMSC',
'CBC',
];
/**
* 网元拓展包列表,默认顺序
* IMS-adb/kvdb/rtproxy/mf
* UDM-adb/kvdb
*/
export const NE_EXPAND_LIST = ['ADB', 'KVDB', 'RTPROXY', 'MF'];

View File

@@ -1,3 +1,12 @@
/**响应-code加密数据 */
export const RESULT_CODE_ENCRYPT = 2;
/**响应-msg加密数据 */
export const RESULT_MSG_ENCRYPT: Record<string, string> = {
zh_CN: '加密!',
en_US: 'encrypt!',
};
/**响应-code正常成功 */
export const RESULT_CODE_SUCCESS = 1;

View File

@@ -1,5 +1,5 @@
import { onBeforeMount } from 'vue';
import { ConfigProvider } from 'ant-design-vue/lib';
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';
@@ -8,6 +8,7 @@ import { localGet, localSet } from '@/utils/cache-local-utils';
*/
export const usePrimaryColor = () => {
onBeforeMount(() => {
message.config({ top: '100px' }); // 全局配置消息距离顶部的位置
changePrimaryColor(getLocalColor());
});
};

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@ export default {
// 语言
i18n: '中文',
hello: '你好',
welcome: '欢迎使用,核心网管理平台',
// 通用
common: {
@@ -34,7 +35,6 @@ export default {
unableNull:'不能为空',
moreText: '更多',
searchBarText: '搜索栏',
tableStripedText: '表格斑马纹',
reloadText: '刷新',
columnSetText: '列设置',
columnSetTitle: '列展示/排序',
@@ -53,9 +53,15 @@ export default {
fold: '折叠',
},
rowId: '编号',
operate: '操作',
createTime: '创建时间',
updateTime: '更新时间',
remark: '备注',
description: '说明',
operate: '更多操作',
operateOk: '操作成功!',
operateErr: '操作失败!',
copyText: "复制",
copyOk: '复制成功!',
units: {
second: '秒',
minute: '分钟',
@@ -124,12 +130,14 @@ export default {
onlyAllow:'只支持上传文件格式',
},
LockScreen: {
inputPlacePwd:'请输入登录密码',
inputPlacePwd:'请输入锁屏密码',
validSucc:'校验通过',
validError:'校验失败',
backLogin:'退出并重新登录',
backReload:'正在重启,请稍等...',
backReload2:'当准备就绪的时候,你的浏览器会自动刷新。',
systemReset:'正在重置,请稍等...',
systemReset2:'数据信息正在重置',
},
},
@@ -141,6 +149,8 @@ export default {
page403: '没有访问权限',
page404: '找不到匹配页面',
helpDoc: '系统使用文档',
traceTaskHLR: '跟踪任务 HLR',
lockScreen: '锁屏',
account: {
index: "个人中心",
profile: "个人信息",
@@ -164,6 +174,9 @@ export default {
codeHit: '验证码',
codeText: '获取验证码',
codeSmsSend: '发送成功,请注意查看短信',
ipPlease: '请输入有效的IP地址',
ipv4Reg: '不是有效IPv4地址',
ipv6Reg: '不是有效IPv6地址',
},
// 布局
@@ -173,9 +186,11 @@ export default {
helpDoc: '使用手册',
},
rightContent: {
alarm: "活动告警",
lock: "锁屏",
lockTip: "确认要进行锁屏吗?",
helpDoc: "系统使用文档",
lockPasswd: "解锁密码",
lockPasswdTip: "可不设置密码",
fullscreen: "全屏显示",
logout: "退出登录",
profile: "个人中心",
@@ -262,10 +277,10 @@ export default {
email: "电子邮箱",
emailPleace: "请输入正确的电子邮箱",
phonenumber: "手机号码",
phonenumberPleace: "请输入正确的电子邮箱",
phonenumberPleace: "请输入正确的手机号码",
nick: "用户昵称",
nickPleace: "请输入用户昵称",
nickTip: "昵称只能包含字母、数字、中文和下划线,且不少于2位",
nickTip: "昵称少于2位",
profileTip: "确认要提交修改用户基本信息吗?",
profileOk: "用户基本信息修改成功!",
know: "我知道了",
@@ -282,10 +297,10 @@ export default {
newPassword: "新密码",
newPasswordTip: "密码至少包含大小写字母、数字、特殊符号且不少于6位",
newPassworddPleace: "请输入新密码",
confirmPassword: "确认新密码",
confirmPassword: "确认新密码",
confirmPasswordPleace: "请确认新密码",
submit: "提交修改",
reset: "重置",
reset: "重置",
submitTip: "确认要提交修改密码吗?",
submitOkTip: "恭喜您,{num} 账号密码修改成功!",
submitOk: "重新登录",
@@ -424,15 +439,14 @@ export default {
letUpTime:'激活时间',
createTime:'创建时间',
onlyAble:'只支持上传文件格式 {fileText}',
nullData:'暂无网元列表数据',
nullVersion:'当前网元无可回退版本',
},
license: {
neTypePlease: '选择网元类型',
neType: '网元类型',
fileName: '文件名',
createTime: '上传时间',
comment: '文件说明',
serialNum: '序列号',
createTime: '时间',
comment: '说明',
updateComment: 'License说明',
updateCommentPlease: '请输入License说明',
updateFile: 'License文件',
@@ -471,21 +485,21 @@ export default {
neType: "网元类型",
neTypePleace: "请选择网元类型",
noConfigData: "暂无配置项数据",
updateValue: "{num} 属性值修改成功",
updateValue: "{num} 属性值修改成功",
updateValueErr: "属性值修改失败",
updateItem: "修改 Index 为 {num} 记录成功",
updateItemErr: "记录修改失败",
delItemOk: "删除 Index 为 {num} 记录成功",
addItemOk: "新增 Index 为 {num} 记录成功",
addItemErr: "记录新增失败",
requireUn: "{display} 输入值是未知类型",
requireString: "{display} 参数值不合理",
requireInt: "{display} 参数值不在合理范围 {filter}",
requireIpv4: "{display} 不是合法的IPV4地址",
requireIpv6: "{display} 不是合法的IPV6地址",
requireEnum: "{display} 不是合理的枚举值",
requireBool: "{display} 不是合理的布尔类型的值",
editOkTip: "确认更新该{num}属性值吗?",
requireUn: "{display} 输入值是未知类型",
requireString: "{display} 参数值不合理",
requireInt: "{display} 参数值不在合理范围 {filter}",
requireIpv4: "{display} 不是合法的IPV4地址",
requireIpv6: "{display} 不是合法的IPV6地址",
requireEnum: "{display} 不是合理的枚举值",
requireBool: "{display} 不是合理的布尔类型的值",
editOkTip: "确认更新该{num}属性值吗?",
updateItemTip: "确认更新Index为 【{num}】 的数据项?",
delItemTip: "确认删除Index为 【{num}】 的数据项?",
arrayMore: "展开",
@@ -549,40 +563,78 @@ export default {
realTimeDataStart: "开启实时数据",
realTimeDataStop: "关闭实时数据",
cdrInfo: "CDR信息",
neName: "网元名称",
rmUID: "资源标识",
time: "记录时间",
rowInfo: "记录信息",
type: "记录类型",
duration: "通话时长",
seizureTime: "呼叫开始时间",
releaseTime: "挂断结束时间",
caller: "主叫",
called: "被叫",
result: "结果",
resultOk: "成功",
resultFail: "失败",
delTip: "确认删除编号为【{msg}】的数据项?",
exportTip: "确认导出当前查询条件的话单数据吗?(导出最大支持一万条)",
smfChargingID: '计费ID',
smfSubscriptionIDData: '订阅 ID 数据',
smfSubscriptionIDType: '订阅 ID 类型',
smfDataVolumeUplink: '数据量上行链路',
smfDataVolumeDownlink: '数据量下行链路',
smfDataTotalVolume: '数据总量',
smfDuration: '持续时间',
smfInvocationTime: '调用时间',
},
ue: {
eventType: "事件类型",
realTimeDataStart: "开启实时数据",
realTimeDataStop: "关闭实时数据",
ueInfo: "UE信息",
neName: "网元名称",
rmUID: "资源标识",
rowInfo: "记录信息",
time: "记录时间",
result: "结果",
resultOk: "成功",
delTip: "确认删除编号为【{msg}】的数据项?",
exportTip: "确认导出当前查询条件的事件数据吗?(导出最大支持一万条)",
},
},
ne: {
neInfo: {
version: "网元版本",
common: {
neType: '网元类型',
neTypePlease: "请选择网元类型",
neTypeTip: '填写创建的网元类型,如:SMF',
neId: '网元标识',
neIdPlease: '请输入网元标识',
neIdTip: '填写网元绑定的唯一标识',
rmUid: '资源唯一标识',
rmUidPlease: '请输入资源唯一标识',
rmUidTip: "用于网元日志、告警、指标等数据上报的标记",
neName: '网元名称',
neNamePlease: '请输入网元名称',
ipAddr: '服务IP',
ipAddrPlease: '请输入网元服务IP地址',
ipAddrTip: "支持IPV4/IPV6,同步变更配置地址",
port: '服务端口',
portTip: "网元服务端口,默认:33030",
serialNum: '序列号',
expiryDate: '许可证到期日期',
normalcy: '正常',
exceptions: '异常',
restart: '重启',
restartTip: '确认要重新启动网元服务吗?',
start: '启动',
startTip: '确认要启动网元服务吗?',
stop: '停止',
stopTip: '确认要停止网元服务吗?',
reload: '重载',
reloadTip: '确认要重载网元配置信息吗?',
oam: 'OAM',
log: '日志',
},
neInfo: {
version: "网元版本",
state: "网元状态",
serviceState: "服务状态",
normalcy: "正常",
exceptions: "异常",
info: '状态信息',
resourceInfo: '资源情况',
sysMem: "系统内存",
@@ -590,8 +642,41 @@ export default {
sysDisk: "系统存储",
neCpu: "网元CPU",
hostConfig: "终端连接配置",
rmUID: "数据资源定位标识符用于日志、告警上报等数据标记",
ipAddr: "支持IPV4/IPV6,同步变更下方配置的配置地址",
pvflag: '网元虚拟化标识',
pnf: '物理网元',
vnf: '虚拟网元',
neAddress: '物理地址(MAC)',
neAddressTip: '记录网元的网卡物理地址(MAC)',
dn: '网络标识',
vendorName: '提供厂商',
province: '服务地域',
addTitle: '新增网元信息',
editTitle: '编辑网元信息',
delTip: '确认删除网元信息数据项吗?',
oam: {
title: 'OAM配置',
sync: '同步到网元',
oamEnable: '服务',
oamPort: '端口',
snmpEnable: '服务',
snmpPort: '端口',
kpiEnable: '上报',
kpiTimer: '上报周期',
kpiTimerPlease: '请输入上报周期(单位秒)',
omcIP: 'OMC IP',
},
backConf: {
export: '配置导出',
import: '配置导入',
title: '配置文件导入',
importType: '文件来源',
server:'服务器文件',
local:'本地文件',
localUpload:'本地上传',
exportTip:'确认要导出网元配置信息到文件?',
exportMsg:'导出网元配置信息到文件成功',
pathPlease: '未发现文件',
},
},
neHost: {
hostType: "主机类型",
@@ -603,20 +688,21 @@ export default {
port: "端口",
portPlease: "请正确填写主机端口号",
user: "用户名",
userPlease: "请正确填写主机登录用户",
userPlease: "请正确填写主机用户",
database: "数据库",
authMode: "认证模式",
password: "密码",
passwordPlease: "请正确填写主机登录密码",
passwordPlease: "请正确填写主机密码",
privateKey: "私钥",
privateKeyPlease: "请正确填写私钥字符内容 ~/.ssh/id_rsa",
passPhrase: "私钥密码",
remark: "备注信息",
createTime: "创建时间",
delTip: "确认要删除主机编号为【{num}】的信息吗?",
addTitle: "新增主机连接",
editTitle: "编辑主机连接",
test: "测试连接",
testOk: "测试连接成功",
authRSA: "免密授权",
authRSATip: "是否要配置免密授权?",
},
neHostCmd: {
cmdType: "命令类型",
@@ -625,12 +711,149 @@ export default {
titlePlease: "请正确填写命令名称",
command: "命令",
commandPlease: "请正确输入有效命令字符串",
remark: "备注",
createTime: "创建时间",
delTip: "确认要删除命令编号为【{num}】的信息吗?",
addTitle: "新增主机命令",
editTitle: "编辑主机命令",
},
neSoftware: {
uploadTitle: "上传软件",
upload: "上传",
uploadNotFile: "未上传软件文件",
uploadBatch: "批量上传",
uploadBatchMax: "可上传多个软件包,最多同时选择{txt}个。",
uploadFileName: "解析文件名称格式如: amf-r2.240x.xx-xxx",
name: "文件名",
path: "软件文件",
pathPlease: "请上传软件包文件",
version: "软件版本",
versionPlease: "请输入软件版本号",
delTip: "确认要删除软件包吗?",
downTip: "确认要下载软件包【{txt}】吗?",
fileCheckType: '未解析出对应的网元类型',
fileCheckVer: '未解析出对应的版本号',
fileTypeNotEq: '不是指定网元类型 {txt}',
fileTypeExists: '已存在相同类型文件',
fileNameExists: '已存在相同名称文件',
fileCheckTypeDep: '未解析出对应指定的依赖包类型',
dependFile: '软件包依赖',
dependFileTip: '文件名解析同上,依据上传顺序安装',
},
neVersion: {
upgrade: "升级到新版本",
upgradeTip: "确认要升级到新版本吗?",
upgradeTipEmpty: "当前没有可用的新版本",
upgradeTipEqual: "当前版本与新版本相同,确认要进行更新吗?",
rollback: '切换到上一个版本',
rollbackTip: "确认切换到上一个版本吗?",
rollbackTipEmpty: "目前没有可用的上一个版本",
rollbackTipEqual: '当前版本与之前版本相同,确认要进行切换吗?',
version: "当前版本",
preVersion: "上一个版本",
newVersion: "新版本",
status: "版本状态",
upgradeBatch: "批量更新",
upgradeBatchTip: "对勾选的记录进行新版本升级吗?",
upgradeNotNewVer: '没有发现新版本',
upgradeOMCVer: '拒绝批量操作升级OMC',
upgradeDone: '更新完成,服务正在重载',
upgradeFail: '更新失败,请检查软件文件是否存在且服务终端环境是否可用!',
upgradeModal: '网元版本更新',
},
neLicense: {
status: "许可证状态",
change: "变更许可证",
reload: "刷新信息",
reloadTip: "确认要刷新许可证信息吗?",
reloadBatch: "批量刷新",
reloadBatchTip: "对勾选的记录进行信息刷新吗?",
updateTtile: "更新许可证",
downCodeTop: "确认要将许可激活码保存到文件吗?",
activationRequestCode: "许可激活码",
licensePath: "许可证文件",
licensePathTip: "请上传许可证文件",
upload: '上传',
uploadFile: "上传许可证",
uploadChangeOk: '网元更新许可证成功,正在后台校验!',
uploadChangeFail: "部分网元更新许可证失败,请检查服务终端环境是否可用!",
},
neConfig: {
treeTitle: "配置导航",
treeSelectTip: "左侧配置导航中选择配置项信息!",
neType: "网元类型",
neTypePleace: "请选择网元类型",
noConfigData: "暂无配置项数据",
updateValue: "【 {num} 】 属性值修改成功",
updateValueErr: "属性值修改失败",
updateItem: "修改 Index 为 {num} 记录成功",
updateItemErr: "记录修改失败",
delItemOk: "删除 Index 为 {num} 记录成功",
addItemOk: "新增 Index 为 {num} 记录成功",
addItemErr: "记录新增失败",
requireUn: "【 {display} 】输入值是未知类型",
requireString: "【 {display} 】参数值不合理",
requireInt: "【 {display} 】参数值不在合理范围 {filter}",
requireIpv4: "【 {display} 】不是合法的IPV4地址",
requireIpv6: "【 {display} 】不是合法的IPV6地址",
requireEnum: "【 {display} 】不是合理的枚举值",
requireBool: "【 {display} 】不是合理的布尔类型的值",
editOkTip: "确认更新该【 {num} 】属性值吗?",
updateItemTip: "确认更新Index为 【{num}】 的数据项?",
delItemTip: "确认删除Index为 【{num}】 的数据项?",
arrayMore: "展开",
},
neConfigBackup: {
name: "名称",
downTip: '确认要下载备份文件【{txt}】吗?',
title: "修改备份信息 {txt}",
},
neQuickSetup: {
reloadPara5G: '刷新',
stepPrev: '上一步',
stepPrevTip: '确认要放弃当前变更返回上一步吗?',
stepNext: '下一步',
stepSave: '保存信息',
startTitle: '服务终端环境',
startDesc: '测试连接网元服务',
startStepNext: '确认要下一步进行配置网元信息?',
addr: '终端IP',
kernelName: '系统',
kernelRelease: '内核',
machine: '架构',
prettyName: '平台',
prettyNameTip: '支持 Ubuntu',
nodename: '主机名',
auth: '权限授予',
sudo: '提权',
sudoErr: '确保有权限进行软件包安装,请配置授予当前用户允许无密码 sudo 权限。',
sshLink: '免密直连',
configTitle: "配置网元",
configDesc: "填写网元基础信息",
configAddTitle: '新增提示',
configAddTip: '是否新增为新的网元信息并继续?',
configUpdateTitle: '更新提示',
configUpdateTip: '是否更新到已存在网元信息并继续?',
configStepNext: '确认要下一步进行网元软件安装?',
installTitle: "网元安装",
installDesc: "安装到服务终端",
installConfirmTip: '确认要安装软件包【{name}】吗?',
installStepNext: '确认要下一步进行网元授权吗?',
installSource: '软件来源',
installSourceOption: '已上传',
installSourceUpload: '新上传',
installSelect: '选择记录',
installUpload: '上传文件',
installText: '安装',
licenseTitle: "授权许可",
licenseDesc: "网元服务授权认证",
licenseResultTitle: "是否立即授权激活",
licenseResultTitleOk: '成功激活',
licenseUpload: '许可证',
licenseEnd: '结束',
licenseEndTip: "确认要结束安装吗?",
licenseCheack: '等待网元验证',
licenseTip1: '1. 点击【许可证】可获取许可激活码,随后联系网元厂商进行激活',
licenseTip2: '2. 点击【结束】将结束安装过程',
},
},
neUser: {
auth: {
@@ -644,7 +867,7 @@ export default {
import: '导入',
loadDataConfirm: '确认要重新加载数据吗?',
loadData: '加载数据',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新。加载结束后可点击重置刷新数据列表,请勿重复点击获取更新!!!',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,请稍候!!!',
startIMSI: '起始IMSI',
batchAddText: '批量新增',
batchDelText: '批量删除',
@@ -657,9 +880,10 @@ export default {
imsiTip3: 'MSIN=移动客户识别码采用等长10位数字构成',
amfTip: '鉴权管理域,参数最大长度为 4',
algoIndexTip: '算法索引介于0到15之间',
kiTip: '用户签权密钥信息,最大长度为32',
kiTip: '用户签权密钥信息,长度只能是32',
opcTip: '鉴权秘钥OPC是由Ki和OP经过计算得来的OP为运营商的根秘钥ki是鉴权秘钥,最大长度为32',
delSure:'确认删除IMSI编号为: {imsi} 的用户吗?',
imsiConfirm:'IMSI的长度必须为15',
},
sub: {
subInfo:'签约信息',
@@ -671,7 +895,7 @@ export default {
import: '导入',
loadDataConfirm: '确认要重新加载数据吗?',
loadData: '加载数据',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新。加载结束后可点击重置刷新数据列表,请勿重复点击获取更新!!!',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,请稍候!!!',
numAdd: '放号个数',
numDel: '删除个数',
checkDel:'勾选删除',
@@ -691,7 +915,8 @@ export default {
micoTip: '签约的 MICO 业务标志位',
rfspTip:'RFSP 索引,在 NG-RAN 中,特定 RRM 配置的索引,参数介于0到127之间',
ueTypeTip: '运营商定义的用户 UE Usage Type整型参数介于0到127之间',
epsFlagTip: '是否开启4G EPS 服务',
cnFlag: '是否开启 5G Core Network 服务',
epsFlagTip: '是否开启 4G EPS 服务',
contextIdTip: '签约APN 上下文ID必须从APN Context list 中选择。',
apnContextTip: '手机可用的APN列表最多六个在HSS中定义。',
staticIpTip: '指定手机用户上网时使用的静态IP地址,为"-"时表示使用动态IP地址',
@@ -709,17 +934,28 @@ export default {
addTitle: '新增策略控制信息',
updateTitle: '{imsi} 策略控制信息',
startIMSI: '起始IMSI',
batchOper: '批量操作',
batchAddText: '批量新增',
batchDelText: '批量删除',
batchUpdateText: '批量更新',
batchNum: '批量个数',
batchNum: '批量个数',
imsiTip: 'IMSI=MCC+MNC+MSIN',
imsiTip1: 'MCC=移动国家号码, 由三位数字组成',
imsiTip2: 'MNC=移动网络号,由两位数字组成',
imsiTip3: 'MSIN=移动客户识别码采用等长10位数字构成',
delSure:'确认删除IMSI编号为: {imsi} 的用户吗?',
checkDel:'勾选删除',
delSure:'确认删除IMSI编号为: {imsi} 的数据项吗?',
uploadFileOk: '文件上传成功',
uploadFileErr: '文件上传失败',
pccRuleTip:'PCC策略规则模板(对应参数配置-PCC Rules)',
sessRuleTip:'会话策略规则模板(对应参数配置-Session Rules)',
qosAudioTip:'语音呼叫QoS(对应参数配置-QoS Template的QoS ID)',
qosVideoTip:'视频呼叫QoS(对应参数配置-QoS Template的QoS ID)',
hdrTip:'HTTP头增强(对应参数配置-Header Enrich Template)',
ueTip:'UE策略模板(样例: uep_001)',
sarTip1:'服务区限制',
sarTip2:'(对应参数配置-Service Area Restriction)',
rfsfTip:'无线频率选择优先级',
},
base5G: {
neType: '网元对象',
@@ -755,7 +991,7 @@ export default {
viewTask:'查看任务',
editTask:'修改任务',
addTask:'新增任务',
stopTask:'挂起',
stopTask:'停止',
errorTaskInfo: '获取任务信息失败',
granulOptionPlease:'请选择测量粒度',
letupSure:'确认激活编号为 【{id}】 的任务?',
@@ -815,10 +1051,11 @@ export default {
exportSure:'确认是否导出全部统计数据',
exportEmpty: "导出数据为空",
showChartSelected: "显示全部",
realTimeData: "实时5s数据",
realTimeData: "实时数据",
},
customTarget:{
kpiId:'自定义指标项',
kpiIdTip:'该网元没有自定义指标',
period:'颗粒度',
title:'自定义指标项标题',
objectType:'对象类型',
@@ -829,8 +1066,35 @@ export default {
delCustom:'成功删除记录编号为 {num} 自定义指标',
addCustom:'添加自定义指标',
editCustom:'编辑自定义指标',
errorCustomInfo: '获取信息失败',
}
errorCustomInfo: '获取信息失败',
status: '状态',
active:'正常',
inactive:'停用',
symbol:"符号",
element:'元素',
granularity:'颗粒度',
unit:'单位',
},
kpiKeyTarget:{
"fullWidthLayout":"全宽布局",
"twoColumnLayout":"两列布局",
"saveLayout": "保存布局",
"restoreSaved": "恢复布局",
"saveSuccess": " {name} 保存成功",
"restoreSavedSuccess": " {name} 恢复成功",
"noSavedLayout": "没有找到保存的布局 {name}",
"layout1": "布局1",
"layout2": "布局2",
"layout3": "布局3"
},
kpiOverView:{
"kpiChartTitle":"网元指标概览",
"changeLine":"切换为折线图",
"changeBar":"切换为柱状图",
"chooseShowMetrics":"选择需要显示的指标",
"chooseMetrics":"选择指标",
},
},
traceManage: {
analysis: {
@@ -855,18 +1119,23 @@ export default {
pcap: {
capArgPlease: '请输入tcpdump -i any支持参数',
cmd: '命令',
execCmd: "通用tcpdump抓包命令",
execCmdsSctp: "过滤sctp和port命令",
execUPFCmdA: '适合其他网元异常UPF配合抓包的情况',
execUPFCmdB: '适合UPF异常需要抓包分析的情况',
execCmd: "通用命令选项",
execCmd2: "过滤协议端口命令",
execCmd3: "分割文件按时间单位秒 (-G 10 ),最多生成文件数量 (-W 7)",
execUPFCmdA: '标准版-UPF配合其他网元异常抓包分析',
execUPFCmdB: '标准版-UPF异常需要抓包分析',
batchOper: '批量操作',
batchStartText: '批量开始',
batchStopText: '批量停止',
batchDownText: '批量下载',
fileView: '历史抓包文件',
fileUPF: '标准版',
fileUPFTip: 'UPF内部抓包分析包',
textStart: "开始",
textStartBatch: "批量开始",
textStop: "停止",
textStopBatch: "批量停止",
textLog: "日志",
textLogMsg: "日志信息",
textLog: "日志文件",
textLogMsg: "日志文件信息",
textDown: "下载",
textDownBatch: "批量下载",
downTip: "确认要下载 {title} 抓包数据文件吗?",
downOk: "{title} 文件下载完成",
downErr: "{title} 文件下载异常",
@@ -880,12 +1149,13 @@ export default {
stopNotRun: "{title} 任务未运行",
},
task: {
neTypePlease: '请选择网元类型',
neType: '网元类型',
neID: '网元内部标识',
traceId: '跟踪编号',
trackType: '跟踪类型',
trackTypePlease: '请选择跟踪类型',
creater: '创建人',
textStop: "停止",
status: '状态',
time: '时间',
startTime: '开始时间',
endTime: '结束时间',
msisdn: 'MSISDN',
@@ -904,17 +1174,22 @@ export default {
interfacesPlease: '请输入信令接口',
signalPort: '信令端口',
signalPortPlease: '请输入信令端口',
signalPortTip: '接口对应的端口',
signalPortTip: '目标IP地址或源IP地址对应一方的端口',
rangePicker: '开始结束时间',
rangePickerPlease: '请选择任务时间开始结束时间',
comment: '任务说明',
commentPlease: '可输入任务说明',
remark: '说明',
remarkPlease: '可输入任务说明',
addTask: '添加任务',
editTask: '修改任务',
viewTask: '查看任务',
errorTaskInfo: '获取任务信息失败',
delTask: '成功删除任务 {num}',
delTaskTip: '确认删除记录编号为 {num} 的数据项?',
delTaskTip: '确认删除记录编号为 {id} 的数据项?',
stopTask: '成功停止任务 {id}',
stopTaskTip: '确认停止记录编号为 {id} 的任务?',
pcapView: "跟踪数据分析",
traceFile: "跟踪文件",
errMsg: "错误信息",
imsiORmsisdn: "imsi 或 msisdn 是空值,不能开始任务",
},
},
faultManage: {
@@ -965,6 +1240,7 @@ export default {
showSet:'显示过滤设置',
exportSure:'确认是否导出全部活动告警信息',
viewIdInfo:'查看{alarmId} 记录信息',
closeModal:'关闭',
},
historyAlarm:{
exportSure:'确认是否导出全部历史告警信息?',
@@ -976,6 +1252,9 @@ export default {
save:'保存设置',
noChange:'告警前转接口设置无变更',
forwardSet:'告警前转接口设置',
},
eventAlarm:{
exportSure:'确认是否导出全部事件告警信息?',
}
},
logManage:{
@@ -1004,8 +1283,9 @@ export default {
alarmId:'告警唯一标识',
alarmSeq:'告警流水号',
alarmObj:'告警前转对象',
alarmInter:'告警前转接口',
alarmTitle:'告警标题',
alarmInfo:'告警内容',
alarmInfo:'操作结果',
eventTime:'告警产生时间',
logTime:'记录时间'
},
@@ -1022,8 +1302,21 @@ export default {
downTip: "确认下载文件名为 【{fileName}】 文件?",
downTipErr: "文件获取失败",
dirCd: "进入目录",
viewAs: '查看操作',
reload: "重载",
follow: '监视内容变化',
tailChar: '末尾字数',
tailLines: '末尾行数',
},
},
exportFile:{
fileName:'文件来源',
downTip: "确认下载文件名为 【{fileName}】 文件?",
downTipErr: "文件获取失败",
deleteTip: "确认删除文件名为 【{fileName}】 文件?",
deleteTipErr: "文件删除失败",
selectTip:"请选择文件名",
}
},
monitor: {
session: {
userName: "登录账号",
@@ -1340,7 +1633,7 @@ export default {
edgeTypeLineAnimateState: "直线,含有状态动画",
edgeLabelPositionStart: "开头",
edgeLabelPositionMiddle: "中间",
edgeLabelPositionEnd: "末尾",
edgeLabelPositionEnd: "末尾",
nodeTypeCircle: "圆形",
nodeTypeRect: "矩形",
nodeTypeEllipse: "椭圆",
@@ -1398,9 +1691,9 @@ export default {
loginIp: '登录地址',
loginTime: '登录时间',
status: '用户状态',
userNameTip:'账号不能以数字开头,可包含大写小写字母,数字,且不少于5位',
userNameTip:'账号只能包含大写字母、小写字母数字的字符串长度至少为6位',
passwdTip:'密码至少包含大小写字母、数字、特殊符号,且不少于6位',
nickNameTip:'昵称只能包含字母、数字、中文和下划线,且不少于2位',
nickNameTip:'昵称不少于2位',
emailTip:'请输入正确的邮箱地址',
phoneTip:'请输入正确的手机号码',
resetPwd:'重置密码',
@@ -1423,7 +1716,7 @@ export default {
userWork:'用户岗位',
userWorkPlease: '请选择用户岗位',
userTip:'用户说明',
loginPwd:'登密码',
loginPwd:'登密码',
updateSure:'是否更新已经存在的数据',
downloadObj:'下载模板',
importTitle:'用户导入',
@@ -1509,6 +1802,13 @@ export default {
i18nOpen: "显示切换",
i18nDefault: "默认语言",
i18nInstruction: '是否显示国际化切换,设置系统默认语言',
reset: "系统重置",
resetInstruction: "系统重置将会清除当前系统内所有数据,请谨慎操作!!!",
resetTipContent: '确认要清除当前系统内所有数据并坚持继续吗?',
homeInstruction:'设置系统首页界面',
home: '系统首页',
homeTip:'确认要提交当前界面为系统界面吗?',
homeSet:'系统首页设置',
},
role:{
allScopeOptions:'全部数据权限',
@@ -1533,10 +1833,10 @@ export default {
distributeUser:'分配用户',
roleMark:'角色说明',
menu:'菜单权限',
roleKeyTip:"权限标识示例:dba 控制器中使用权限标识,如: @PreAuthorize({ hasRoles: ['dba'] })",
roleKeyTip:"权限标识用于控制页面控件或路由接口",
openSwitch:'展开/折叠',
selAllSwitch:'全选/全不选',
relationSwitch:'父子联动',
relationSwitch:'节点联动',
normal:'正常',
stop:'暂停',
preScope:'权限范围',
@@ -1559,7 +1859,7 @@ export default {
className:'部门名称',
classId:'部门编号',
classSort:'部门排序',
status:'岗位状态',
status:'部门状态',
createTime:'创建时间',
highClass:'上级部门',
emailTip:'请输入正确的邮箱地址',
@@ -1590,7 +1890,7 @@ export default {
operate:{
operId:'日志编号',
moduleName:'模块名称',
workType:'业务类型',
workType:'操作类型',
operUser:'操作人员',
requestMe:'请求方式',
host:'请求主机',
@@ -1629,8 +1929,8 @@ export default {
unlockSure:'确认解锁用户 【{username}】 数据项?',
},
},
menu:{
menuInfo:'菜单信息',
menu:{
menuInfo:'菜单信息',
menuName:'菜单名称',
menuId:'菜单编号',
menuSort:'菜单排序',
@@ -1662,7 +1962,7 @@ export default {
componentTip:' 页面组件目录 views 访问的组件路径,如:system/user/index 注意:不带 .vue 文件后缀路由地址是网络地址可填入链接',
perms:`权限标识示例:monitor:server:query 后端控制器中使用权限标识,如:['monitor:server:query'] 前端vue页面中使用权限标识,如:v-perms:has="['monitor:server:query']"`
},
dict:{
dict:{
dictInfo:'字典类型信息',
dictId:'字典编号',
dictName:'字典名称',
@@ -1703,6 +2003,66 @@ export default {
exportOk: "已完成导出",
typeDataErr: "获取字典类型信息失败",
},
quickStart: {
start: '开始设置',
skip: '跳过',
finish: '完成设置',
stepPrev: '上一步',
stepNext: '下一步',
exit: '退出',
save: '保存信息',
sysTitle: '系统配置',
sysAdmin: '管理员',
sysInfo: '系统信息',
sysLogo: '系统LOGO',
sysLogoTip: '将图片展示到系统LOGO区域查看效果请使用透明背景尺寸比例适应区域大小',
sysName: '系统名称',
sysNameTip: '系统名称限制20个字符长度',
sysUploadLogo: '确认要上传系统LOGO文件吗?',
sysUploadOk: '文件上传成功,请进行保存信息',
sysSave: '保存',
sysSaveOk: '信息保存成功!',
sysPrevTip: '确认要返回上一个步骤吗?',
sysNextNe: '确认要进行网元安装吗?',
sysNextDone: '确认要跳过网元安装吗?',
stepNeInfoTitle: "网元服务配置",
stepNeInfoDesc: "设置网元对应的服务终端",
stepNeInfoStepPrev: '确认要退出网元安装步骤吗?',
stepNeInfoStepNext: '确认要下一步进行网元配置参数?',
stepPara5GTitle: "网元配置参数",
stepPara5GDesc: "设置网元全局参数信息",
savePara5GOk: '保存成功!',
stepPara5GStepPrev: '确认要放弃当前变更返回上一步吗?',
stepPara5GStepNext: '确认要下一步进行网元服务安装吗?',
stepInstallTitle: "网元服务安装",
stepInstallDesc: "将网元服务安装到服务终端",
stepInstallStepPrev: '确认要放弃当前变更返回上一步吗?',
stepInstallStepNext: '确认要下一步进行网元许可授权吗?',
stepInstallText: '选择安装',
stepInstallTip: '确认安装选择的网元新版本吗?',
stepInstallModal: '网元进行安装',
stepInstallNotNewVer: '没有发现新版本',
stepInstallDone: '安装完成,服务进入初始化',
stepInstallFail: '安装失败,请检查服务终端环境是否可用!',
stepLicenseTitle: "网元许可授权",
stepLicenseDesc: "获取网元许可激活码进行授权认证",
stepLicenseReload: '选择刷新许可证',
stepLicenseReloadTip: '确认刷新选择的许可证信息吗?',
stepLicenseDownCode: '选择下载网元许可激活码',
stepLicenseDownCodeTip: '确认下载选择的网元许可激活码到文本文件吗?',
stepLicenseStepPrev: '确认要放弃当前变更返回上一步吗?',
stepLicenseStepNext: '确认要结束网元安装步骤吗?',
stepLicenseStepNext2: '请下载网元许可授权码文件保存,并联系网元厂商获取授权许可证',
stepLicenseEnd: '结束',
doneTitle: "完成配置",
doneTip: '请进入系统后,根据情况进行更多相关配置',
doneNETitle: '已经进行网元安装配置',
doneNEDesc: '如有异常网元,可在系统内重新安装授权许可',
doneSkipTitle: '未进行网元安装配置',
doneSkipDesc: '系统将会默认初始网元信息,可在系统内自行修改或进行安装',
donePrevTip: '确认要返回上一个步骤吗?',
doneOkTip: '确认完成设置并开始使用吗?',
},
},
mmlManage: {
cmdTitle: "命令导航",
@@ -1710,14 +2070,14 @@ export default {
cmdOpTip: "左侧命令导航中选择要操作项!",
cmdNoTip: "{num} 无可选命令操作",
require: "必填参数:{num}",
requireUn: "{display} 输入值是未知类型",
requireString: "{display} 参数值不合理",
requireInt: "{display} 参数值不在合理范围 {filter}",
requireIpv4: "{display} 不是合法的IPV4地址",
requireIpv6: "{display} 不是合法的IPV6地址",
requireEnum: "{display} 不是合理的枚举值",
requireBool: "{display} 不是合理的布尔类型的值",
requireFile: "{display} 不是符合参数文件类型的值",
requireUn: "{display} 输入值是未知类型",
requireString: "{display} 参数值不合理",
requireInt: "{display} 参数值不在合理范围 {filter}",
requireIpv4: "{display} 不是合法的IPV4地址",
requireIpv6: "{display} 不是合法的IPV6地址",
requireEnum: "{display} 不是合理的枚举值",
requireBool: "{display} 不是合理的布尔类型的值",
requireFile: "{display} 不是符合参数文件类型的值",
cmdQuickEntry: "命令快速输入",
cmdQuickEntryHelp: "换行(Shift + Enter) 执行发送(Enter)",
cmdParamPanel: "参数面板",
@@ -1772,6 +2132,28 @@ export default {
hostSelectMore: "加载更多 {num}",
hostSelectHeader: "主机列表",
},
ps:{
realTimeHigh:"高",
realTimeLow:"低",
realTimeRegular:"常规",
realTimeStop:"已暂停",
realTime:"实时更新速度",
pid:"PID",
name:"应用名称",
username:"用户名",
runTime:"运行时间",
numThreads:"线程数",
cpuPercent:"CPU使用率",
diskRead:"磁盘读取",
diskWrite:"磁盘写入",
},
net:{
localAddr:"本地地址",
remoteAddr:"远程地址",
status:"状态",
proto:"协议",
port:"端口",
},
},
},
};

View File

@@ -4,12 +4,20 @@ import {
WaterMark,
getMenuData,
clearMenuItem,
MenuDataItem,
type MenuDataItem,
} from 'antdv-pro-layout';
import RightContent from './components/RightContent.vue';
import Tabs from './components/Tabs.vue';
import GlobalMask from '@/components/GlobalMask/index.vue';
import { scriptUrl } from '@/assets/js/icon_font_8d5l8fzk5b87iudi';
import { computed, reactive, watch, onMounted, onUnmounted } from 'vue';
import {
computed,
reactive,
watch,
onMounted,
onUnmounted,
nextTick,
} from 'vue';
import useLayoutStore from '@/store/modules/layout';
import useRouterStore from '@/store/modules/router';
import useTabsStore from '@/store/modules/tabs';
@@ -21,6 +29,7 @@ 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 { t, currentLocale } = useI18n();
@@ -50,7 +59,7 @@ watch(
// 路由地址含有内嵌地址标识又是隐藏菜单需要处理打开高亮菜单栏
if (v.path.includes(MENU_PATH_INLINE) && v.meta.hideInMenu) {
const idx = v.path.lastIndexOf(MENU_PATH_INLINE);
layoutState.openKeys.splice(-1);
layoutState.openKeys = layoutState.selectedKeys.slice(0, -1);
layoutState.selectedKeys[matched.length - 1] = v.path.slice(0, idx);
}
},
@@ -159,8 +168,28 @@ function fnLocale(m: MenuDataItem) {
return title;
}
/**检查系统名称是否超出范围进行滚动 */
function fnCheckAppNameOverflow() {
const container: HTMLDivElement | null = document.querySelector('.app-name');
if (!container) return;
const text: HTMLDivElement | null = container.querySelector('.marquee');
if (!text) return;
if (text.offsetWidth > container.offsetWidth) {
text.classList.add('app-name_scrollable');
text.setAttribute('data-content', text.innerText);
} else {
text.classList.remove('app-name_scrollable');
}
}
watch(
() => appStore.appName,
() => nextTick(fnCheckAppNameOverflow)
);
//
onMounted(() => {
fnCheckAppNameOverflow();
fnGetServerTime();
useAlarmStore().fnGetActiveAlarmInfo();
});
@@ -224,12 +253,10 @@ onUnmounted(() => {
v-model:selectedKeys="layoutState.selectedKeys"
v-model:openKeys="layoutState.openKeys"
:menu-data="menuData"
:breadcrumb="{ routes: breadcrumb } as any"
disable-content-margin
:breadcrumb="{ routes: breadcrumb }"
v-bind="proConfig"
:iconfont-url="scriptUrl"
:sider-width="208"
:locale="(fnLocale as any)"
:locale="fnLocale"
>
<!--插槽-菜单头-->
<template #menuHeaderRender>
@@ -246,8 +273,10 @@ onUnmounted(() => {
:alt="appStore.appName"
:title="appStore.appName"
/>
<h1 class="title" :title="appStore.appName">
{{ appStore.appName }}
<h1 class="app-name" :title="appStore.appName">
<span class="marquee app-name_scrollable">
{{ appStore.appName }}
</span>
</h1>
</template>
<template v-if="appStore.logoType === 'brand'">
@@ -265,7 +294,7 @@ onUnmounted(() => {
<template #headerContentRender></template>
<!--插槽-顶部右侧-->
<template #rightContentRender>
<template #headerContentRightRender>
<RightContent />
</template>
@@ -300,9 +329,6 @@ onUnmounted(() => {
</transition>
</RouterView>
<!-- 锁屏遮罩 -->
<LockScreen />
<!--插槽-内容底部-->
<template #footerRender="{ width }">
<footer class="footer">
@@ -317,11 +343,17 @@ onUnmounted(() => {
:href="appStore.officialUrl"
target="_blank"
size="small"
v-perms:has="['system:setting:official']"
v-if="appStore.officialUrl !== '#'"
>
{{ t('loayouts.basic.officialUrl') }}
</a-button>
<a-button type="link" size="small" @click="fnClickHelpDoc()">
<a-button
type="link"
size="small"
v-perms:has="['system:setting:doc']"
@click="fnClickHelpDoc()"
>
{{ t('loayouts.basic.helpDoc') }}
</a-button>
</a-space>
@@ -329,6 +361,9 @@ onUnmounted(() => {
</footer>
</template>
</ProLayout>
<!-- 全局遮罩 -->
<GlobalMask />
</WaterMark>
</template>
@@ -349,18 +384,40 @@ onUnmounted(() => {
margin-right: 16px;
}
.title {
.app-name {
overflow: hidden;
text-overflow: ellipsis;
// text-overflow: ellipsis;
white-space: nowrap;
width: 130px;
width: 148px;
> .app-name_scrollable {
padding-right: 12px;
display: inline-block;
animation: scrollable-animation linear 6s infinite both;
&::after {
content: attr(data-content);
position: absolute;
top: 0;
right: -100%;
transition: right 0.3s ease;
}
@keyframes scrollable-animation {
0% {
transform: translateX(0);
}
100% {
transform: translateX(calc(-100% - 12px));
}
}
}
}
.footer {
z-index: 16;
margin: 0px;
width: auto;
margin-top: 52px;
margin-top: 32px;
&-fixed {
position: fixed;
bottom: 0;
@@ -378,7 +435,8 @@ onUnmounted(() => {
}
& #serverTimeDom {
color: #00000085;
color: inherit;
opacity: 0.85;
transition: all 0.3s;
}
}

View File

@@ -1,19 +1,20 @@
<script setup lang="ts">
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import Modal from 'ant-design-vue/lib/modal/Modal';
import { useRouter } from 'vue-router';
import { useRoute, useRouter } from 'vue-router';
import { useFullscreen } from '@vueuse/core';
import useI18n from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user';
import useAlarmStore from '@/store/modules/alarm';
import useLockedStore from '@/store/modules/locked';
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 lockedStore = useLockedStore();
const maskStore = useMaskStore();
const userStore = useUserStore();
const appStore = useAppStore();
const route = useRoute();
const router = useRouter();
/**头像展开项点击 */
@@ -31,15 +32,24 @@ function fnClick({ key }: MenuInfo) {
}
}
/**锁屏确认 */
const lockConfirm = ref<boolean>(false);
/**锁屏密码 */
const lockPasswd = ref<string>('');
/**锁屏按钮提示 */
function fnClickLock() {
Modal.confirm({
title: t('common.tipTitle'),
content: t('loayouts.rightContent.lockTip'),
onOk() {
lockedStore.fnLock('lock');
},
});
lockConfirm.value = true;
lockPasswd.value = '';
maskStore.lockPasswd = '';
}
/**锁屏确认跳转锁屏页面 */
function fnClickLockToPage() {
lockConfirm.value = false;
maskStore.lockPasswd = lockPasswd.value;
maskStore.handleMaskType('lock');
router.push({ name: 'LockScreen', query: { redirect: route.path } });
}
/**告警数按钮提示跳转 */
@@ -47,16 +57,6 @@ function fnClickAlarm() {
router.push({ name: 'ActiveAlarm_2088' });
}
/**系统使用手册跳转 */
function fnClickHelpDoc(language?: string) {
const routeData = router.resolve({ name: 'HelpDoc' });
let href = routeData.href;
if (language) {
href = `${routeData.href}?language=${language}`;
}
window.open(href, '_blank');
}
/**改变多语言 */
function fnChangeLocale(e: any) {
changeLocale(e.key);
@@ -65,39 +65,63 @@ function fnChangeLocale(e: any) {
<template>
<a-space :size="12" align="center">
<a-button type="text" @click="fnClickAlarm">
<template #icon>
<a-badge
:count="useAlarmStore().activeAlarmTotal"
:overflow-count="99"
status="warning"
<a-tooltip placement="bottom">
<template #title>{{ t('loayouts.rightContent.alarm') }}</template>
<a-button type="text" style="color: inherit" @click="fnClickAlarm">
<template #icon>
<a-badge
:count="useAlarmStore().activeAlarmTotal"
:overflow-count="99"
status="warning"
style="color: inherit"
>
<BellOutlined />
</a-badge>
</template>
</a-button>
</a-tooltip>
<!-- 锁屏操作 -->
<span v-perms:has="['system:setting:lock']">
<a-tooltip placement="bottom">
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
<a-button type="text" style="color: inherit" @click="fnClickLock()">
<template #icon>
<LockOutlined />
</template>
</a-button>
<ProModal
:drag="true"
:width="400"
:minHeight="200"
:mask-closable="false"
v-model:visible="lockConfirm"
:title="t('loayouts.rightContent.lockTip')"
@ok="fnClickLockToPage()"
>
<BellOutlined />
</a-badge>
</template>
</a-button>
<a-tooltip placement="bottom">
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
<a-button type="text" @click="fnClickLock">
<template #icon>
<LockOutlined />
</template>
</a-button>
</a-tooltip>
<a-tooltip placement="bottom">
<template #title>{{ t('loayouts.rightContent.helpDoc') }}</template>
<a-button type="text" @click="fnClickHelpDoc()">
<template #icon>
<QuestionCircleOutlined />
</template>
</a-button>
</a-tooltip>
<a-space>
{{ t('loayouts.rightContent.lockPasswd') }}
<a-input-password
v-model:value="lockPasswd"
:placeholder="t('common.inputPlease')"
>
<template #prefix>
<a-tooltip
:title="t('loayouts.rightContent.lockPasswdTip')"
placement="topLeft"
>
<UnlockOutlined />
</a-tooltip>
</template>
</a-input-password>
</a-space>
</ProModal>
</a-tooltip>
</span>
<a-tooltip placement="bottom">
<template #title>{{ t('loayouts.rightContent.fullscreen') }}</template>
<a-button type="text" @click="toggle">
<a-button type="text" style="color: inherit" @click="toggle">
<template #icon>
<FullscreenExitOutlined v-if="isFullscreen" />
<FullscreenOutlined v-else />
@@ -107,7 +131,7 @@ function fnChangeLocale(e: any) {
<a-dropdown
placement="bottom"
:trigger="['click', 'hover']"
trigger="click"
v-if="appStore.i18nOpen && hasPermissions(['system:setting:i18n'])"
>
<a-button size="small" type="default">
@@ -123,7 +147,7 @@ function fnChangeLocale(e: any) {
</template>
</a-dropdown>
<a-dropdown placement="bottomRight" :trigger="['click', 'hover']">
<a-dropdown placement="bottomRight" trigger="click">
<div class="user">
<a-avatar
shape="circle"

View File

@@ -95,7 +95,7 @@ function fnTabClose(path: string) {
/**
* 国际化翻译转换
*/
function fnLocale(title: string) {
function fnLocale(title: string) {
if (title.indexOf('router.') !== -1) {
title = t(title);
}
@@ -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 :trigger="['click', 'hover']" placement="bottomRight">
<a-dropdown trigger="click" placement="bottomRight">
<a-button type="ghost" shape="circle" size="small">
<template #icon><DownOutlined /></template>
</a-button>

View File

@@ -4,7 +4,9 @@ import App from './App.vue';
import router from './router';
import directive from './directive';
import i18n from './i18n';
import ProModal from "antdv-pro-modal";
import 'antdv-pro-layout/dist/style.css';
import 'antdv-pro-modal/dist/style.css';
import 'ant-design-vue/dist/antd.variable.min.css';
const app = createApp(App);
@@ -12,5 +14,6 @@ app.use(store);
app.use(router);
app.use(directive);
app.use(i18n);
app.use(ProModal);
app.mount('#app');

View File

@@ -1,7 +1,7 @@
import Cookies from 'js-cookie';
import { TOKEN_COOKIE } from '@/constants/token-constants';
import { localRemove, localSet } from '@/utils/cache-local-utils';
import { CACHE_LOCAL_LOCK } from '@/constants/cache-keys-constants';
import { CACHE_LOCAL_LOCK_PASSWD, CACHE_LOCAL_MASK } from '@/constants/cache-keys-constants';
/**获取cookis中Token字符串 */
export function getToken(): string {
@@ -11,11 +11,12 @@ export function getToken(): string {
/**设置cookis中Token字符串 */
export function setToken(token: string): void {
Cookies.set(TOKEN_COOKIE, token);
localSet(CACHE_LOCAL_LOCK, 'none');
localSet(CACHE_LOCAL_MASK, 'none');
}
/**移除cookis中Token字符串,localStorage中锁屏字符串 */
export function removeToken(): void {
Cookies.remove(TOKEN_COOKIE);
localRemove(CACHE_LOCAL_LOCK);
localRemove(CACHE_LOCAL_MASK);
localRemove(CACHE_LOCAL_LOCK_PASSWD);
}

View File

@@ -13,10 +13,13 @@ import {
import {
APP_REQUEST_HEADER_CODE,
APP_REQUEST_HEADER_VERSION,
APP_DATA_API_KEY,
} from '@/constants/app-constants';
import {
RESULT_CODE_ENCRYPT,
RESULT_CODE_ERROR,
RESULT_CODE_SUCCESS,
RESULT_MSG_ENCRYPT,
RESULT_MSG_ERROR,
RESULT_MSG_NOT_TYPE,
RESULT_MSG_SERVER_ERROR,
@@ -25,11 +28,12 @@ import {
RESULT_MSG_URL_NOTFOUND,
RESULT_MSG_URL_RESUBMIT,
} from '@/constants/result-constants';
import { decryptAES, encryptAES } from '@/utils/encrypt-utils';
/**响应结果类型 */
export type ResultType = {
/**响应码 */
code: number | 1 | 0;
code: number;
/**信息 */
msg: string;
/**数据 */
@@ -76,6 +80,8 @@ type OptionsType = {
body?: BodyInit;
/**防止数据重复提交 */
repeatSubmit?: boolean;
/**接口数据加密 */
crypto?: boolean;
/**携带授权Token请求头 */
whithToken?: boolean;
/**中断控制信号timeout不会生效 */
@@ -165,26 +171,43 @@ function beforeRequest(options: OptionsType): OptionsType | Promise<any> {
}
}
// get请求拼接地址栏参数
if (options.method === 'get' && options.params) {
let paramStr = '';
// 请求拼接地址栏参数
if (options.params) {
const params = options.params;
const queryParams: string[] = [];
for (const key in params) {
const value = params[key];
// 空字符或未定义的值不作为参数发送
if (value === '' || value === undefined) continue;
paramStr += `&${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
const str = `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
queryParams.push(str);
}
if (paramStr && paramStr.startsWith('&')) {
options.url = `${options.url}?${paramStr.substring(1)}`;
const paramStr = queryParams.join('&');
if (paramStr) {
const separator = options.url.includes('?') ? '&' : '?';
// 请求加密
if (options.crypto) {
const data = encryptAES(JSON.stringify(paramStr), APP_DATA_API_KEY);
options.url += `${separator}data=${encodeURIComponent(data)}`;
} else {
options.url += `${separator}${paramStr}`;
}
}
}
if (options.method === 'get') return options;
// 非get参数提交
if (options.data instanceof FormData) {
options.body = options.data;
} else {
options.body = JSON.stringify(options.data);
let body = options.data
if (body instanceof FormData) {
options.body = body;
} else if (body) {
// 请求加密
if (options.crypto) {
const data = encryptAES(JSON.stringify(body), APP_DATA_API_KEY);
body = { data };
}
options.body = JSON.stringify(body);
}
return options;
}
@@ -199,6 +222,28 @@ function interceptorResponse(res: ResultType): ResultType | Promise<any> {
window.location.reload();
}
// 响应数据解密
if (res.code === RESULT_CODE_ENCRYPT) {
const str = decryptAES(res.data, APP_DATA_API_KEY);
let data = {};
try {
data = JSON.parse(str);
} catch (error) {
console.error(error);
}
if (Object.keys(data).length === 0) {
return Promise.resolve({
code: RESULT_CODE_ERROR,
msg: RESULT_MSG_ENCRYPT[language],
});
}
return Promise.resolve({
code: RESULT_CODE_SUCCESS,
msg: RESULT_MSG_SUCCESS[language],
data,
});
}
// 风格处理
if (!Reflect.has(res, 'code')) {
return Promise.resolve({
@@ -266,7 +311,7 @@ export async function request(options: OptionsType): Promise<ResultType> {
case 'text': // 文本数据
const str = await res.text();
return {
code: 1,
code: RESULT_CODE_SUCCESS,
msg: str,
};
case 'json': // json格式数据

124
src/plugins/wk-worker.ts Normal file
View File

@@ -0,0 +1,124 @@
/**连接参数类型 */
export type OptionsType = {
/**
* 线路工作服务地址
*
* self.onmessage = error => {} - 接收消息
*
* self.postMessage() -回复消息
*/
url: string;
/**message事件的回调函数 */
onmessage: (data: any) => void;
/**error事件的回调函数 */
onerror: Function;
/**close事件的回调函数 */
onclose?: (code: number) => void;
};
/**
* Web Worker 使用方法
*
* import { WK, OptionsType } from '@/plugins/wk-worker';
*
* const wk = new WK();
*
* 创建连接
* const options: OptionsType = { };
* wk.connect(options);
*
* 手动关闭
* wk.close();
*/
export class WK {
/**wk 实例 */
private wk: Worker | null = null;
/**wk 连接参数 */
private options: OptionsType | null = null;
/**
* 构造函数
* @param {object} params 构造函数参数
*/
constructor(options?: OptionsType) {
if (!window.Worker) {
// 检测浏览器支持
console.error('Sorry! Browser does not support Web Workers');
return;
}
options && this.connect(options);
}
/**
* 创建链接
* @param {object} options 连接参数
*/
public connect(options: OptionsType) {
this.options = options;
try {
const wk = new Worker(options.url);
// 用于收到来自其消息时的回调函数。
wk.onmessage = ev => {
// 解析文本消息
if (ev.type === 'message') {
try {
if (typeof options.onmessage === 'function') {
options.onmessage(ev.data);
}
} catch (error) {
console.error('worker message formatting error', error);
}
}
};
// 用于发生错误关闭后的回调函数。
wk.onmessageerror = ev => {
console.error('worker message error anomaly', ev);
if (typeof options.onclose === 'function') {
options.onerror(ev);
}
};
// 用于发生错误后的回调函数。
wk.onerror = ev => {
console.error('worker error anomaly', ev);
if (typeof options.onerror === 'function') {
options.onerror(ev);
}
};
this.wk = wk;
} catch (error) {
if (typeof options.onerror === 'function') {
options.onerror(error);
}
}
}
/**
* 发送消息
* @param data JSON数据
* @returns
*/
public send(data: Record<string, any>): boolean {
if (!this.wk) {
console.warn('worker unavailable');
return false;
}
this.wk.postMessage(data);
return true;
}
// 手动关闭会被立即终止
public close() {
if (!this.wk) {
console.warn('worker unavailable');
return;
}
this.wk.terminate();
// 用于关闭后的回调函数。
if (this.options && typeof this.options.onclose === 'function') {
this.options.onclose(1000);
}
}
}

View File

@@ -27,7 +27,7 @@ export type OptionsType = {
/**
* WebSocket 使用方法
*
* import WS from '@/plugins/ws-websocket.ts';
* import { OptionsType, WS } from '@/plugins/ws-websocket';
*
* const ws = new WS();
*

View File

@@ -87,6 +87,24 @@ const constantRoutes: RouteRecordRaw[] = [
meta: { title: 'router.helpDoc' },
component: () => import('@/views/tool/help/index.vue'),
},
{
path: '/trace-task-hlr',
name: 'TraceTaskHLR',
meta: { title: 'router.traceTaskHLR' },
component: () => import('@/views/traceManage/task-hlr/index.vue'),
},
{
path: '/quick-start',
name: 'QuickStart',
meta: { title: 'router.quickStart' },
component: () => import('@/views/system/quick-start/index.vue'),
},
{
path: '/lock-screen',
name: 'LockScreen',
meta: { title: 'router.lockScreen' },
component: () => import('@/views/tool/lockScreen/index.vue'),
},
{
path: '/redirect',
name: 'Redirect',
@@ -136,18 +154,36 @@ router.afterEach((to, from, failure) => {
});
/**无Token可访问页面地址白名单 */
const WHITE_LIST: string[] = ['/login', '/auth-redirect', '/help', '/register'];
const WHITE_LIST: string[] = [
'/login',
'/auth-redirect',
'/help',
'/register',
'/quick-start',
'/trace-task-hlr',
];
/**全局路由-前置守卫 */
router.beforeEach((to, from, next) => {
router.beforeEach(async (to, from, next) => {
NProgress.start();
const token = getToken();
// 获取系统配置信息
const appStore = useAppStore();
if (!appStore.loginBackground) {
appStore.fnSysConf();
await appStore.fnSysConf();
}
// 需要系统引导跳转
if (appStore.bootloader && to.path !== '/quick-start') {
next({ name: 'QuickStart' });
}
// 不重复引导
if (!appStore.bootloader && to.path === '/quick-start') {
next({ name: 'Index' });
}
const token = getToken();
// 没有token
if (!token) {
if (WHITE_LIST.includes(to.path)) {
@@ -168,31 +204,27 @@ router.beforeEach((to, from, next) => {
// 判断当前用户是否有角色信息
const user = useUserStore();
if (user.roles && user.roles.length === 0) {
// 获取用户信息
user
.fnGetInfo()
.then(() => {
return useRouterStore().generateRoutes();
})
.then(accessRoutes => {
// 根据后台配置生成可访问的路由表
if (accessRoutes && accessRoutes.length !== 0) {
for (const route of accessRoutes) {
// 动态添加可访问路由表http开头会异常
if (!validHttp(route.path)) {
router.addRoute(route);
}
try {
// 获取用户信息
await user.fnGetInfo();
// 获取路由信息
const accessRoutes = await useRouterStore().generateRoutes();
// 根据后台配置生成可访问的路由表
if (accessRoutes && accessRoutes.length !== 0) {
for (const route of accessRoutes) {
// 动态添加可访问路由表http开头会异常
if (!validHttp(route.path)) {
router.addRoute(route);
}
}
// 刷新替换原先路由确保addRoutes已完成
next({ ...to, replace: true });
})
.catch(e => {
console.error(`[${to.path}]: ${e.message}`);
user.fnLogOut().finally(() => {
next({ name: 'Login' });
});
});
}
// 刷新替换原先路由确保addRoutes已完成
next({ ...to, replace: true });
} catch (error: any) {
console.error(`[${to.path}]: ${error.message}`);
await user.fnLogOut();
next({ name: 'Login' });
}
} else {
next();
}

View File

@@ -1,6 +1,7 @@
import { getSysConf } from '@/api';
import { CACHE_LOCAL_I18N } from '@/constants/cache-keys-constants';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { removeToken } from '@/plugins/auth-token';
import { parseUrlPath } from '@/plugins/file-static-url';
import { localGet, localSet } from '@/utils/cache-local-utils';
import { defineStore } from 'pinia';
@@ -17,6 +18,8 @@ type AppStore = {
/**服务版本 */
version: string;
buildTime: string;
/**系统引导使用 */
bootloader: boolean;
// 序列号
serialNum: string;
/**应用版权声明 */
@@ -48,6 +51,7 @@ const useAppStore = defineStore('app', {
version: `-`,
buildTime: `-`,
bootloader: false,
serialNum: `-`,
copyright: `Copyright ©2023 For ${import.meta.env.VITE_APP_NAME}`,
logoType: 'icon',
@@ -57,7 +61,7 @@ const useAppStore = defineStore('app', {
loginBackground: '',
helpDoc: '',
officialUrl: '',
i18nOpen: true,
i18nOpen: false,
i18nDefault: 'en_US',
}),
getters: {},
@@ -70,16 +74,17 @@ const useAppStore = defineStore('app', {
document.title = this.appName;
}
},
/**设置版权声明 */
setCopyright(text: string) {
this.copyright = text;
},
// 获取系统配置信息
async fnSysConf() {
const res = await getSysConf();
if (res.code === RESULT_CODE_SUCCESS && res.data) {
this.version = res.data.version;
this.buildTime = res.data.buildTime;
this.bootloader = res.data.bootloader === 'true';
// 引导时
if (this.bootloader) {
removeToken();
}
this.serialNum = res.data.serialNum;
this.appName = res.data.title;
this.copyright = res.data.copyright;

View File

@@ -32,8 +32,8 @@ const useDictStore = defineStore('dict', {
{
label: data.dictLabel,
value: data.dictValue,
elTagType: data.tagType,
elTagClass: data.tagClass,
tagType: data.tagType,
tagClass: data.tagClass,
},
];
},
@@ -47,8 +47,8 @@ const useDictStore = defineStore('dict', {
const dictData: DictType[] = res.data.map(d => ({
label: d.dictLabel,
value: d.dictValue,
elTagType: d.tagType,
elTagClass: d.tagClass,
tagType: d.tagType,
tagClass: d.tagClass,
}));
this.dicts.set(key, dictData);
disct = dictData;

View File

@@ -10,10 +10,10 @@ type LayoutStore = {
proConfig: {
/**导航布局 */
layout: 'side' | 'top' | 'mix';
/**导航菜单主题色 */
navTheme: 'dark' | 'light';
/**顶部导航主题仅导航布局为mix时生效 */
headerTheme: 'dark' | 'light';
/**全局主题色,需要导入样式文件 */
theme: 'dark' | 'light';
/**菜单导航主题 */
menuTheme: 'dark' | 'light';
/**固定顶部栏 */
fixedHeader: boolean;
/**固定菜单栏 */
@@ -41,8 +41,8 @@ const proConfigLocal: LayoutStore['proConfig'] = localGetJSON(
CACHE_LOCAL_PROCONFIG
) || {
layout: 'mix',
headerTheme: 'light',
navTheme: 'light',
theme: 'light',
menuTheme: 'light',
fixSiderbar: true,
fixedHeader: true,
splitMenus: true,
@@ -53,8 +53,8 @@ const useLayoutStore = defineStore('layout', {
visible: false,
proConfig: {
layout: proConfigLocal.layout,
navTheme: proConfigLocal.navTheme,
headerTheme: proConfigLocal.headerTheme,
theme: proConfigLocal.theme,
menuTheme: proConfigLocal.menuTheme,
fixedHeader: Boolean(proConfigLocal.fixedHeader),
fixSiderbar: Boolean(proConfigLocal.fixSiderbar),
splitMenus: Boolean(proConfigLocal.splitMenus),
@@ -77,10 +77,6 @@ const useLayoutStore = defineStore('layout', {
/**修改布局设置 */
changeConf(key: string, value: boolean | string | number | undefined) {
if (Reflect.has(this.proConfig, key)) {
// 同时修改mix混合菜单的导航主题
if (key === 'navTheme') {
Reflect.set(this.proConfig, 'headerTheme', value);
}
Reflect.set(this.proConfig, key, value);
localSetJSON(CACHE_LOCAL_PROCONFIG, this.proConfig);
}

View File

@@ -1,51 +0,0 @@
import { getSysConf } from '@/api';
import { CACHE_LOCAL_LOCK } from '@/constants/cache-keys-constants';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { localGet, localSet } from '@/utils/cache-local-utils';
import { defineStore } from 'pinia';
/**锁屏信息类型 */
type Locked = {
/**锁屏类型 */
type: 'none' | 'lock' | 'reload' | string;
/**lock 超时锁屏时间,秒*/
lockTimeout: number;
};
const useLockedStore = defineStore('locked', {
state: (): Locked => ({
type: localGet(CACHE_LOCAL_LOCK) || 'none',
lockTimeout: 0,
}),
getters: {},
actions: {
// 重启等待-轮询
async relaodWait() {
try {
const res = await getSysConf();
if (res.code === RESULT_CODE_SUCCESS && res.data) {
this.fnLock('none');
window.location.reload();
}
} catch (error) {
// 延迟5秒
setTimeout(() => {
this.relaodWait();
}, 5_000);
}
},
// 设置锁定
async fnLock(type: 'none' | 'lock' | 'reload' | string) {
this.type = type;
localSet(CACHE_LOCAL_LOCK, type);
if (type === 'reload') {
// 延迟5秒
setTimeout(() => {
this.relaodWait();
}, 2_000);
}
},
},
});
export default useLockedStore;

70
src/store/modules/mask.ts Normal file
View File

@@ -0,0 +1,70 @@
import { getSysConf } from '@/api';
import {
CACHE_LOCAL_LOCK_PASSWD,
CACHE_LOCAL_MASK,
} from '@/constants/cache-keys-constants';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { localGet, localRemove, localSet } from '@/utils/cache-local-utils';
import { defineStore } from 'pinia';
/**全局遮罩信息类型 */
type MaskStateType = {
/**锁屏类型 */
type: 'none' | 'lock' | 'reload' | 'reset';
/**lock 锁屏密码*/
lockPasswd: string;
/**lock 超时锁屏时间,秒*/
lockTimeout: number;
};
const useMaskStore = defineStore('mask', {
state: (): MaskStateType => ({
type: (localGet(CACHE_LOCAL_MASK) || 'none') as MaskStateType['type'],
lockPasswd: localGet(CACHE_LOCAL_LOCK_PASSWD) || '',
lockTimeout: 0,
}),
getters: {},
actions: {
// 检查服务等待-轮询
async checkServiceWait() {
try {
const res = await getSysConf();
if (res.code === RESULT_CODE_SUCCESS && res.data) {
// 延迟5秒
setTimeout(() => {
this.handleMaskType('none');
window.location.reload();
}, 2_000);
} else {
// 延迟5秒
setTimeout(() => {
this.checkServiceWait();
}, 5_000);
}
} catch (error) {
// 延迟5秒
setTimeout(() => {
this.checkServiceWait();
}, 5_000);
}
},
// 设置遮罩类型
async handleMaskType(type: MaskStateType['type']) {
this.type = type;
localSet(CACHE_LOCAL_MASK, type);
if (type === 'reload') {
// 延迟5秒
setTimeout(() => {
this.checkServiceWait();
}, 5_000);
}
if (type === 'lock') {
localSet(CACHE_LOCAL_LOCK_PASSWD, this.lockPasswd);
} else {
localRemove(CACHE_LOCAL_LOCK_PASSWD);
}
},
},
});
export default useMaskStore;

Some files were not shown because too many files have changed in this diff Show More