Compare commits

..
Author SHA1 Message Date
TsMask 2fb3467fb5 mager: 合并11.2版本 2024-11-23 10:57:55 +08:00
TsMask 63d7d11350 Merge remote-tracking branch 'origin/main' into practical-training 2024-08-03 14:11:19 +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 2bd98540be Merge remote-tracking branch 'origin/main' into practical-training 2024-08-01 17:53:53 +08:00
TsMask e21a8dc898 perf: 优化快速安装配置公共参数页面 2024-08-01 17:34:16 +08:00
TsMask 630c63e23f feat: 配置数据导出成表格,多语言翻译 2024-08-01 16:07:17 +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 ada1f388fc fix: 参数配置array展开显示异常 2024-07-30 09:32:52 +08:00
TsMask c73fcbd91c chore: 更新版本号 2.240729 2024-07-29 18:27:15 +08:00
TsMask b9cf34714f feat: 网元信息允许教师备份操作权限控制 2024-07-29 15:28:22 +08:00
TsMask 53200d5f41 feat: 网元配置备份操作权限控制删除/编辑按钮 2024-07-29 15:27:50 +08:00
TsMask 023e317b0d feat: 网元配置备份操作权限控制删除/编辑按钮 2024-07-29 14:36:19 +08:00
lai 543a2b7434 新增 统一配置网元 2024-07-29 10:38:14 +08:00
TsMask 52d5b9b732 style: 学生关闭右击样式 2024-07-27 16:14:59 +08:00
TsMask 292488f20c fix: 配置载入时禁用切换网元 2024-07-27 16:13:08 +08:00
TsMask b0b844f0f6 fix: 学生禁止操作删除日志CDR/Event 2024-07-27 16:11:59 +08:00
TsMask 0819fbdb44 Merge remote-tracking branch 'origin/main' into practical-training 2024-07-27 15:03:16 +08:00
TsMask 4ae9051411 style: 系统设置LOGO和文档判断是否开启语言切换显示控件 2024-07-27 15:01:56 +08:00
TsMask a88ae826cc Merge remote-tracking branch 'origin/main' into practical-training 2024-07-27 14:16:15 +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 76499d98e0 fix: 参数数据与示例对比差异显示功能 2024-07-22 18:16:48 +08:00
TsMask 94ccb45f8c style: 配置历史记录抽屉展开的title初始为空避免显示错误 2024-07-22 18:14:29 +08:00
TsMask 79e2b4ac26 feat: 添加是否系统管理员的权限判断函数 2024-07-22 11:46:23 +08:00
TsMask b2510c0eb3 fix: 班级学生列表搜索时刷新合并申请状态,可直接应用和退回操作 2024-07-22 11:45:15 +08:00
TsMask f977b6ea53 style: 添加用户水印,学生菜单布局侧边栏显示 2024-07-19 17:32:58 +08:00
TsMask 1e9c6a51be fix: 教师只能重启网元,禁止操作网元信息 2024-07-19 17:31:45 +08:00
TsMask d68a773214 feat: 历史记录抽屉查看数据对比差异 2024-07-19 16:23:01 +08:00
TsMask f60f26ae89 fix: 参数配置列表编辑切换属性回显错误 2024-07-19 16:22:15 +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 c35a5a9c33 fix: 参数配置教师操作学生应用和退回 2024-07-18 15:04:51 +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 4d755cea5d feat: 参数应用申请操作和查看功能 2024-07-17 17:04:13 +08:00
TsMask c87458bc23 feat: 参数配置教师应用和切换学生功能 2024-07-17 17:03:32 +08:00
TsMask a2d93ddafe fix: 系统名称横向滚动衔接动画 2024-07-16 11:21:16 +08:00
TsMask cfd04ba1b6 Merge remote-tracking branch 'origin/main' into practical-training 2024-07-16 10:01:32 +08:00
TsMask 4af02693a4 feat: 教师选择学生进行切换查看学生配置数据信息 2024-07-15 17:59:30 +08:00
TsMask 66eb27813f feat: 新增网元应用申请提交列表操作 2024-07-15 17:56:28 +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 65c8c6f809 perf: 参数配置页面函数重构 2024-07-11 14:49:26 +08:00
TsMask ecaa0ce077 fix: 参数配置接入实训调整网元类型选择,权限按钮 2024-07-11 10:24:27 +08:00
TsMask 99140f0641 feat: 接入实训接口调试参数配置 2024-07-11 10:23:18 +08:00
TsMask 3bdae264e1 fix: 网元信息单行更新局部信息变更失效 2024-07-10 15:47:28 +08:00
TsMask f3c46976ae Merge remote-tracking branch 'origin/main' into practical-training 2024-07-09 19:09:04 +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 efa8764bd1 feat: 配置参数直连数据获取优化 2024-07-09 10:05:43 +08:00
TsMask f0561242ca fix: fetch请求拼接地址栏参数不区分请求方法 2024-07-09 10:04:46 +08:00
TsMask bc0e463191 fix: 用户岗位和角色指定只能选一个 2024-07-08 11:25:10 +08:00
TsMask 45bf9fe115 Merge remote-tracking branch 'origin/main' into practical-training 2024-07-08 10:57:22 +08:00
TsMask 4c85c61f05 fix: 右上角告警和帮助图标仅教师和管理员看见 2024-07-06 14:22:04 +08:00
TsMask 318f84504f fix: 看板数字活动连接禁止学生角色跳转页面 2024-07-06 14:20:06 +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 53fa36eace Merge remote-tracking branch 'origin/main' into practical-training 2024-07-03 15:33:26 +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 9123484bf5 Merge remote-tracking branch 'origin/main' into practical-training 2024-06-28 12:04:57 +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 e7e4557e96 style: 个人信息隐藏手机号和邮箱的输入 2024-06-27 16:07:55 +08:00
TsMask 6b1fe4a582 Merge remote-tracking branch 'origin/main' into practical-training 2024-06-27 15:36:40 +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 2610ab17ad Merge remote-tracking branch 'origin/main' into practical-training 2024-06-26 17:25:33 +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 b84a08d825 fix: 教师不能管理分配部门,屏蔽电话邮箱 2024-06-24 17:13:09 +08:00
TsMask 06b6175a76 fix: 用户管理刷新不应重置页数1 2024-06-24 17:11:49 +08:00
TsMask 824c38593b Merge remote-tracking branch 'origin/main' into practical-training 2024-06-24 11:18:30 +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 69fb3df7ec Merge remote-tracking branch 'origin/main' into practical-training 2024-06-20 14:56:37 +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 42827796c7 fix: 用户管理内教师角色只能新增学生 2024-06-20 10:28:01 +08:00
TsMask eb38211e3b style: 部门改为班级 2024-06-20 10:27:28 +08:00
TsMask fd1d2a5bad Merge remote-tracking branch 'origin/main' into practical-training 2024-06-20 10:19:01 +08:00
TsMask 57f575aa84 fix: 用户账号规则修改允许数字开头至少6位 2024-06-20 10:16:04 +08:00
TsMask 2d5bfb9842 Merge remote-tracking branch 'origin/main' into practical-training 2024-06-20 09:34:54 +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 c0a7f28958 Merge remote-tracking branch 'origin/main' into practical-training 2024-06-19 14:26:24 +08:00
TsMask 374a9bde7e fix: 用户管理不能改自己状态,权限控制分配岗位 2024-06-19 14:02:24 +08:00
TsMask 5f4e47e998 Merge remote-tracking branch 'origin/main' into practical-training 2024-06-19 12:04:40 +08:00
TsMask 19a91936de style: 默认菜单主题色dark 2024-06-19 12:03:59 +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
lai e6faa59f32 取消注释以及完善多选框处理逻辑 2024-04-02 19:15:06 +08:00
lai 65fab4de1b AMF404时处理表格数据 2024-04-02 18:28:09 +08:00
simonzhangsz b044f01b1d update change log 2024-04-02 16:46:52 +08:00
TsMask f4ed68fc44 del: 格式时间-到指定时区 2024-04-01 18:15:50 +08:00
TsMask 4de98923b7 fix: 格式时间-到指定时区 2024-04-01 18:07:10 +08:00
TsMask 1e0e3a89cf fix: 看板参数可能为null编译检查不过 2024-04-01 16:41:13 +08:00
TsMask edabd9a104 chore: 更新依赖 2024-04-01 16:33:58 +08:00
TsMask c11893566a fix: 黄金指标类型变化列显示异常 2024-04-01 16:31:27 +08:00
TsMask c88bef959a style: 系统用户管理密码输入框提示信息 2024-04-01 16:01:32 +08:00
TsMask ffd1b02bf9 fix: 终端-PCC信息,展示信息列宽可以调整 2024-04-01 16:00:19 +08:00
TsMask 075ad76d19 fix: 属性变更codemirror编辑器 2024-04-01 15:59:09 +08:00
TsMask fbbd0496de ref: 重构codemirror编辑器组件 2024-04-01 15:58:29 +08:00
TsMask 00e8b7acbb feat: 网元安装步骤页面 2024-04-01 15:58:06 +08:00
TsMask 3d40e0856e chore: 更新版本日志 2024-03-30 20:30:27 +08:00
TsMask 32d7897818 fix: 终端-基站信息,展示信息列宽可以调整 2024-03-30 20:14:30 +08:00
TsMask fa14f50e2d feat: 新增网元操作相关接口 2024-03-30 20:13:53 +08:00
TsMask 4eff5d48cd feat: 新增网元操作相关接口 2024-03-29 16:54:24 +08:00
TsMask 5380c4fb3f feat: 网元安装页面 2024-03-27 19:13:54 +08:00
TsMask e10a82ff35 fix: 终端远程连接组件添加消息监听和发送句柄 2024-03-27 19:13:22 +08:00
TsMask f85535672e fix: 软件安装包检查超时180s 2024-03-27 19:12:24 +08:00
lai 3c1c0620d1 修改必填提示语 2024-03-27 19:08:08 +08:00
lai 9531230fc0 Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-03-27 10:08:13 +08:00
lai 151175fb3f 取消sd必填 2024-03-27 10:08:08 +08:00
TsMask 9faf02a1a6 feat: 新增网元操作相关接口 2024-03-26 21:01:39 +08:00
TsMask c2e95f607b style: 终端-基站信息Radio Name列宽调整 2024-03-25 10:50:33 +08:00
TsMask 3a50300bf9 fix: UDM签约列名读取出错 SNSSAIs=>nssai 2024-03-22 11:02:09 +08:00
TsMask 188a108d87 style: 网元信息页面字段列宽度 2024-03-21 15:08:00 +08:00
TsMask 11e788cb8f fix: 看板流量图实例为空判断 2024-03-21 14:51:13 +08:00
TsMask 74195bc88b fix: 拓扑状态刷新定时器改调度器 2024-03-21 10:52:54 +08:00
TsMask 2a622aa1d6 fix: 拓扑状态刷新定时器改调度器 2024-03-21 10:10:46 +08:00
TsMask d15b75e8fd fix: 看板ws黄金指标UPF 2024-03-21 10:10:02 +08:00
TsMask 4ae5f64da3 fix: 数据超过100弹出 2024-03-21 10:05:36 +08:00
TsMask 16ab366136 chore: 更新日志说明2.2403.1-20240319 2024-03-19 09:59:08 +08:00
TsMask 85abd7bca4 fix: 网元列表排序新增MOCNGW 2024-03-18 19:35:20 +08:00
lai cd66ff927d 调整回数据库时间 2024-03-18 15:44:43 +08:00
TsMask d242a87191 fix: 系统日志登录和接口操作记录查询时间带时分秒 2024-03-18 10:11:49 +08:00
TsMask e1eaba0d68 feat: 网元安装软件版本接口 2024-03-18 10:11:12 +08:00
TsMask 5a7c161ed2 fix: 表格字段列排序对语言失效问题 2024-03-11 16:28:30 +08:00
TsMask a0a4e65d5e fix: 文件上传切片跳过不合并数据块问题 2024-03-11 16:27:41 +08:00
TsMask a6751424a5 fix: 网元快速安装页面变量缺失导致编译出错 2024-03-09 18:15:47 +08:00
TsMask 8abaff86e5 fix 开发服务端口改为33020 2024-03-09 18:10:59 +08:00
TsMask e7442bf750 feat: 网元快速安装页面模块化 2024-03-09 18:10:09 +08:00
TsMask dce068fcb1 feat: 网元主机表单校验和提示翻译 2024-03-09 18:08:40 +08:00
simonzhangsz 249d89af88 fix: port 3030 change to 33030 2024-03-08 15:31:45 +08:00
TsMask 0f3a689b04 chore: 更新版本号2.240307.1 2024-03-07 17:10:34 +08:00
TsMask 569eea08cb style: 网元信息页面样式 2024-03-07 17:09:06 +08:00
TsMask 3cb80bbd85 fix: 表格字段排序支持缓存变更状态 2024-03-07 17:04:09 +08:00
TsMask e0d590724b feat: 表格字段排序状态缓存记录 2024-03-07 17:03:19 +08:00
TsMask 2cfab00e8f feat: 数据级缓存工具 2024-03-07 17:02:39 +08:00
TsMask 06170ba38f fix: 拖动框地脚null类型异常,不支持footer插槽 2024-03-07 17:00:20 +08:00
TsMask 7e28df210d fix: UE-PCF页面提示信息调整 2024-03-07 16:58:41 +08:00
TsMask a69e8c89f8 fix: 缓存信息页面图表Echart语言数据设置 2024-03-07 10:17:46 +08:00
TsMask f5544c66bd feat: 网元主机操作Hooks包 2024-03-06 19:57:32 +08:00
TsMask 7339f45193 style: 缓存信息页面标题翻译 2024-03-06 16:04:44 +08:00
TsMask 739025935a fix: 选择列表不进行可操作使用网元状态过滤 2024-03-06 14:46:40 +08:00
TsMask eaa0e2d70c fix: 移除获取网元列表,取消status状态过滤 2024-03-06 14:46:05 +08:00
TsMask 2bffdaef3a style: 网元主机输入框placeholder 2024-03-06 14:43:00 +08:00
TsMask 79809b56e9 feat: 网元信息页面多语言翻译 2024-03-06 09:57:36 +08:00
TsMask e5896c8513 fix: 网元信息编辑带主机配置页面 2024-03-05 16:18:45 +08:00
TsMask 104041eea5 fix: 网元主机操作翻译提示 2024-03-05 16:17:38 +08:00
TsMask 0b576ed446 feat: 新增CDR和UE页面,以及翻译 2024-03-05 16:16:50 +08:00
TsMask c1174fc273 fix 网元管理表单主键id未定义重置失效 2024-03-04 20:44:44 +08:00
TsMask 90e1cd022b fix: 切片文件上传文件名去除非法字符和空格 2024-03-04 19:14:18 +08:00
TsMask 001e5e887b chore: 版本号2.2402.7 2024-03-04 17:59:27 +08:00
TsMask 8230dbf257 fix: 可操作使用网元状态过滤 2024-03-04 17:58:19 +08:00
TsMask 49fa7bdec8 fix: MML管理文件类型判断 2024-03-04 17:58:00 +08:00
TsMask bd13b70a88 feat: 网元信息页面代码抽离组件,补充新增修改接口 2024-03-01 18:57:24 +08:00
TsMask 9b5b43c2bf feat: 常量值-网元列表,默认顺序 2024-03-01 18:55:48 +08:00
TsMask dee4733ad0 fix: 删除无效变量loadDataLoading 2024-03-01 18:53:56 +08:00
TsMask c07c1dfde3 fix: 缓存网元列表改换接口查询网元列表全部无分页 2024-03-01 18:53:10 +08:00
TsMask 181da5836b feat: 网元信息页面改表格勾选删除展开看信息 2024-03-01 18:02:42 +08:00
TsMask 7a787db45d feat: 新增网元信息页面 2024-02-29 20:56:41 +08:00
TsMask 49c98697e1 style: 终端页面样式调整标注释 2024-02-29 20:56:16 +08:00
TsMask 7dedbb927c fix: 修改j网元信息接口 2024-02-29 20:55:29 +08:00
lai c2cc81fccf 修复性能门限提交失败异常 2024-02-29 10:22:42 +08:00
lai 92b2a4fb37 自定义指标界面 2024-02-29 10:21:26 +08:00
lai b7d02ff669 去除对smdata的校验 2024-02-29 10:19:11 +08:00
lai b4179b4c60 修复提交异常 2024-02-29 10:18:52 +08:00
TsMask d7e08a1fff feat: ws工具新增连接状态函数 2024-02-28 17:37:09 +08:00
TsMask d52fdc115c chore: 更新依赖版本 2024-02-28 17:36:16 +08:00
TsMask e86ae12801 feat: 新增终端主机页面 2024-02-28 17:35:44 +08:00
TsMask 87b2fd965c feat: MML网元操作支持区分接口类型 2024-02-28 16:47:59 +08:00
TsMask 8397847e66 style: 备注修改 2024-02-28 10:27:38 +08:00
TsMask 84b0575ab4 feat: MML网元操作支持区分接口类型 2024-02-28 10:27:02 +08:00
TsMask f19e5e48f3 fix: 帮助文档文件名称指定5G核心网网管操作手册.pdf 2024-02-27 10:24:38 +08:00
TsMask 073f17b61f fix: 网元主机页面查询框显示空白 2024-02-26 17:03:38 +08:00
TsMask 4cdfe6097d feat: 新增网元主机命令页面 2024-02-26 17:03:03 +08:00
TsMask d55a4e3da7 fix: ws函数发送消息判断是否连接正常 2024-02-26 12:09:49 +08:00
TsMask dd6c38c57e feat: 新增网元主机页面 2024-02-26 12:09:09 +08:00
TsMask f705ba3a2e feat: 字典标签支持取默认数据项 2024-02-23 19:35:32 +08:00
lai 8721aa3a49 补充 2024-02-22 19:39:18 +08:00
lai d2507e4706 UPF图细节调整 2024-02-22 19:35:16 +08:00
simonzhangsz 0937efc6e6 fix: 2.2402.6 changelog 2024-02-22 18:14:19 +08:00
simonzhangsz 57445cd48f Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-02-22 18:12:15 +08:00
simonzhangsz a193655353 fix: changelog 2024-02-22 18:02:53 +08:00
TsMask 10b150f13c chore: 更新版本号2.2402.6 2024-02-22 17:52:15 +08:00
lai c9fdd1785a 添加点击事件以及换图标 2024-02-22 15:45:23 +08:00
lai a821d49eed 修改中英文 2024-02-22 15:10:01 +08:00
TsMask 28122bbfae fix: 看板用户行为CDR短信号码显示区间样式 2024-02-21 17:20:33 +08:00
TsMask 3b4b085499 fix: 看病栏目添加跳转事件 2024-02-21 17:15:39 +08:00
lai 51b3388cdc 基站中英文 2024-02-21 16:55:07 +08:00
lai 908d9341db 添加MME接口 2024-02-21 16:47:18 +08:00
TsMask 82a2ab158f style: 看板栏目多语言翻译调整 2024-02-21 15:01:46 +08:00
lai ce893f32e0 签约用户拆分SM Data 2024-02-21 14:39:38 +08:00
lai 65696dee09 首页表格新增一列 2024-02-21 14:38:57 +08:00
TsMask 625b39d901 fix: Loading初始语言en_US 2024-02-19 14:49:11 +08:00
lai 4c20e639d8 Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 2024-02-19 14:45:43 +08:00
TsMask f28dfeb9b4 fix: 文档查看下载文件名称?显示问题 2024-02-19 10:50:37 +08:00
TsMask a75c89c451 fix: MML命令输入框shift+回车进行换行,回车直接发送 2024-02-19 10:44:47 +08:00
TsMask 883816c540 fix: UDM鉴权ki和opc显示禁用输入 2024-02-19 10:42:29 +08:00
TsMask 24ba825365 fix: UDM用户数据超时时间180s 2024-02-19 10:41:46 +08:00
lai accb02963c 告警日志中英文错误 2024-02-18 17:00:40 +08:00
TsMask abe5595fa7 feat: 黄金指标实时数据非对应网元类型 2024-02-07 10:26:06 +08:00
299 changed files with 232716 additions and 18867 deletions

No files matched your search

+3 -3
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.2402.5"
VITE_APP_VERSION = "2.241115"
# 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api"
+3 -3
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.240205.5"
VITE_APP_VERSION = "2.241115"
# 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api"
+54 -7
View File
@@ -1,5 +1,52 @@
# 版本发布日志
## 2.2404.1-20240402
- 新增 网元安装流程相关页面与操作相关接口联调
- 新增 终端远程连接组件添加消息监听和发送句柄
- 优化 移除vue-codemirror库改为codemirror,编辑输入支持 yaml语法
- 优化 终端-基站信息Radio Name列宽调整
- 更新 依赖版本
## 2.2403.1-20240319
- 新增 ws 工具连接状态函数
- 新增 终端主机配置页面
- 新增 终端主机命令页面
- 新增 网元信息关联主机页面,表格支持勾选删除记录并展开看网元资源 sn
- 新增 数据级缓存工具,支持表格字段排序状态缓存记录,表格字段排序支持缓存变更状态
- 新增 网元主机操作翻译提示,网元主机操作 Hooks 包
- 新增 IMS-CDR 和 AMF-UE 页面,以及翻译
- 新增 网元快速安装页面,网元安装步骤页面模块
- 新增 MML 网元操作 UPF 支持区分 telnet 发送端
- 新增 网元快速安装步骤选择安装包界面
- 新增 网元版本接口/网元软件包接口
- 新增 自定义指标界面
- 修复 帮助文档中英标题翻译文件名称指定《5G 核心网网管操作手册.pdf》
- 修复 ws 函数发送消息判断是否连接正常
- 修复 网元管理表单主键 id 重置失效导致新增操作为更新操作
- 修复 网元选择列表不进行可操作使用网元状态过滤
- 修复 移除获取网元列表,取消 status 状态过滤
- 修复 缓存信息页面标题翻译,图表 Echart 语言数据设置
- 修复 性能门限提交失败异常
- 修复 提交异常并去除对 smdata 的校验
- 优化 全局缓存网元列表,接口改换查询网元列表全部无分页
- 优化 网元默认可选常量值,删除无效变量声明
- 优化 UE-PCF 页面提示信息、网元信息页面样式、网元主机表单校验和提示翻译
- 优化 拖动框地脚 null 类型异常,不支持 footer 插槽
- 优化 切片文件上传文件名去除非法字符和空格,开发服务端口改为 33020
- 更新 包依赖版本
## 2.2402.6-20240222
- 修复 UDM 用户数据超时时间 180s
- 修复 UDM 鉴权 ki 和 opc 显示禁用输入
- 新增 MML 命令输入框 shift+回车进行换行,回车直接发送
- 修复 文档查看下载文件名称?显示问题
- 修复 看板栏目添加跳转事件
- 修复 看板用户行为字典数据翻译
- 优化 看板用户行为 CDR 短信号码显示区间样式
## 2.2402.5-20240205
- 修复 拓扑架构图调整缺失的节点非网元元素,看板拓扑非网元点击排除
@@ -17,14 +64,14 @@
- 优化 配置参数编辑页面记录类型多语言是否系统内置
- 优化 看板用户行为小屏幕换行显示字内容,格子高度百分比充满
- 优化 看板推送用户行为插入又弹出减少渲染数量
- 修复 看班告警统计判断修复,超时30秒,图渲染逻辑优化
- 修复 参数配置DNN List参数显示null问题
- 优化 ws消息队列延迟处理
- 新增 看板用户事件CDR短信类型,短信结果200显示成功
- 优化 看板告警统计0数字不显示
- 优化 看板用户事件CDR指定类型MOC/MTSM
- 修复 看班告警统计判断修复,超时 30 秒,图渲染逻辑优化
- 修复 参数配置 DNN List 参数显示 null 问题
- 优化 ws 消息队列延迟处理
- 新增 看板用户事件 CDR 短信类型,短信结果 200 显示成功
- 优化 看板告警统计 0 数字不显示
- 优化 看板用户事件 CDR 指定类型 MOC/MTSM
- 新增 黄金指标项图表显示全部开关控制
- 新增 黄金指标项随机颜色,图表实时5s动态显示
- 新增 黄金指标项随机颜色,图表实时 5s 动态显示
## 2.2401.4-20240130
+1 -33
View File
@@ -2,23 +2,9 @@
## 简介
- 系统布局使用 [@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
```
## 程序命令
项目目录下 `.env.[环境]` 文件对应环境的一些配置,启动前请检查文件内是否配置正确。
@@ -60,23 +46,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
```
+32 -24
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,40 +14,48 @@
"dependencies": {
"@ant-design/icons-vue": "^7.0.1",
"@antv/g6": "~4.8.24",
"@codemirror/lang-javascript": "^6.2.1",
"@codemirror/merge": "^6.5.0",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-yaml": "^6.1.1",
"@codemirror/merge": "^6.7.2",
"@codemirror/theme-one-dark": "^6.1.2",
"@tato30/vue-pdf": "^1.9.3",
"@vueuse/core": "^10.7.0",
"ant-design-vue": "^3.2.20",
"antdv-pro-layout": "^3.2.6",
"@tato30/vue-pdf": "^1.11.2",
"@vueuse/core": "11.2.0",
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"ant-design-vue": "^4.2.5",
"antdv-pro-layout": "^4.1.9",
"antdv-pro-modal": "^4.0.5",
"codemirror": "^6.0.1",
"dayjs": "^1.11.10",
"echarts": "~5.4.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.11",
"echarts": "~5.5.0",
"file-saver": "^2.0.5",
"js-base64": "^3.7.5",
"grid-layout-plus": "^1.0.5",
"intl-tel-input": "^24.6.0",
"js-base64": "^3.7.7",
"js-cookie": "^3.0.5",
"localforage": "^1.10.0",
"nprogress": "^0.2.0",
"p-queue": "^8.0.1",
"pinia": "^2.1.7",
"vue": "~3.3.13",
"vue-codemirror": "^6.1.1",
"vue-i18n": "~9.9.0",
"vue-router": "^4.2.5",
"p-queue": "~8.0.1",
"pinia": "2.2.6",
"vue": "^3.5.12",
"vue-i18n": "^10.0.4",
"vue-router": "^4.4.5",
"vue3-smooth-dnd": "^0.0.6",
"xlsx": "^0.18.5"
"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/node": "^22.7.7",
"@types/nprogress": "^0.2.3",
"@vitejs/plugin-vue": "^5.0.2",
"@vitejs/plugin-vue": "^5.1.4",
"less": "^4.2.0",
"typescript": "^5.3.3",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.0.10",
"vite-plugin-compression": "^0.5.1",
"vue-tsc": "^1.8.27"
"typescript": "^5.6.3",
"unplugin-vue-components": "^0.27.4",
"vite": "5.4.10",
"vite-plugin-compression": "~0.5.1",
"vue-tsc": "^2.1.8"
}
}
+3 -2
View File
@@ -11,8 +11,9 @@
*/
(function () {
// host = ip:port
const host = '192.168.8.100:3030';
// const host = '192.168.8.100:33030';
const host = `${window.location.hostname}:33030`;
// Service Address
sessionStorage.setItem('baseUrl', `http://${host}`);
// websocket Address
+1 -1
View File
@@ -155,7 +155,7 @@
}
</style>`;
const lang = localStorage.getItem('cache:local:i18n');
const lang = localStorage.getItem('cache:local:i18n') || 'en_US';
// 根据浏览器选择语言
// if (!lang) {
// let preferredLanguage = navigator.language;
File renamed without changes.
Binary file not shown.
File diff suppressed because it is too large. Load diff
Binary file not shown.
File diff suppressed because it is too large. Load diff
+166
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
View File
@@ -0,0 +1,162 @@
// load the Wiregasm library
importScripts(
'wiregasm_new.js', // self-compilation es5
'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.wasm'
// 'https://cdn.jsdelivr.net/npm/@goodtools/wiregasm/dist/wiregasm.wasm'
),
await inflateRemoteBuffer(
'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' });
}
};
+54 -70
View File
@@ -1,20 +1,48 @@
<script setup lang="ts">
import { ConfigProvider } from 'ant-design-vue/lib';
import { usePrimaryColor } from '@/hooks/useTheme';
import zhCN from 'ant-design-vue/lib/locale/zh_CN';
import enUS from 'ant-design-vue/lib/locale/en_US';
import { onBeforeMount, ref, watch } from 'vue';
import { message } from 'ant-design-vue/es';
import zhCN from 'ant-design-vue/es/locale/zh_CN';
import enUS from 'ant-design-vue/es/locale/en_US';
import { usePrefersColorScheme, viewTransitionTheme } from 'antdv-pro-layout';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import { ref, watch } from 'vue';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import useLayoutStore from '@/store/modules/layout';
import useAppStore from '@/store/modules/app';
import useI18n from '@/hooks/useI18n';
const { t, currentLocale } = useI18n();
const appStore = useAppStore();
const { themeConfig, initPrimaryColor, changeConf } = useLayoutStore();
dayjs.extend(advancedFormat);
// dayjs.locale('zh-cn'); // 默认中文
let locale = ref(enUS); // 国际化初始中文
dayjs.locale('zh-cn'); // 默认中文
usePrimaryColor(); // 载入用户自定义主题色
// 偏好设置
const colorScheme = usePrefersColorScheme();
watch(
() => colorScheme.value,
themeMode => {
viewTransitionTheme(() => {
changeConf('theme', themeMode);
});
}
);
let locale = ref(zhCN); // 国际化初始中文
onBeforeMount(() => {
// 全局message提示
message.config({
top: '100px', // 距离顶部位置100px
duration: 3,
maxCount: 15,
});
initPrimaryColor();
// 输出应用版本号
const appStore = useAppStore();
console.info(
`%c ${t('common.desc')} %c ${appStore.appCode} - ${appStore.appVersion} `,
'color: #fadfa3; background: #030307; padding: 4px 0;',
'color: #030307; background: #fadfa3; padding: 4px 0;'
);
});
// 国际化切换语言
function fnChangeLocale(v: string) {
@@ -35,22 +63,15 @@ fnChangeLocale(currentLocale.value);
watch(currentLocale, val => {
fnChangeLocale(val);
});
// 输出应用版本号
console.info(
`%c ${t('common.title')} %c ${appStore.appCode} - ${appStore.appVersion} `,
'color: #fadfa3; background: #030307; padding: 4px 0;',
'color: #030307; background: #fadfa3; padding: 4px 0;'
);
</script>
<template>
<ConfigProvider :locale="locale">
<a-config-provider :theme="themeConfig" :locale="locale">
<RouterView />
</ConfigProvider>
</a-config-provider>
</template>
<style>
<style lang="css">
#app {
height: 100%;
}
@@ -61,10 +82,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,
@@ -87,56 +104,23 @@ body .ant-pro-basicLayout {
transform: translate(-2em, 0);
}
/**强制改表格边距 */
.ant-table.ant-table-small .ant-table-tbody > tr > td,
.ant-table.ant-table-small .ant-table-thead > tr > th {
padding: 6px !important;
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
/** ==== 表格头按钮区域 S === **/
/* 默认 */
.button-container {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
[data-theme='dark']::view-transition-old(root) {
z-index: 1;
}
[data-theme='dark']::view-transition-new(root) {
z-index: 999;
}
.button-container > button,
.button-container > span {
margin-right: 12px;
margin-bottom: 12px;
::view-transition-old(root) {
z-index: 999;
}
.button-container > button:last-child,
.button-container > span:last-child {
margin-right: 0;
::view-transition-new(root) {
z-index: 1;
}
/* 平板端 */
@media (max-width: 992px) {
.button-container {
flex-direction: row;
align-items: flex-start;
align-items: left;
}
.button-container > button,
.button-container > span {
margin-right: 12px;
margin-bottom: 12px;
}
}
/* 手机端 */
@media (max-width: 576px) {
.button-container {
flex-direction: column;
align-items: flex-start;
align-items: left;
}
.button-container > button,
.button-container > span {
margin-right: 0px;
margin-bottom: 12px;
}
}
/** ==== 表格头按钮区域 E === **/
</style>
-55
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;
}
+50 -429
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;
});
}
-72
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,
});
}
+20 -79
View File
@@ -1,6 +1,11 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch';
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';
import { NE_TYPE_LIST } from '@/constants/ne-constants';
/**
* 查询网元列表
@@ -8,27 +13,8 @@ import { parseObjLineToHump } from '@/utils/parse-utils';
* @returns object
*/
export async function listNeInfo(query: Record<string, any>) {
let totalSQL =
'select count(*) as total from ne_info where (status=0 or status=3)';
let rowsSQL = 'select * from ne_info where (status=0 or status=3) ';
// 系统特定顺序
const specificOrder = [
'OMC',
'MME',
'AMF',
'AUSF',
'UDM',
'SMF',
'PCF',
'UPF',
'NRF',
'NSSF',
'IMS',
'N3IWF',
'NEF',
'LMF',
];
let totalSQL = 'select count(*) as total from ne_info where 1=1 ';
let rowsSQL = 'select * from ne_info where 1=1 ';
// 查询
let querySQL = '';
@@ -67,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;
@@ -92,15 +78,18 @@ export async function getNeInfo(id: string | number) {
url: `/api/rest/databaseManagement/v1/select/omc_db/ne_info`,
method: 'get',
params: {
SQL: `select * from ne_info where (status=0 or status=3) and id = ${id}`,
SQL: `select * from ne_info 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['ne_info'][0]),
});
let neInfo = result.data.data[0]['ne_info'];
if (neInfo) {
return Object.assign(result, {
data: parseObjLineToHump(neInfo[0]),
});
}
return { code: RESULT_CODE_ERROR, msg: RESULT_MSG_ERROR[language] };
}
return result;
}
@@ -148,57 +137,9 @@ export async function delNeInfo(data: Record<string, any>) {
});
}
/**
* 获取网元网元列表
* @returns object
*/
export async function getNelistAll() {
// 系统特定顺序
const specificOrder = [
'OMC',
'MME',
'AMF',
'AUSF',
'UDM',
'SMF',
'PCF',
'UPF',
'NRF',
'NSSF',
'IMS',
'N3IWF',
'NEF',
'LMF',
];
// 发起请求
const result = await request({
url: `/api/rest/databaseManagement/v1/elementType/omc_db/objectType/ne_info`,
method: 'get',
params: {
SQL: `SELECT ne_type,ne_name,ne_id,ip FROM ne_info WHERE status in ('0','3')`,
},
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
let data = result.data.data[0];
//通过sort进行冒泡排序
data['ne_info'].sort((a: any, b: any) => {
const typeA = specificOrder.indexOf(a.ne_type);
const typeB = specificOrder.indexOf(b.ne_type);
if (typeA === -1) return 1;
if (typeB === -1) return -1;
return typeA - typeB;
});
return Object.assign(result, {
data: parseObjLineToHump(data['ne_info']),
});
}
return result;
}
/**
* 导出网元配置文件
* @param
* @param data data {neType neId}
* @returns bolb
*/
export function exportSet(data: Record<string, any>) {
+3
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) {
+5 -4
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({
+124
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;
}
+6 -22
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,21 +43,20 @@ export async function listMain() {
ipAddress,
serialNum,
name: key.split('/').join('_'),
expiryDate: '-',
status: 'Abnormal',
};
}
return mergedObj;
});
//通过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;
});
//console.log(mergedData);
return mergedData;
}
@@ -105,5 +88,6 @@ export function getSysConf() {
return request({
url: `/sys-conf`,
method: 'get',
whithToken: false,
});
}
+53
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,
});
}
+2
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,
});
}
+3 -1
View File
@@ -30,17 +30,19 @@ export async function getMMLByNE(neType: string) {
* 发送网元的mml命令
* @param neType 网元类型
* @param neId 网元ID
* @param objectType 接口类型
* @param cmdStr 命令串
* @returns
*/
export async function sendMMlByNE(
neType: string,
neId: string,
objectType: string,
cmdArr: string[]
) {
// 发起请求
const result = await request({
url: `/api/rest/operationManagement/v1/elementType/${neType}/objectType/mml?ne_id=${neId}`,
url: `/api/rest/operationManagement/v1/elementType/${neType}/objectType/${objectType}?ne_id=${neId}`,
method: 'post',
data: { mml: cmdArr },
timeout: 180_000,
+1
View File
@@ -6,5 +6,6 @@ export function getLoad(query: Record<string, any>) {
url: '/monitor/load',
method: 'get',
params: query,
timeout: 60_000,
});
}
-93
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;
}
+1
View File
@@ -5,5 +5,6 @@ export function getSystemInfo() {
return request({
url: '/monitor/system-info',
method: 'get',
timeout: 60_000,
});
}
-29
View File
@@ -1,29 +0,0 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询网元列表
* @param query 查询参数
* @returns object
*/
export function listNe(query: Record<string, any>) {
return request({
url: '/ne/list',
method: 'get',
params: query,
timeout: 60_000,
});
}
/**
* 查询网元状态
* @param neType 网元类型
* @param neId 网元ID
* @returns object
*/
export function stateNe(neType: string, neId: string) {
return request({
url: '/ne/state',
method: 'get',
params: { neType, neId },
});
}
+66
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,
});
}
+83
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,
});
}
+103
View File
@@ -0,0 +1,103 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询网元主机列表
* @param query 查询参数
* @returns object
*/
export function listNeHost(query: Record<string, any>) {
return request({
url: '/ne/host/list',
method: 'get',
params: query,
});
}
/**
* 查询网元主机详细
* @param hostId 网元主机ID
* @returns object
*/
export function getNeHost(hostId: string | number) {
return request({
url: `/ne/host/${hostId}`,
method: 'get',
});
}
/**
* 新增网元主机
* @param data 网元主机对象
* @returns object
*/
export function addNeHost(data: Record<string, any>) {
return request({
url: '/ne/host',
method: 'post',
data: data,
});
}
/**
* 修改网元主机
* @param data 网元主机对象
* @returns object
*/
export function updateNeHost(data: Record<string, any>) {
return request({
url: '/ne/host',
method: 'put',
data: data,
});
}
/**
* 删除网元主机
* @param hostId 网元主机ID
* @returns object
*/
export function delNeHost(hostId: string | number) {
return request({
url: `/ne/host/${hostId}`,
method: 'delete',
});
}
/**
* 测试连接网元主机
* @param data 网元主机对象
* @returns object
*/
export function testNeHost(data: Record<string, any>) {
return request({
url: '/ne/host/test',
method: 'post',
data: data,
});
}
/**
* 网元主机SSH方式检查服务器环境
* @param data 网元主机对象
* @returns object
*/
export function neHostCheckInfo(data: Record<string, any>) {
return request({
url: '/ne/host/checkBySSH',
method: 'post',
data: data,
});
}
/**
* 网元主机SSH方式授权免密发送
* @param data 网元主机对象
* @returns object
*/
export function neHostAuthorizedRSA(data: Record<string, any>) {
return request({
url: '/ne/host/authorizedBySSH',
method: 'post',
data: data,
});
}
+64
View File
@@ -0,0 +1,64 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询网元主机命令列表
* @param query 查询参数
* @returns object
*/
export function listNeHostCmd(query: Record<string, any>) {
return request({
url: '/ne/hostCmd/list',
method: 'get',
params: query,
});
}
/**
* 查询网元主机命令详细
* @param cmdId 网元主机命令ID
* @returns object
*/
export function getNeHostCmd(cmdId: string | number) {
return request({
url: `/ne/hostCmd/${cmdId}`,
method: 'get',
});
}
/**
* 新增网元主机命令
* @param data 网元主机命令对象
* @returns object
*/
export function addNeHostCmd(data: Record<string, any>) {
return request({
url: '/ne/hostCmd',
method: 'post',
data: data,
});
}
/**
* 修改网元主机命令
* @param data 网元主机命令对象
* @returns object
*/
export function updateNeHostCmd(data: Record<string, any>) {
return request({
url: '/ne/hostCmd',
method: 'put',
data: data,
});
}
/**
* 删除网元主机命令
* @param cmdId 网元主机命令ID
* @returns object
*/
export function delNeHostCmd(cmdId: string | number) {
return request({
url: `/ne/hostCmd/${cmdId}`,
method: 'delete',
});
}
+183
View File
@@ -0,0 +1,183 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询网元列表
* @param query 查询参数
* @returns object
*/
export function listNeInfo(query: Record<string, any>) {
return request({
url: '/ne/info/list',
method: 'get',
params: query,
timeout: 60_000,
});
}
/**
* 查询网元信息详细
* @param infoId 信息ID
* @returns object
*/
export function getNeInfo(infoId: string | number) {
return request({
url: `/ne/info/${infoId}`,
method: 'get',
});
}
/**
* 网元信息新增
* @param data 网元对象
* @returns object
*/
export function addNeInfo(data: Record<string, any>) {
return request({
url: `/ne/info`,
method: 'post',
data: data,
crypto: true,
timeout: 30_000,
});
}
/**
* 网元信息修改
* @param data 网元对象
* @returns object
*/
export function updateNeInfo(data: Record<string, any>) {
return request({
url: `/ne/info`,
method: 'put',
data: data,
crypto: true,
timeout: 30_000,
});
}
/**
* 网元信息删除
* @param id 信息ID
* @returns object
*/
export function delNeInfo(infoIds: string | number) {
return request({
url: `/ne/info/${infoIds}`,
method: 'delete',
timeout: 60_000,
});
}
/**
* 查询网元列表全部无分页
* @param query 查询参数 neType neId bandStatus bandHost
* @returns object
*/
export function listAllNeInfo(query: Record<string, any>) {
return request({
url: '/ne/info/listAll',
method: 'get',
params: query,
timeout: 60_000,
});
}
/**
* 查询网元状态
* @param neType 网元类型
* @param neId 网元ID
* @returns object
*/
export function stateNeInfo(neType: string, neId: string) {
return request({
url: '/ne/info/state',
method: 'get',
params: { neType, neId },
});
}
/**
* 查询网元信息
* @param neType 网元类型
* @param neId 网元ID
* @returns object
*/
export function getNeInfoByTypeAndID(neType: string, neId: string) {
return request({
url: '/ne/info/byTypeAndID',
method: 'get',
params: { neType, neId },
});
}
/**
* 网元端OAM配置文件读取
* @param neType 网元类型
* @param neId 网元ID
* @returns object
*/
export function getOAMFile(neType: string, neId: string) {
return request({
url: '/ne/info/oamFile',
method: 'get',
params: { neType, neId },
});
}
/**
* 网元端配置文件写入
* @param neType 网元类型
* @param neId 网元ID
* @param content 用json对象
* @param sync 同步到网元
* @returns object
*/
export function saveOAMFile(data: Record<string, any>) {
return request({
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,
});
}
+83
View File
@@ -0,0 +1,83 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询网元授权列表
* @param query 查询参数
* @returns object
*/
export function listNeLicense(query: Record<string, any>) {
return request({
url: '/ne/license/list',
method: 'get',
params: query,
timeout: 60_000,
});
}
/**
* 查询网元授权详细
* @param licenseId 信息ID
* @returns object
*/
export function getNeLicense(licenseId: string | number) {
return request({
url: `/ne/license/${licenseId}`,
method: 'get',
});
}
/**
* 网元neType和neID查询
* @param neType 网元类型
* @param neId 网元ID
* @returns object
*/
export function getNeLicenseByTypeAndID(neType: string, neId: string) {
return request({
url: `/ne/license/byTypeAndID`,
method: 'get',
params: { neType, neId },
});
}
/**
* 网元授权激活授权申请码
* @param neType 网元类型
* @param neId 网元id
* @returns object
*/
export function codeNeLicense(neType: string, neId: string) {
return request({
url: `/ne/license/code`,
method: 'get',
params: { neType, neId },
});
}
/**
* 网元授权激活授权文件替换
* @param data 网元对象 {"neType": "", "neId": "", "licensePath": "", "reload": true}
* @returns object
*/
export function changeNeLicense(data: Record<string, any>) {
return request({
url: `/ne/license/change`,
method: 'post',
data: data,
timeout: 180_000,
});
}
/**
* 网元授权激活状态
* @param neType 网元类型
* @param neId 网元id
* @returns object
*/
export function stateNeLicense(neType: string, neId: string) {
return request({
url: `/ne/license/state`,
method: 'get',
params: { neType, neId },
});
}
+80
View File
@@ -0,0 +1,80 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询网元版本列表
* @param query 查询参数
* @returns object
*/
export function listNeSoftware(query: Record<string, any>) {
return request({
url: '/ne/software/list',
method: 'get',
params: query,
timeout: 60_000,
});
}
/**
* 查询网元软件包详细
* @param softwareId 信息ID
* @returns object
*/
export function getNeSoftware(softwareId: string | number) {
return request({
url: `/ne/software/${softwareId}`,
method: 'get',
});
}
/**
* 网元软件包新增
* @param data 网元对象
* @returns object
*/
export function addNeSoftware(data: Record<string, any>) {
return request({
url: `/ne/software`,
method: 'post',
data: data,
repeatSubmit: false,
});
}
/**
* 网元软件包修改
* @param data 网元对象
* @returns object
*/
export function updateNeSoftware(data: Record<string, any>) {
return request({
url: `/ne/software`,
method: 'put',
data: data,
});
}
/**
* 网元软件包删除
* @param id 信息ID
* @returns object
*/
export function delNeSoftware(softwareIds: string | number) {
return request({
url: `/ne/software/${softwareIds}`,
method: 'delete',
timeout: 60_000,
});
}
/**
* 网元软件包设为网元新版本
* @param data data { "version": "2.2404.18", "neType": "SMF", "name": "smf-r2.2404.18-ub22.deb"}
* @returns object
*/
export function newNeVersion(data: Record<string, any>) {
return request({
url: `/ne/software/newNeVersion`,
method: 'post',
data: data,
});
}
+41
View File
@@ -0,0 +1,41 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询网元版本列表
* @param query 查询参数
* @returns object
*/
export function listNeVersion(query: Record<string, any>) {
return request({
url: '/ne/version/list',
method: 'get',
params: query,
timeout: 60_000,
});
}
/**
* 查询网元版本详细
* @param versionId 信息ID
* @returns object
*/
export function getNeVersion(versionId: string | number) {
return request({
url: `/ne/version/${versionId}`,
method: 'get',
});
}
/**
* 网元版本操作
* @param data {neType,neId,preinput:{参数},action:"upgrade"}
* @returns object
*/
export function operateNeVersion(data: Record<string, any>) {
return request({
url: `/ne/version/operate`,
method: 'post',
data: data,
timeout: 180_000,
});
}
+42
View File
@@ -0,0 +1,42 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询AMF-UE会话事件列表
* @param query 查询参数
* @returns object
*/
export function listAMFDataUE(query: Record<string, any>) {
return request({
url: '/neData/amf/ue/list',
method: 'get',
params: query,
});
}
/**
* AMF-UE会话删除
* @param id 信息ID
* @returns object
*/
export function delAMFDataUE(ueIds: string | number) {
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,
});
}
+42
View File
@@ -0,0 +1,42 @@
import { request } from '@/plugins/http-fetch';
/**
* 查询IMS-CDR会话事件
* @param query 查询参数
* @returns object
*/
export function listIMSDataCDR(query: Record<string, any>) {
return request({
url: '/neData/ims/cdr/list',
method: 'get',
params: query,
});
}
/**
* IMS-CDR会话删除
* @param id 信息ID
* @returns object
*/
export function delIMSDataCDR(cdrIds: string | number) {
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
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
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
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,
});
}
+142
View File
@@ -0,0 +1,142 @@
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,
timeout: 30_000,
});
}
/**
* 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,
});
}
+141
View File
@@ -0,0 +1,141 @@
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,
timeout: 30_000,
});
}
/**
* 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,
});
}
-133
View File
@@ -1,133 +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',
});
}
/**
* 导入鉴权数据
* @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,
});
}
/**
* 新增鉴权
* @param data 鉴权对象
* @returns object
*/
export function addAuth(data: Record<string, any>) {
return request({
url: `/ne/udm/auth/${data.neId}`,
method: 'post',
data: data,
});
}
/**
* 批量新增鉴权
* @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,
});
}
/**
* 删除鉴权
* @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',
});
}
+3 -1
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":"","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;
}
+5 -3
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 });
}
// 模拟数据
+31 -14
View File
@@ -136,14 +136,21 @@ 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 && result.data?.status) {
return {
code: RESULT_CODE_ERROR,
msg: result.data?.cause,
data: result.data,
};
if (result.code === RESULT_CODE_SUCCESS) {
if (result.data?.status) {
return {
code: RESULT_CODE_ERROR,
msg: result.data?.cause,
data: result.data,
};
}
if (result.data?.data) {
result.data = result.data.data;
return result;
}
}
return result;
}
@@ -158,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) {
@@ -180,14 +188,21 @@ 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 && result.data?.status) {
return {
code: RESULT_CODE_ERROR,
msg: result.data?.cause,
data: result.data,
};
if (result.code === RESULT_CODE_SUCCESS) {
if (result.data?.status) {
return {
code: RESULT_CODE_ERROR,
msg: result.data?.cause,
data: result.data,
};
}
if (result.data?.data) {
result.data = result.data.data;
return result;
}
}
return result;
}
@@ -197,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,
});
}
@@ -213,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,
});
}
+41 -15
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',
-135
View File
@@ -1,135 +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,
});
}
/**
* 新增签约
* @param data 签约对象
* @returns object
*/
export function addSub(neID: string, data: Record<string, any>) {
return request({
url: `/ne/udm/sub/${neID}`,
method: 'post',
data: data,
});
}
/**
* 批量新增新增签约
* @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,
});
}
/**
* 删除签约
* @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',
});
}
+19
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;
}
+127
View File
@@ -0,0 +1,127 @@
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 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 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: `/pm/kpiC/title/totalList`,
method: 'get',
params: query,
});
return result;
}
/**
* 查询自定义指标详细
* @param id 网元ID
* @returns object
*/
export async function getCustom(id: string | number) {
return request({
url: `/pm/kpiC/title/${id}`,
method: 'get',
});
}
/**
* 新增自定义指标
* @param data 网元对象
* @returns object
*/
export function addCustom(data: Record<string, any>) {
return request({
url: `/pm/kpiC/title`,
method: 'post',
data: data,
});
}
/**
* 修改自定义指标
* @param data 网元对象
* @returns object
*/
export function updateCustom(data: Record<string, any>) {
return request({
url: `/pm/kpiC/title/${data.id}`,
method: 'put',
data: data,
});
}
/**
* 删除自定义指标
* @returns object
*/
export async function delCustom(data: Record<string, any>) {
return request({
url: `/pm/kpiC/title/${data.id}`,
method: 'delete',
});
}
+4 -7
View File
@@ -1,9 +1,9 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch';
import { parseDateToStr } from '@/utils/date-utils';
import { parseObjLineToHump } from '@/utils/parse-utils';
/**
* Todo 废弃
* 查询黄金指标数据
* @param query 查询参数
* @returns object
@@ -110,6 +110,7 @@ export async function getKPITitle(neType: string) {
}
/**
* Todo 废弃
* 查询UPF上下行速率数据
* @param query 查询参数
* @returns object
@@ -126,9 +127,7 @@ export async function listUPFData(timeArr: any) {
url: `/api/rest/databaseManagement/v1/select/omc_db/gold_kpi`,
method: 'get',
params: {
SQL: `SELECT gold_kpi.*,kpi_title.en_title FROM gold_kpi LEFT JOIN kpi_title on gold_kpi.kpi_id=kpi_title.kpi_id where 1=1 and gold_kpi.kpi_id ='UPF.03' and timestamp BETWEEN '${parseDateToStr(
twentyFourHoursAgo
)}' AND '${parseDateToStr(initTime)}' `,
SQL: `SELECT gold_kpi.*,kpi_title.en_title FROM gold_kpi LEFT JOIN kpi_title on gold_kpi.kpi_id=kpi_title.kpi_id where 1=1 and gold_kpi.kpi_id ='UPF.03' AND timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 10 MINUTE) AND NOW()`,
},
timeout: 60_000,
}),
@@ -137,9 +136,7 @@ export async function listUPFData(timeArr: any) {
url: `/api/rest/databaseManagement/v1/select/omc_db/gold_kpi`,
method: 'get',
params: {
SQL: `SELECT gold_kpi.*,kpi_title.en_title FROM gold_kpi LEFT JOIN kpi_title on gold_kpi.kpi_id=kpi_title.kpi_id where 1=1 and gold_kpi.kpi_id ='UPF.06' and timestamp BETWEEN '${parseDateToStr(
twentyFourHoursAgo
)}' AND '${parseDateToStr(initTime)}' `,
SQL: `SELECT gold_kpi.*,kpi_title.en_title FROM gold_kpi LEFT JOIN kpi_title on gold_kpi.kpi_id=kpi_title.kpi_id where 1=1 and gold_kpi.kpi_id ='UPF.06' AND timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 10 MINUTE) AND NOW()`,
},
timeout: 60_000,
}),
+5 -5
View File
@@ -103,7 +103,7 @@ export function addPerfThre(data: Record<string, any>) {
return request({
url: `/api/rest/databaseManagement/v1/omc_db/measure_threshold`,
method: 'post',
data: { measure_task: [obj] },
data: { measure_threshold: [obj] },
});
}
@@ -115,15 +115,15 @@ export function addPerfThre(data: Record<string, any>) {
export function updatePerfThre(data: Record<string, any>) {
let obj: any = {
ne_type: data.neType,
kpi_set: data.performanceArr,
kpi_set: data.kpiSet,
status: 'Inactive',
orig_severity: data.origSeverity,
threshold: data.threshold,
threshold: ''+data.threshold,
};
return request({
url: `/api/rest/databaseManagement/v1/omc_db/measure_task?WHERE=id=${data.id}`,
url: `/api/rest/databaseManagement/v1/omc_db/measure_threshold?WHERE=id=${data.id}`,
method: 'put',
data: { data: obj },
data: { measure_threshold: obj },
});
}
+52
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,
},
});
}
+14 -1
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,
});
}
@@ -94,7 +96,12 @@ export async function uploadFileChunk(
chunkSize: number = 1,
subPath: string = 'default'
) {
const { name, size } = fileData;
let { name, size } = fileData;
// 去除非法字符
const cleanedFilename = name.replace(/[\\/:*?"<>|]/g, '');
// 去除空格
name = cleanedFilename.replace(/\s/g, '_');
// 数据块大小
const chunkSizeInBytes = chunkSize * 1024 * 1024;
// 文件标识使用唯一编码 MD5(文件名+文件大小)
const fileIdentifier = `${name}-${size}`;
@@ -125,6 +132,7 @@ export async function uploadFileChunk(
const chunksIndex = `${index}`;
// 跳过已上传块
if (resCheck.data.includes(chunksIndex)) {
uploadedSize += chunk.size;
continue;
}
@@ -163,6 +171,7 @@ export function chunkCheck(identifier: string, fileName: string) {
url: '/file/chunkCheck',
method: 'post',
data: { identifier, fileName },
timeout: 60_000,
});
}
@@ -182,6 +191,7 @@ export function chunkMerge(
url: '/file/chunkMerge',
method: 'post',
data: { identifier, fileName, subPath },
timeout: 60_000,
});
}
@@ -196,6 +206,7 @@ export function chunkUpload(data: FormData) {
method: 'post',
data,
dataType: 'form-data',
timeout: 60_000,
});
}
@@ -208,6 +219,7 @@ export function transferStaticFile(data: Record<string, any>) {
url: `/file/transferStaticFile`,
method: 'post',
data,
timeout: 60_000,
});
}
@@ -235,6 +247,7 @@ export async function uploadFileToNE(
neType,
neId,
},
timeout: 60_000,
});
return transferToNeFileRes;
}
+20
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,
});
}
+23 -2
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
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,
});
}
File renamed without changes.
+64
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 },
});
}
@@ -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
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
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,
});
}
-154
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;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

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

After

Width:  |  Height:  |  Size: 3.4 KiB

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

After

Width:  |  Height:  |  Size: 4.0 KiB

+87 -40
View File
@@ -1,70 +1,117 @@
<template>
<codemirror
:model-value="modelValue"
:placeholder="props.placeholder"
:style="props.editorStyle"
:disabled="props.disabled"
:autofocus="false"
:indent-with-tab="true"
:tab-size="props.tabSize"
:extensions="[javascript(), oneDark]"
@ready="fnReady"
@change="fnChange"
/>
</template>
<script lang="ts" setup>
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { yaml } from '@codemirror/lang-yaml';
import { oneDark } from '@codemirror/theme-one-dark';
import { ref, watch } from 'vue';
const emit = defineEmits(['update:value']);
import { basicSetup, EditorView } from 'codemirror';
import { indentWithTab } from '@codemirror/commands';
import { keymap } from '@codemirror/view';
import { EditorState } from '@codemirror/state';
import { ref, watch, onMounted, onBeforeUnmount } from 'vue';
const emit = defineEmits(['update:value', 'change']);
const props = defineProps({
/**禁用输入使用v-model:value时不生效 */
value: {
type: String,
required: true,
},
placeholder: {
/**编辑框高度 */
height: {
type: String,
default: 'input context here...',
},
/**是否禁止输入 */
disabled: {
type: Boolean,
default: false,
},
editorStyle: {
type: Object,
default: () => ({ height: '400px !important' }),
default: '400px',
},
/**缩进2空格 */
tabSize: {
type: Number,
default: 2,
},
/**是否禁止输入 */
disabled: {
type: Boolean,
default: true,
},
/**高亮语言 支持javascript、yaml */
lang: {
type: String,
default: 'javascript',
},
});
// 绑定值
const modelValue = ref<string>('');
/**视图容器 */
const viewContainerDom = ref<HTMLElement | undefined>(undefined);
let viewContainer: EditorView | null = null;
/**变更时更新绑定值 */
function fnChange(value: string, viewUpdate: any) {
if (props.disabled) return;
emit('update:value', value);
/**高亮语言拓展 */
function fnLangExtension() {
if (props.lang === 'yaml') {
return yaml();
}
return javascript();
}
/**组件渲染后 */
function fnReady(payload: any) {
modelValue.value = props.value;
/**初始化渲染视图 */
function handleRanderView(container: HTMLElement | undefined) {
if (!container) return;
viewContainer = new EditorView({
doc: props.value,
extensions: [
oneDark,
basicSetup,
keymap.of([indentWithTab]),
fnLangExtension(),
EditorView.editable.of(!props.disabled),
EditorState.readOnly.of(props.disabled),
EditorState.tabSize.of(props.tabSize),
EditorView.updateListener.of(v => {
if (v.docChanged) {
const docStr = v.state.doc.toString();
emit('change', docStr, v.state.doc);
// 禁用时不双向绑定,防止监听重复变化数值
if (!props.disabled) {
emit('update:value', docStr);
}
}
}),
],
parent: container,
});
}
/**监听是否value改变 */
watch(
() => props.value,
val => {
modelValue.value = val;
// 禁用时无输入靠外部值变化改变数值
if (props.disabled && viewContainer) {
const docLine = viewContainer.state.doc.length;
viewContainer.dispatch({
changes: { from: 0, to: docLine, insert: val },
});
}
}
);
onMounted(() => {
handleRanderView(viewContainerDom.value);
});
onBeforeUnmount(() => {
viewContainer?.destroy();
});
</script>
<style lang="less" scoped></style>
<template>
<div
ref="viewContainerDom"
class="container"
:style="{ '--editor-height': height }"
></div>
</template>
<style lang="less" scoped>
.container {
--editor-height: 400px;
}
.container :deep(.cm-editor) {
height: var(--editor-height);
}
</style>
+97 -82
View File
@@ -1,116 +1,131 @@
<template>
<a-modal
:title="props.title"
width="80%"
:visible="props.visible"
:body-style="{ padding: '0 24px' }"
:destroy-on-close="true"
@cancel="fnCronModal(false)"
@ok="fnCronModal(true)"
>
<div ref="mergeViewContainer" class="mergeViewContainer"></div>
</a-modal>
</template>
<script lang="ts" setup>
import { javascript } from '@codemirror/lang-javascript';
import { yaml } from '@codemirror/lang-yaml';
import { oneDark } from '@codemirror/theme-one-dark';
import { MergeView } from '@codemirror/merge';
import { EditorView, basicSetup } from 'codemirror';
import { EditorState } from '@codemirror/state';
import { watch, ref } from 'vue';
import { nextTick } from 'vue';
const emit = defineEmits(['cancel', 'ok', 'update:visible']);
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
const emit = defineEmits(['update:newArea', 'change']);
const props = defineProps({
visible: {
type: Boolean,
required: true,
},
title: {
type: String,
default: '内容比较',
},
newArea: {
type: String,
default: '当前内容',
},
oldArea: {
type: String,
default: '原始内容',
},
/**当前变更内容 */
newArea: {
type: String,
default: '当前内容',
},
/**编辑框高度 */
height: {
type: String,
default: '400px !important',
default: '400px',
},
/**缩进2空格 */
tabSize: {
type: Number,
default: 2,
},
/**是否禁止输入 */
disabled: {
type: Boolean,
default: true,
},
/**高亮语言 */
lang: {
type: String,
default: 'javascript',
},
});
const mergeViewContainer = ref();
/**视图容器 */
const viewContainerDom = ref<HTMLElement | undefined>(undefined);
let viewContainer: MergeView | null = null;
/**监听是否显示,初始cron属性 */
/**高亮语言拓展 */
function fnLangExtension() {
if (props.lang === 'yaml') {
return yaml();
}
return javascript();
}
/**初始化渲染视图 */
function handleRanderView(container: HTMLElement | undefined) {
if (!container) return;
viewContainer = new MergeView({
a: {
doc: props.oldArea,
extensions: [
fnLangExtension(),
oneDark,
basicSetup,
EditorView.editable.of(false),
EditorState.readOnly.of(true),
],
},
b: {
doc: props.newArea,
extensions: [
fnLangExtension(),
oneDark,
basicSetup,
EditorView.editable.of(!props.disabled),
EditorState.readOnly.of(props.disabled),
EditorState.tabSize.of(props.tabSize),
EditorView.updateListener.of(v => {
if (v.docChanged) {
const docStr = v.state.doc.toString();
emit('change', docStr, v.state.doc);
// 禁用时不双向绑定,防止监听重复变化数值
if (!props.disabled) {
emit('update:newArea', docStr);
}
}
}),
],
},
parent: container,
});
}
/**监听是否value改变 */
watch(
() => props.visible,
() => props.newArea,
val => {
if (val) {
// 开启时等待dom完成
nextTick(() => {
// 设置高度
mergeViewContainer.value.style.height = props.height;
// 实例到dom
new MergeView({
a: {
doc: props.oldArea,
extensions: [
javascript(),
oneDark,
basicSetup,
EditorView.editable.of(false),
EditorState.readOnly.of(true),
],
},
b: {
doc: props.newArea,
extensions: [
javascript(),
oneDark,
basicSetup,
EditorView.editable.of(!props.disabled),
EditorState.readOnly.of(props.disabled),
],
},
parent: mergeViewContainer.value,
});
// 禁用时无输入靠外部值变化改变数值
if (props.disabled && viewContainer) {
const docLine = viewContainer.b.state.doc.length;
viewContainer.b.dispatch({
changes: { from: 0, to: docLine, insert: val },
});
}
}
);
/**
* 窗口事件
* @param val modal触发事件
*/
function fnCronModal(val: boolean) {
emit('update:visible', false);
if (val) {
emit('ok', true);
} else {
emit('cancel');
}
}
onMounted(() => {
handleRanderView(viewContainerDom.value);
});
onBeforeUnmount(() => {
viewContainer?.destroy();
});
</script>
<template>
<div
ref="viewContainerDom"
class="container"
:style="{ '--editor-height': height }"
></div>
</template>
<style lang="less" scoped>
.mergeViewContainer {
height: 400px;
overflow-y: scroll;
overflow-x: hidden;
color: #abb2bf;
background-color: #282c34;
.container {
--editor-height: 400px;
}
.container :deep(.cm-editor) {
height: var(--editor-height);
}
</style>
+10 -8
View File
@@ -1,9 +1,10 @@
<template>
<a-modal
<ProModal
:drag="true"
:destroyOnClose="true"
:title="t('components.CronModal.title')"
:visible="props.visible"
:open="props.open"
:body-style="{ padding: '0 24px' }"
:destroy-on-close="true"
@cancel="fnCronModal(false)"
@ok="fnCronModal(true)"
>
@@ -31,9 +32,10 @@
v-model:value="cronStr"
disabled
/>
</a-modal>
</ProModal>
</template>
<script lang="ts" setup>
import { ProModal } from 'antdv-pro-modal';
import CronSecond from './components/Second.vue';
import CronMinute from './components/Minute.vue';
import CronHour from './components/Hour.vue';
@@ -43,9 +45,9 @@ import { reactive, computed, watch } from 'vue';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const emit = defineEmits(['cancel', 'ok', 'update:visible']);
const emit = defineEmits(['cancel', 'ok', 'update:open']);
const props = defineProps({
visible: {
open: {
type: Boolean,
required: true,
},
@@ -74,7 +76,7 @@ const cronStr = computed(() => {
/**监听是否显示,初始cron属性 */
watch(
() => props.visible,
() => props.open,
val => {
if (!val) return;
const arr = props.cron.split(' ');
@@ -97,7 +99,7 @@ watch(
* @param val modal触发事件
*/
function fnCronModal(val: boolean) {
emit('update:visible', false);
emit('update:open', false);
if (val) {
emit('ok', cronStr.value);
} else {
+16 -10
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',
},
/**当前的值 */
@@ -15,14 +15,24 @@ const props = defineProps({
type: [Number, String],
default: '',
},
/**数据默认值,当前值不存在时 */
valueDefault: {
type: [Number, String],
},
});
/**遍历找到对应值数据项 */
const item = computed(() => {
if (Array.isArray(props.options) && props.options.length > 0) {
const option = (props.options as any[]).find(
let option = props.options.find(
item => `${item[props.valueField]}` === `${props.value}`
);
// 数据默认值
if (!option && props.valueDefault != undefined) {
option = props.options.find(
item => `${item[props.valueField]}` === `${props.valueDefault}`
);
}
return option;
}
return undefined;
@@ -31,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>
-168
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,
},
});
// 对标题进行监听
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>
+141
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 isOpen = 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:open="isOpen"
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>
@@ -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 d’Ivoire",
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",
};
@@ -0,0 +1,4 @@
import countryTranslations from './countries';
import interfaceTranslations from './interface';
export default { ...countryTranslations, ...interfaceTranslations };
@@ -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",
};
@@ -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: "中国香港特别行政区",
};
@@ -0,0 +1,4 @@
import countryTranslations from './countries';
import interfaceTranslations from './interface';
export default { ...countryTranslations, ...interfaceTranslations };
@@ -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: "科索沃",
};
+168
View File
@@ -0,0 +1,168 @@
<!-- https://github.com/jackocnr/intl-tel-input/blob/master/react/src/intl-tel-input/react.tsx -->
<script lang="ts" setup>
import { Iti } from 'intl-tel-input';
import intlTelInput from 'intl-tel-input/intlTelInputWithUtils';
import 'intl-tel-input/build/css/intlTelInput.min.css';
import { ref, onMounted, onBeforeUnmount, nextTick } 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 number = itiRef.value?.getNumber() || '';
const countryIso = itiRef.value?.getSelectedCountryData().iso2 || '';
// note: this number will be in standard E164 format, but any container component can use
// intlTelInputUtils.formatNumber() to convert this to another format
// as well as intlTelInputUtils.getNumberType() etc. if need be
let data = {
number,
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', number);
emit('update:change', data);
}
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,
});
if (props.value) {
itiRef.value.setNumber(props.value);
}
if (props.disabled) {
itiRef.value.setDisabled(props.disabled);
}
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"
: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;
}
.iti .ant-input {
box-sizing: border-box;
margin: 0;
font-variant: tabular-nums;
list-style: none;
font-feature-settings: 'tnum';
position: relative;
display: inline-block;
width: 100%;
min-width: 0;
padding: 4px 11px;
color: #000000d9;
font-size: 14px;
line-height: 1.5715;
background-color: transparent;
background-image: none;
border: 1px solid #424242;
border-radius: 6px;
transition: all 0.3s;
}
.iti .ant-input:focus,
.iti .ant-input-focused {
border-color: var(--ant-primary-color-hover);
box-shadow: 0 0 0 2px var(--ant-primary-color-outline);
border-right-width: 1px !important;
outline: 0;
}
</style>
-217
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>
+73 -15
View File
@@ -1,9 +1,10 @@
<script setup lang="ts">
import { reactive, watch, onMounted, PropType } from 'vue';
import { reactive, watch, onMounted, PropType, nextTick } from 'vue';
import { Container, Draggable } from 'vue3-smooth-dnd';
import useI18n from '@/hooks/useI18n';
import { type ColumnsType } from 'ant-design-vue/lib/table';
const { t } = useI18n();
import { dbGetJSON, dbSetJSON } from '@/utils/cache-db-utils';
import { CACHE_DB_TABLE_DND } from '@/constants/cache-keys-constants';
const { t, currentLocale } = useI18n();
const emit = defineEmits(['update:columns-dnd']);
const props = defineProps({
@@ -16,7 +17,8 @@ const props = defineProps({
type: Array<any>,
required: true,
},
/**按钮类型
/**
* 按钮类型
* text 图标
* ghost 图标按钮带文字
*/
@@ -24,34 +26,50 @@ const props = defineProps({
type: String as PropType<'text' | 'ghost'>,
default: 'text',
},
/**
* 缓存列变更数据标识,不传则不缓存
*/
cacheId: {
type: String,
default: '',
},
});
/**表格字段列 */
const tableColumns = reactive<ColumnsType>(props.columns);
const tableColumns = reactive(props.columns);
/**表格字段列勾选状态 */
const state = reactive({
const state = reactive<{
indeterminate: boolean;
/**是否全选 */
checkAll: boolean;
/**字段标题列表 */
columnsTitleList: string[];
}>({
indeterminate: false,
checkAll: true,
columnsTitleList: tableColumns.map(s => `${s.title}`),
columnsTitleList: [],
});
/**表格字段列全选操作 */
function fnTableColumnsCheckAllChange(e: any) {
const checked = e.target.checked;
state.indeterminate = false;
state.columnsTitleList = checked ? tableColumns.map(s => `${s.title}`) : [];
state.columnsTitleList = checked
? tableColumns.map(s => `${s.title as string}`)
: [];
}
/**表格字段列拖拽操作 */
function fnTableColumnsDrop(dropResult: any) {
const { removedIndex, addedIndex, payload } = dropResult;
if (removedIndex !== null && addedIndex !== null) {
let itemToAdd = payload;
itemToAdd = tableColumns.splice(removedIndex, 1)[0];
tableColumns.splice(addedIndex, 0, itemToAdd);
fnUpdateColumns();
if (removedIndex === null || addedIndex === null) {
return;
}
let itemToAdd = payload;
itemToAdd = tableColumns.splice(removedIndex, 1)[0];
tableColumns.splice(addedIndex, 0, itemToAdd);
fnUpdateColumns();
}
/**表格字段列固定操作 */
@@ -66,6 +84,7 @@ function fnTableColumnsFixed(row: Record<string, any>) {
} else {
row.fixed = !row.fixed;
}
fnUpdateColumns();
}
/**表格字段列勾选字段变化 */
@@ -77,7 +96,18 @@ function fnUpdateColumns() {
if (list.length === 0) {
list = [tableColumns[0]];
}
emit('update:columns-dnd', list);
if (props.cacheId) {
// 存入数据
dbSetJSON(
CACHE_DB_TABLE_DND,
`${props.cacheId}#${currentLocale.value}`,
list
);
}
nextTick(() => {
emit('update:columns-dnd', list);
});
}
/**表格字段列勾选监听 */
@@ -92,7 +122,34 @@ watch(
);
onMounted(() => {
fnUpdateColumns();
if (props.cacheId) {
// 读取数据后响应
dbGetJSON(CACHE_DB_TABLE_DND, `${props.cacheId}#${currentLocale.value}`)
.then(data => {
if (data) {
const titleList: string[] = [];
for (const item of data) {
titleList.push(`${item.title}`);
// 固定标记还原
if (item.fixed !== undefined) {
const fixedItem = tableColumns.find(s => s.title === item.title);
if (fixedItem) {
fixedItem.fixed = item.fixed;
}
}
}
state.columnsTitleList = titleList;
} else {
state.columnsTitleList = tableColumns.map(s => `${s.title}`);
}
})
.finally(() => {
fnUpdateColumns();
});
} else {
state.columnsTitleList = tableColumns.map(s => `${s.title}`);
fnUpdateColumns();
}
});
</script>
@@ -128,6 +185,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)"
>
+225
View File
@@ -0,0 +1,225 @@
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { FitAddon } from '@xterm/addon-fit';
import { Terminal } from '@xterm/xterm';
import '@xterm/xterm/css/xterm.css';
import { RESULT_CODE_ERROR } from '@/constants/result-constants';
import { OptionsType, WS } from '@/plugins/ws-websocket';
const ws = new WS();
const emit = defineEmits(['connect', 'close', 'message']);
const props = defineProps({
/**终端ID,必传 */
id: {
type: String,
required: true,
},
/**连接主机ID,必传 */
hostId: {
type: String,
required: true,
},
/**初始发送命令 */
initCmd: {
type: [String, Boolean],
default: false,
},
});
/**终端输入DOM节点实例对象 */
const terminalDom = ref<HTMLElement | undefined>(undefined);
/**终端输入实例对象 */
const terminal = ref<any>(null);
/**终端输入命令 */
const terminalCmd = ref<string>('');
/**终端输入渲染 */
function handleRanderXterm(container: HTMLElement | undefined) {
if (!container) return;
const xterm = new Terminal({
lineHeight: 1.2,
fontSize: 12,
fontFamily: "Monaco, Menlo, Consolas, 'Courier New', monospace",
theme: {
background: '#000000',
},
cursorBlink: true, // 光标闪烁
cursorStyle: 'block',
scrollback: 1000,
scrollSensitivity: 15,
tabStopWidth: 4,
disableStdin: false, // 禁止输入
});
// 挂载
xterm.open(container);
// 自适应尺寸
const fitAddon = new FitAddon();
xterm.loadAddon(fitAddon);
// 终端输入字符按键监听
xterm.onKey(({ key, domEvent }) => {
// console.log(key, domEvent);
// 单键输入
switch (domEvent.key) {
case 'Enter':
const cmdStr = terminalCmd.value.trim();
// 发送文本
terminal.value.scrollToBottom();
terminal.value.writeln('\r\n');
ws.send({
requestId: `redis_${props.hostId}`,
type: 'redis',
data: `${cmdStr}\r\n`,
});
terminalCmd.value = '';
// 退出登录
if ('quit' === cmdStr) {
setTimeout(() => {
ws.close();
}, 1000);
}
break;
case 'Backspace':
// 处理退格键,删除最后一个字符
xterm.write('\b \b');
break;
default:
xterm.write(key);
terminalCmd.value += key;
return;
}
});
// 创建 ResizeObserver 实例
var observer = new ResizeObserver(entries => {
fitAddon.fit();
});
// 监听元素大小变化
observer.observe(container);
terminal.value = xterm;
}
/**连接打开后回调 */
function wsOpen(ev: any) {
// console.info('wsOpen', ev);
nextTick(() => {
handleRanderXterm(terminalDom.value);
// 连接事件
emit('connect', {
timeStamp: ev.timeStamp,
cols: terminal.value.cols,
rows: terminal.value.rows,
hostId: props.hostId,
id: props.id,
});
// 初始发送命令
if (typeof props.initCmd === 'string') {
ws.send({
requestId: `redis_${props.hostId}`,
type: 'redis',
data: `${props.initCmd}\r\n`,
});
}
});
}
/**连接错误后回调 */
function wsError(ev: any) {
console.error('wsError', ev);
if (terminal.value != null) {
let message = 'disconnected';
terminal.value.write(`\x1b[31m${message}\x1b[m\r\n`);
} else if (terminalDom.value) {
terminalDom.value.style.background = '#000';
terminalDom.value.style.color = '#ff4d4f';
terminalDom.value.style.height = '60%';
terminalDom.value.innerText = 'disconnected';
}
}
/**连接关闭后回调 */
function wsClose(code: number) {
// console.warn('wsClose', code);
if (terminal.value != null) {
let message = 'disconnected';
terminal.value.write(`\x1b[31m${message}\x1b[m\r\n`);
}
// 关闭事件
emit('close', {
code: code,
hostId: props.hostId,
id: props.id,
});
}
/**接收消息后回调 */
function wsMessage(res: Record<string, any>) {
emit('message', res);
// console.log('wsMessage', res);
const { code, requestId, data } = res;
if (code === RESULT_CODE_ERROR) {
console.warn(res.msg);
return;
}
if (!requestId) return;
if (data.indexOf('is empty') > 0) return;
if (terminal.value != null) {
// terminal.value.write(data.trim().replace(/\n/g, "\r\n"));
// 是否n结尾
if (/[\r\n]$/.test(data)) {
terminal.value.writeln(data.trim().replace(/\n/g, '\r\n'));
} else {
terminal.value.write(data.replace(/\n/g, '\r\n'));
}
}
}
onMounted(() => {
if (props.hostId) {
// 建立链接
const options: OptionsType = {
url: '/ws/redis',
params: {
hostId: props.hostId,
},
onmessage: wsMessage,
onerror: wsError,
onopen: wsOpen,
onclose: wsClose,
};
ws.connect(options);
}
});
onBeforeUnmount(() => {
ws.close();
});
// 给组件设置属性 ref="xxxTerminal"
// setup内使用 const xxxTerminal = ref();
defineExpose({
/**发送方法 */
send: (data: string) => {
ws.send({
requestId: `redis_${props.hostId}`,
type: 'redis',
data: `${data}\r\n`,
});
},
});
</script>
<template>
<div class="terminal">
<div ref="terminalDom" :id="id" class="terminal"></div>
</div>
</template>
<style lang="css" scoped>
.terminal {
width: 100%;
height: 100%;
}
</style>
+258
View File
@@ -0,0 +1,258 @@
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { FitAddon } from '@xterm/addon-fit';
import { Terminal } from '@xterm/xterm';
import '@xterm/xterm/css/xterm.css';
import { RESULT_CODE_ERROR } from '@/constants/result-constants';
import { OptionsType, WS } from '@/plugins/ws-websocket';
const ws = new WS();
const emit = defineEmits(['connect', 'close', 'message']);
const props = defineProps({
/**终端ID,必传 */
id: {
type: String,
required: true,
},
/**连接主机ID,必传 */
hostId: {
type: String,
required: true,
},
/**窗口单行字符数 */
cols: {
type: Number,
default: 80,
},
/**窗口行数 */
rows: {
type: Number,
default: 40,
},
/**禁止输入 */
disable: {
type: Boolean,
default: false,
},
/**初始发送命令 */
initCmd: {
type: [String, Boolean],
default: false,
},
});
/**终端输入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,
scrollSensitivity: 15,
tabStopWidth: 4,
disableStdin: props.disable, // 禁止输入
});
// 挂载
xterm.open(container);
// 自适应尺寸
const fitAddon = new FitAddon();
xterm.loadAddon(fitAddon);
// 终端输入字符按键监听
xterm.onData(char => {
ws.send({
requestId: `ssh_${props.hostId}`,
type: 'ssh',
data: char,
});
// const printable = char.match(/[\x20-\x7E]/); // 匹配可打印字符的正则表达式
// if (char === '\r' || char === '\x0D') {
// // 处理回车键,添加换行
// xterm.writeln('');
// } else if (char === '\x08' || char === '\x7F') {
// // 处理退格键,删除最后一个字符
// xterm.write('\b \b');
// } else if (printable) {
// // 处理可打印字符
// xterm.write(char);
// }
});
// 终端输入按键监听
// xterm.onKey(({ key, domEvent }) => {
// // console.log(key, domEvent);
// // 单键输入
// // switch (domEvent.key) {
// // case 'ArrowUp':
// // // 按“↑”方向键时要做的事。
// // break;
// // case 'ArrowDown':
// // // 按“↓”方向键时要做的事。
// // break;
// // case 'ArrowLeft':
// // // 按“←”方向键时要做的事。
// // break;
// // case 'ArrowRight':
// // // 按“→”方向键时要做的事。
// // break;
// // case 'Enter':
// // // 处理回车键,添加换行
// // term.writeln('');
// // break;
// // case 'Backspace':
// // // 处理退格键,删除最后一个字符
// // term.write('\b \b');
// // break;
// // case 'Escape':
// // // 按“ESC”键时要做的事。
// // break;
// // default:
// // return; // 什么都没按就退出吧。
// // }
// });
// 终端尺寸变化触发
xterm.onResize(({ cols, rows }) => {
// console.log('尺寸', cols, rows);
ws.send({
requestId: `ssh_resize_${props.hostId}`,
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,
hostId: props.hostId,
id: props.id,
});
// 初始发送命令
if (typeof props.initCmd === 'string') {
ws.send({
requestId: `ssh_${props.hostId}`,
type: 'ssh',
data: `${props.initCmd}\n`,
});
}
});
}
/**连接错误后回调 */
function wsError(ev: any) {
// console.error('wsError', ev);
if (terminal.value != null) {
let message = 'disconnected';
terminal.value.write(`\x1b[31m${message}\x1b[m\r\n`);
} else if (terminalDom.value) {
terminalDom.value.style.background = '#000';
terminalDom.value.style.color = '#ff4d4f';
terminalDom.value.style.height = '60%';
terminalDom.value.innerText = 'disconnected';
}
}
/**连接关闭后回调 */
function wsClose(code: number) {
// console.warn('wsClose', code);
if (terminal.value != null) {
let message = 'disconnected';
terminal.value.write(`\x1b[31m${message}\x1b[m\r\n`);
}
// 关闭事件
emit('close', {
code: code,
hostId: props.hostId,
id: props.id,
});
}
/**接收消息后回调 */
function wsMessage(res: Record<string, any>) {
emit('message', res);
// console.log('wsMessage', res);
const { code, requestId, data } = res;
if (code === RESULT_CODE_ERROR) {
console.warn(res.msg);
return;
}
if (!requestId) return;
if (terminal.value != null) {
terminal.value.write(data);
}
}
onMounted(() => {
if (props.hostId) {
// 建立链接
const options: OptionsType = {
url: '/ws/ssh',
params: {
hostId: props.hostId,
cols: props.cols,
rows: props.rows,
},
onmessage: wsMessage,
onerror: wsError,
onopen: wsOpen,
onclose: wsClose,
};
ws.connect(options);
}
});
onBeforeUnmount(() => {
ws.close();
});
// 给组件设置属性 ref="xxxTerminal"
// setup内使用 const xxxTerminal = ref();
defineExpose({
/**发送方法 */
send: (data: string) => {
ws.send({
requestId: `ssh_${props.hostId}`,
type: 'ssh',
data: `${data}\n`,
});
},
});
</script>
<template>
<div ref="terminalDom" :id="id" class="terminal"></div>
</template>
<style lang="css" scoped>
.terminal {
width: 100%;
height: 100%;
}
</style>
+264
View File
@@ -0,0 +1,264 @@
<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',
},
/**消息处理函数 */
processMessages: {
type: Function,
default: undefined,
},
});
/**终端输入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) {
let text = '';
// 处理消息
if (props.processMessages) {
text = props.processMessages(data);
}else{
text = processMessage(data);
}
// 无消息是则不输出
if (text === '') {
return;
}
terminal.value.write(text);
}
}
/**终端消息处理*/
function processMessage(data: string): string {
// 查找的开始输出标记
const parts: string[] = data.split('\u001b[?2004l\r');
if (parts.length > 0) {
if (parts[0].startsWith('^C') || parts[0].startsWith('\r')) {
return '';
}
let text = parts[parts.length - 1];
// 找到最后输出标记
let lestIndex = text.lastIndexOf('\u001b[?2004h\u001b]0;');
if (lestIndex !== -1) {
text = text.substring(0, lestIndex);
}
if (text === '' || text === '\r\n' || text.startsWith('^C\r\n')) {
return '';
}
// 是否还有最后输出标记
lestIndex = text.lastIndexOf('\u001b[?2004h');
if (lestIndex !== -1) {
text = text.substring(0, lestIndex);
}
// console.log({ parts, text });
return text;
}
return data;
}
onMounted(() => {
if (props.neType && props.neId) {
// 建立链接
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>
+314
View File
@@ -0,0 +1,314 @@
<script lang="ts" setup>
import { message } from 'ant-design-vue/es';
import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { FitAddon } from '@xterm/addon-fit';
import { Terminal } from '@xterm/xterm';
import '@xterm/xterm/css/xterm.css';
import { RESULT_CODE_ERROR } from '@/constants/result-constants';
import { OptionsType, WS } from '@/plugins/ws-websocket';
const ws = new WS();
const emit = defineEmits(['connect', 'close', 'message']);
const props = defineProps({
/**终端ID,必传 */
id: {
type: String,
required: true,
},
/**连接主机ID,必传 */
hostId: {
type: String,
required: true,
},
/**窗口单行字符数 */
cols: {
type: Number,
default: 120,
},
/**窗口行数 */
rows: {
type: Number,
default: 128,
},
/**禁止输入 */
disable: {
type: Boolean,
default: false,
},
/**初始发送命令 */
initCmd: {
type: [String, Boolean],
default: false,
},
});
/**终端输入DOM节点实例对象 */
const terminalDom = ref<HTMLElement | undefined>(undefined);
/**终端输入实例对象 */
const terminal = ref<any>(null);
/**终端输入文字状态 */
const terminalState = reactive<{
/**输入值 */
text: string;
/**历史 */
history: {
label?: string;
value: string;
}[];
}>({
text: '',
history: [
{
value: 'help',
},
{
value: 'quit',
},
{
value: 'list ver',
},
{
value: 'list lic',
},
],
});
/**自动完成根据输入项进行筛选 */
function fnAutoCompleteFilter(input: string, option: any) {
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0;
}
/**自动完成按键触发 */
function fnAutoCompleteKeydown(evt: any) {
if (evt.key === 'Enter') {
// 阻止默认的换行行为
evt.preventDefault();
// 按下 Shift + Enter 键时换行
if (evt.shiftKey) {
// 插入换行符
const textarea = evt.target;
const start = textarea.selectionStart;
const end = textarea.selectionEnd;
const text = textarea.value;
textarea.value = text.substring(0, start) + '\n' + text.substring(end);
terminalState.text = textarea.value;
// 更新光标位置
textarea.selectionStart = textarea.selectionEnd = start + 1;
} else {
// ws未连接
if (ws.state() !== WebSocket.OPEN) {
message.error('disconnected');
return;
}
// 输入历史
const cmdStr = terminalState.text.trim().replace(/\n/g, '\r\n');
const hisIndex = terminalState.history.findIndex(
item => item.value === cmdStr
);
if (hisIndex === -1) {
terminalState.history.push({
value: cmdStr,
});
}
// 发送文本
terminal.value.scrollToBottom();
terminal.value.writeln(cmdStr);
ws.send({
requestId: `telnet_${props.hostId}`,
type: 'telnet',
data: `${cmdStr}\r\n`,
});
terminalState.text = ' ';
// 退出登录
if (['q', 'quit', 'exit'].includes(cmdStr)) {
setTimeout(() => {
ws.close();
}, 1000);
}
}
}
}
/**终端输入渲染 */
function handleRanderXterm(container: HTMLElement | undefined) {
if (!container) return;
const xterm = new Terminal({
lineHeight: 1.2,
fontSize: 12,
fontFamily: "Monaco, Menlo, Consolas, 'Courier New', monospace",
theme: {
background: '#000000',
},
cursorBlink: true, // 光标闪烁
cursorStyle: 'block',
scrollback: 1000,
scrollSensitivity: 15,
tabStopWidth: 4,
disableStdin: props.disable, // 禁止输入
});
// 挂载
xterm.open(container);
// 自适应尺寸
const fitAddon = new FitAddon();
xterm.loadAddon(fitAddon);
// 终端尺寸变化触发
xterm.onResize(({ cols, rows }) => {
// console.log('尺寸', cols, rows);
ws.send({
requestId: `telnet_resize_${props.hostId}`,
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,
hostId: props.hostId,
id: props.id,
});
// 初始发送命令
if (typeof props.initCmd === 'string') {
ws.send({
requestId: `telnet_${props.hostId}`,
type: 'telnet',
data: `${props.initCmd}\r\n`,
});
}
});
}
/**连接错误后回调 */
function wsError(ev: any) {
console.error('wsError', ev);
if (terminal.value != null) {
let message = 'disconnected';
terminal.value.write(`\x1b[31m${message}\x1b[m\r\n`);
} else if (terminalDom.value) {
terminalDom.value.style.background = '#000';
terminalDom.value.style.color = '#ff4d4f';
terminalDom.value.style.height = '60%';
terminalDom.value.innerText = 'disconnected';
}
}
/**连接关闭后回调 */
function wsClose(code: number) {
// console.warn('wsClose', code);
if (terminal.value != null) {
let message = 'disconnected';
terminal.value.write(`\x1b[31m${message}\x1b[m\r\n`);
}
// 关闭事件
emit('close', {
code: code,
hostId: props.hostId,
id: props.id,
});
}
/**接收消息后回调 */
function wsMessage(res: Record<string, any>) {
emit('message', res);
// console.log('wsMessage', res);
const { code, requestId, data } = res;
if (code === RESULT_CODE_ERROR) {
console.warn(res.msg);
return;
}
if (!requestId) return;
if (terminal.value != null) {
// terminal.value.write(data.trim().replace(/\n/g, "\r\n"));
// 是否n结尾
if (/[\r\n]$/.test(data)) {
terminal.value.writeln(data.trim().replace(/\n/g, '\r\n'));
} else {
terminal.value.write(data.replace(/\n/g, '\r\n'));
}
}
}
onMounted(() => {
if (props.hostId) {
// 建立链接
const options: OptionsType = {
url: '/ws/telnet',
params: {
hostId: props.hostId,
cols: props.cols,
rows: props.rows,
},
onmessage: wsMessage,
onerror: wsError,
onopen: wsOpen,
onclose: wsClose,
};
ws.connect(options);
}
});
onBeforeUnmount(() => {
ws.close();
});
// 给组件设置属性 ref="xxxTerminal"
// setup内使用 const xxxTerminal = ref();
defineExpose({
/**发送方法 */
send: (data: string) => {
ws.send({
requestId: `telnet_${props.hostId}`,
type: 'telnet',
data: `${data}\r\n`,
});
},
});
</script>
<template>
<div class="terminal">
<div ref="terminalDom" style="height: calc(100% - 36px)" :id="id"></div>
<a-auto-complete
v-model:value="terminalState.text"
:dropdown-match-select-width="500"
style="width: 100%"
:options="terminalState.history"
:filter-option="fnAutoCompleteFilter"
@keydown="fnAutoCompleteKeydown"
>
<a-textarea
:auto-size="{ minRows: 1, maxRows: 6 }"
placeholder="Execute command. Shift+Enter to line feed, Enter to send"
/>
</a-auto-complete>
</div>
</template>
<style lang="css" scoped>
.terminal {
width: 100%;
height: 100%;
}
</style>
+38 -24
View File
@@ -1,10 +1,11 @@
<script setup lang="ts">
import { message } from 'ant-design-vue/lib';
import { FileType } from 'ant-design-vue/lib/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import { message } from 'ant-design-vue/es';
import { FileType } from 'ant-design-vue/es/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { ProModal } from 'antdv-pro-modal';
import useI18n from '@/hooks/useI18n';
const { t } = useI18n();
const emit = defineEmits(['upload', 'close', 'update:visible']);
const emit = defineEmits(['upload', 'close', 'update:open']);
const props = defineProps({
/**窗口标题 */
title: {
@@ -17,7 +18,7 @@ const props = defineProps({
default: false,
},
/**是否弹出显示,必传 */
visible: {
open: {
type: Boolean,
required: true,
},
@@ -35,19 +36,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 +60,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 +72,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"
:open="props.open"
: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 +101,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>
+204
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>
+3 -3
View File
@@ -1,5 +1,5 @@
/**管理员-系统指定角色KEY */
export const ADMIN_ROLE_KEY = 'admin';
/**系统管理员-系统指定角色KEY */
export const ADMIN_ROLE_KEY = 'system';
/**管理员-系统指定权限 */
/**系统管理员-系统指定权限 */
export const ADMIN_PERMISSION = '*:*:*';
+3
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';
+8 -2
View File
@@ -10,5 +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';
+29
View File
@@ -0,0 +1,29 @@
/**网元列表,默认顺序 */
export const NE_TYPE_LIST = [
'OMC',
'IMS',
'AMF',
'AUSF',
'UDM',
'SMF',
'PCF',
'NSSF',
'NRF',
'UPF',
'LMF',
'NEF',
'MME',
'N3IWF',
'MOCNGW',
'SMSC',
'SMSF',
'CBC',
'CHF',
];
/**
* 网元拓展包列表,默认顺序
* IMS-adb/kvdb/rtproxy/mf
* UDM-adb/kvdb
*/
export const NE_EXPAND_LIST = ['ADB', 'KVDB', 'RTPROXY', 'MF'];
+9
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;
+2 -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/es';
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());
});
};
+646 -110
View File
File diff suppressed because it is too large. Load diff
+616 -80
View File
File diff suppressed because it is too large. Load diff
Loaded 100 of 299 files, more files were not shown because too many files have changed in this diff. Show more