26 Commits

Author SHA1 Message Date
TsMask
2b2a09ff38 Merge branch 'main-v2' into lichang 2025-07-01 10:15:22 +08:00
TsMask
2181d51999 fix: 参数配置可见visible属性判断 2025-06-30 16:17:07 +08:00
TsMask
a2a7ec3857 chore: 更新版本号 2.2506.4 2025-06-27 19:33:51 +08:00
TsMask
a9b266d49f Merge branch 'main-v2' into lichang 2025-06-26 17:30:28 +08:00
TsMask
1566392c19 feat: AMF/MME对应的IMEI白名单模板去除index 2025-06-24 17:13:57 +08:00
TsMask
5704ff09c3 fix: UDM-IMS数据批量新增/批量删除命令调整 2025-06-24 17:13:18 +08:00
TsMask
673b8f9ad2 chore: 更新版本号 2.250620 2025-06-20 19:30:30 +08:00
TsMask
b6468eecab feat: UDM签约cnType新增可选1仅5G/2仅4G 2025-06-20 14:54:53 +08:00
TsMask
b8c6761fbf feat: 给AMF/MME对应的IMEI白名单添加批量导入和批量删除功能 2025-06-20 14:39:53 +08:00
TsMask
4690a874af Merge branch 'main-v2' into lichang 2025-06-16 19:41:00 +08:00
TsMask
d6aa4086e2 feat: UDM voup/ims导入失败文件下载 2025-06-16 18:47:13 +08:00
TsMask
f513b47fb8 chore: 更新版本号 2.250613 2025-06-13 20:12:08 +08:00
TsMask
859615fecc feat: 菜单根据切换核心网显示 2025-06-13 19:48:09 +08:00
TsMask
4167428c10 chore: 更新依赖项版本 2025-06-13 14:24:36 +08:00
TsMask
11137c03a3 feat: 选择核心网控件 2025-06-13 14:21:56 +08:00
TsMask
d623b7ea36 Merge branch 'main-v2' into lichang 2025-06-12 19:40:54 +08:00
TsMask
eb1dccd642 fix: 数值控件属性maxlength拼写错误 2025-06-12 19:40:25 +08:00
TsMask
4e4b4bc2b7 feat: 顶部右侧内容移除冗余代码,封装为组件 2025-06-12 10:43:47 +08:00
TsMask
4d171b0d06 Merge branch 'main-v2' into lichang 2025-06-12 10:42:27 +08:00
TsMask
94ba520f5d fix: 空格内容无法编辑,提示信息显示方向 2025-06-12 10:34:05 +08:00
TsMask
52573c7678 Merge branch 'main-v2' into lichang 2025-06-12 10:17:18 +08:00
TsMask
d3649ea784 style: 抓包文件目录列表显示文件大小 2025-06-11 20:35:35 +08:00
TsMask
9bddfceda5 fix: 网元参数配置list类型值空白空格bug补充占位符 2025-06-09 18:25:48 +08:00
TsMask
2f7c22aac2 chore: 更新版本号 2.250607 2025-06-07 16:29:29 +08:00
TsMask
2f8ed1d821 fix: 请求响应码常量,身份信息更换逻辑优化 2025-06-07 16:28:18 +08:00
TsMask
d84a6626c1 fix: 更新tcpdump路径从/tmp到/usr/local以符合新目录结构 2025-06-06 15:06:52 +08:00
82 changed files with 1567 additions and 554 deletions

View File

@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network OMC"
VITE_APP_CODE = "OMC" VITE_APP_CODE = "OMC"
# 应用版本 # 应用版本
VITE_APP_VERSION = "2.250530" VITE_APP_VERSION = "2.2506.4"
# 接口基础URL地址-不带/后缀 # 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api" VITE_API_BASE_URL = "/omc-api"

View File

@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network OMC"
VITE_APP_CODE = "OMC" VITE_APP_CODE = "OMC"
# 应用版本 # 应用版本
VITE_APP_VERSION = "2.250530" VITE_APP_VERSION = "2.2506.4"
# 接口基础URL地址-不带/后缀 # 接口基础URL地址-不带/后缀
VITE_API_BASE_URL = "/omc-api" VITE_API_BASE_URL = "/omc-api"

View File

@@ -1,5 +1,28 @@
# 版本发布日志 # 版本发布日志
## 2.2506.4-20250627
- 修复 UDM-IMS数据批量新增/批量删除命令调整
- 优化 AMF/MME对应的IMEI白名单模板去除index
## 2.2506.3-20250620
- 新增 UDM签约cnType新增可选1仅5G/2仅4G
- 新增 给AMF/MME对应的IMEI白名单添加批量导入和批量删除功能
- 新增 UDM voup/ims导入失败文件下载
## 2.2506.2-20250613
- 修复 数值控件属性maxlength拼写错误
- 修复 空格内容无法编辑,提示信息显示方向
- 优化 抓包文件目录列表显示文件大小
## 2.2506.1-20250607
- 优化 请求响应码常量,身份信息更换逻辑优化
- 修复 更新tcpdump路径从/tmp到/usr/local以符合新目录结构
## 2.2505.4-20250530 ## 2.2505.4-20250530
- 优化 网元参数配置修改tooltip位置为bottomLeft防止遮挡 - 优化 网元参数配置修改tooltip位置为bottomLeft防止遮挡

View File

@@ -14,9 +14,9 @@
"dependencies": { "dependencies": {
"@ant-design/icons-vue": "7.0.1", "@ant-design/icons-vue": "7.0.1",
"@antv/g6": "4.8.25", "@antv/g6": "4.8.25",
"@codemirror/lang-javascript": "6.2.3", "@codemirror/lang-javascript": "6.2.4",
"@codemirror/lang-yaml": "6.1.2", "@codemirror/lang-yaml": "6.1.2",
"@codemirror/merge": "6.10.0", "@codemirror/merge": "6.10.2",
"@codemirror/theme-one-dark": "6.1.2", "@codemirror/theme-one-dark": "6.1.2",
"@tato30/vue-pdf": "1.11.3", "@tato30/vue-pdf": "1.11.3",
"@vueuse/core": "13.0.0", "@vueuse/core": "13.0.0",
@@ -24,22 +24,21 @@
"@xterm/xterm": "5.5.0", "@xterm/xterm": "5.5.0",
"ant-design-vue": "4.2.6", "ant-design-vue": "4.2.6",
"antdv-pro-layout": "4.2.0", "antdv-pro-layout": "4.2.0",
"antdv-pro-modal": "4.0.8", "antdv-pro-modal": "4.0.9",
"codemirror": "6.0.1", "codemirror": "6.0.1",
"crypto-js": "4.2.0", "crypto-js": "4.2.0",
"dayjs": "1.11.13", "dayjs": "1.11.13",
"echarts": "5.6.0", "echarts": "5.6.0",
"file-saver": "2.0.5", "file-saver": "2.0.5",
"grid-layout-plus": "1.0.6",
"intl-tel-input": "25.2.0", "intl-tel-input": "25.2.0",
"js-base64": "^3.7.7", "js-base64": "^3.7.7",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"localforage": "^1.10.0", "localforage": "^1.10.0",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"p-queue": "8.0.1", "p-queue": "8.0.1",
"pinia": "2.3.0", "pinia": "3.0.3",
"vue": "3.5.13", "vue": "3.5.16",
"vue-i18n": "11.1.2", "vue-i18n": "11.1.5",
"vue-router": "4.5.0", "vue-router": "4.5.0",
"vue3-smooth-dnd": "0.0.6", "vue3-smooth-dnd": "0.0.6",
"xlsx": "0.18.5" "xlsx": "0.18.5"
@@ -50,12 +49,12 @@
"@types/js-cookie": "3.0.6", "@types/js-cookie": "3.0.6",
"@types/node": "^18.0.0", "@types/node": "^18.0.0",
"@types/nprogress": "0.2.3", "@types/nprogress": "0.2.3",
"@vitejs/plugin-vue": "5.2.3", "@vitejs/plugin-vue": "5.2.4",
"less": "4.2.2", "less": "4.3.0",
"typescript": "5.8.2", "typescript": "5.8.2",
"unplugin-vue-components": "0.28.0", "unplugin-vue-components": "0.28.0",
"vite": "6.3.3", "vite": "6.3.5",
"vite-plugin-compression": "0.5.1", "vite-plugin-compression": "0.5.1",
"vue-tsc": "2.2.8" "vue-tsc": "2.2.10"
} }
} }

Binary file not shown.

86
src/api/core/coreInfo.ts Normal file
View File

@@ -0,0 +1,86 @@
import { CACHE_SESSION_CRYPTO_API } from '@/constants/cache-keys-constants';
import { sessionGet } from '@/utils/cache-session-utils';
import { request } from '@/plugins/http-fetch';
/**
* 查询核心网列表
* @param query 查询参数
* @returns object
*/
export function listCoreInfo(query: Record<string, any>) {
return request({
url: '/core/info/list',
method: 'GET',
params: query,
timeout: 60_000,
});
}
/**
* 查询核心网列表全部无分页
* @param query 查询参数
* @returns object
*/
export function listAllCoreInfo(query: Record<string, any>) {
return request({
url: '/core/info/list/all',
method: 'GET',
params: query,
timeout: 60_000,
});
}
/**
* 查询核心网信息详细
* @param id 信息ID
* @returns object
*/
export function getCoreInfo(id: string | number) {
return request({
url: `/core/info/${id}`,
method: 'GET',
});
}
/**
* 核心网信息新增
* @param data 核心网对象
* @returns object
*/
export function addCoreInfo(data: Record<string, any>) {
return request({
url: `/core/info`,
method: 'POST',
data: data,
crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false',
timeout: 30_000,
});
}
/**
* 核心网信息修改
* @param data 核心网对象
* @returns object
*/
export function updateCoreInfo(data: Record<string, any>) {
return request({
url: `/core/info`,
method: 'PUT',
data: data,
crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false',
timeout: 30_000,
});
}
/**
* 核心网信息删除
* @param id 信息ID
* @returns object
*/
export function delCoreInfo(id: string | number) {
return request({
url: `/core/info/${id}`,
method: 'DELETE',
timeout: 60_000,
});
}

View File

@@ -73,12 +73,12 @@ export function delNeInfo(infoIds: string | number) {
/** /**
* 查询网元列表全部无分页 * 查询网元列表全部无分页
* @param query 查询参数 neType neId bandStatus bandHost * @param query 查询参数 coreUid, neUid bandStatus bandHost
* @returns object * @returns object
*/ */
export function listAllNeInfo(query: Record<string, any>) { export function listAllNeInfo(query: Record<string, any>) {
return request({ return request({
url: '/ne/info/listAll', url: '/ne/info/list/all',
method: 'GET', method: 'GET',
params: query, params: query,
timeout: 60_000, timeout: 60_000,
@@ -87,57 +87,57 @@ export function listAllNeInfo(query: Record<string, any>) {
/** /**
* 查询网元状态 * 查询网元状态
* @param neType 网元类型 * @param coreUid 核心网ID
* @param neId 网元ID * @param neUid 网元ID
* @returns object * @returns object
*/ */
export function stateNeInfo(neType: string, neId: string) { export function stateNeInfo(coreUid: string, neUid: string) {
return request({ return request({
url: '/ne/info/state', url: '/ne/info/state',
method: 'GET', method: 'GET',
params: { neType, neId }, params: { coreUid, neUid },
}); });
} }
/** /**
* 查询网元信息 * 查询网元信息
* @param neType 网元类型 * @param coreUid 核心网ID
* @param neId 网元ID * @param neUid 网元ID
* @returns object * @returns object
*/ */
export function getNeInfoByTypeAndID(neType: string, neId: string) { export function getNeInfoByTypeAndID(coreUid: string, neUid: string) {
return request({ return request({
url: '/ne/info/byTypeAndID', url: '/ne/info/nf',
method: 'GET', method: 'GET',
params: { neType, neId }, params: { coreUid, neUid },
}); });
} }
/** /**
* 网元端OAM配置文件读取 * 网元端OAM配置文件读取
* @param neType 网元类型 * @param coreUid 核心网ID
* @param neId 网元ID * @param neUid 网元ID
* @returns object * @returns object
*/ */
export function getOAMFile(neType: string, neId: string) { export function getOAMFile(coreUid: string, neUid: string) {
return request({ return request({
url: '/ne/info/oamFile', url: '/ne/info/file/oam',
method: 'GET', method: 'GET',
params: { neType, neId }, params: { coreUid, neUid },
}); });
} }
/** /**
* 网元端配置文件写入 * 网元端配置文件写入
* @param neType 网元类型 * @param coreUid 核心网ID
* @param neId 网元ID * @param neUid 网元ID
* @param content 用json对象 * @param content 用json对象
* @param sync 同步到网元 * @param sync 同步到网元
* @returns object * @returns object
*/ */
export function saveOAMFile(data: Record<string, any>) { export function saveOAMFile(data: Record<string, any>) {
return request({ return request({
url: `/ne/info/oamFile`, url: `/ne/info/file/oam`,
method: 'PUT', method: 'PUT',
data: data, data: data,
timeout: 60_000, timeout: 60_000,
@@ -150,7 +150,7 @@ export function saveOAMFile(data: Record<string, any>) {
*/ */
export function getPara5GFilee() { export function getPara5GFilee() {
return request({ return request({
url: '/ne/info/para5GFile', url: '/ne/info/file/para5g',
method: 'GET', method: 'GET',
}); });
} }
@@ -158,12 +158,12 @@ export function getPara5GFilee() {
/** /**
* 网元端公共配置文件写入 * 网元端公共配置文件写入
* @param content txt内容为字符串 其他文件格式都用json对象 * @param content txt内容为字符串 其他文件格式都用json对象
* @param syncNe 同步到网元端 NeType@ NeId * @param syncNe 同步到网元端 coreUid@ neUid
* @returns object * @returns object
*/ */
export function savePara5GFile(data: Record<string, any>) { export function savePara5GFile(data: Record<string, any>) {
return request({ return request({
url: `/ne/info/para5GFile`, url: `/ne/info/file/para5g`,
method: 'PUT', method: 'PUT',
data: data, data: data,
timeout: 60_000, timeout: 60_000,
@@ -172,7 +172,7 @@ export function savePara5GFile(data: Record<string, any>) {
/** /**
* 网元服务操作 * 网元服务操作
* @param data 对象 {neType,neId,action} * @param data 对象 {coreUid, neUid, action}
* @returns object * @returns object
*/ */
export function serviceNeAction(data: Record<string, any>) { export function serviceNeAction(data: Record<string, any>) {

View File

@@ -71,13 +71,16 @@ export function batchAddUDMVolteIMS(data: Record<string, any>, num: number) {
/** /**
* UDMVolteIMS用户删除 * UDMVolteIMS用户删除
* @param data 签约对象 * @param neId 网元ID
* @param imsi_msisdn IMSI/MSISDN
* @param tag 标签 0-voip 1-volte
* @returns object * @returns object
*/ */
export function delUDMVolteIMS(neId: string, imsi: string) { export function delUDMVolteIMS(neId: string, imsi_msisdn: string, tag: string) {
return request({ return request({
url: `/neData/udm/volte-ims/${neId}/${imsi}`, url: `/neData/udm/volte-ims/${neId}/${imsi_msisdn}`,
method: 'DELETE', method: 'DELETE',
params: { volte: tag },
timeout: 180_000, timeout: 180_000,
}); });
} }
@@ -87,12 +90,19 @@ export function delUDMVolteIMS(neId: string, imsi: string) {
* @param neId 网元ID * @param neId 网元ID
* @param imsi IMSI * @param imsi IMSI
* @param num 数量 * @param num 数量
* @param tag 标签 0-voip 1-volte
* @returns object * @returns object
*/ */
export function batchDelUDMVolteIMS(neId: string, imsi: string, num: number) { export function batchDelUDMVolteIMS(
neId: string,
imsi: string,
num: number,
tag: string
) {
return request({ return request({
url: `/neData/udm/volte-ims/${neId}/${imsi}/${num}`, url: `/neData/udm/volte-ims/${neId}/${imsi}/${num}`,
method: 'DELETE', method: 'DELETE',
params: { volte: tag },
timeout: 180_000, timeout: 180_000,
}); });
} }

View File

@@ -4,6 +4,9 @@ export const CACHE_SESSION_CRYPTO_API = 'cache:session:cryptoApi';
/**会话缓存-网络请求 */ /**会话缓存-网络请求 */
export const CACHE_SESSION_FATCH = 'cache:session:fatch'; export const CACHE_SESSION_FATCH = 'cache:session:fatch';
/**会话缓存-当前选中核心网 */
export const CACHE_SESSION_CORE = 'cache:session:core';
/**本地缓存-布局设置 */ /**本地缓存-布局设置 */
export const CACHE_LOCAL_PROCONFIG = 'cache:local:proConfig'; export const CACHE_LOCAL_PROCONFIG = 'cache:local:proConfig';

View File

@@ -19,6 +19,18 @@ export const RESULT_MSG_SUCCESS: Record<string, string> = {
/**响应-code错误失败 */ /**响应-code错误失败 */
export const RESULT_CODE_ERROR = 400001; export const RESULT_CODE_ERROR = 400001;
/**响应-code身份认证失败或者过期 */
export const RESULT_CODE_AUTH = 401001;
/**响应-code无效身份信息 */
export const RESULT_CODE_AUTH_INVALID = 401002;
/**响应-code令牌字符为空 */
export const RESULT_CODE_AUTH_NOTOKEN = 401003;
/**响应-code设备指纹信息不匹配 */
export const RESULT_CODE_AUTH_DEVICE = 401004;
/**响应-code错误异常 */ /**响应-code错误异常 */
export const RESULT_CODE_EXCEPTION = 500001; export const RESULT_CODE_EXCEPTION = 500001;

View File

@@ -877,6 +877,10 @@ export default {
rfspTip:'RFSP index, in NG-RAN, the index of a specific RRM configuration, parameter between 0 and 127', rfspTip:'RFSP index, in NG-RAN, the index of a specific RRM configuration, parameter between 0 and 127',
ueTypeTip: 'Operator-defined subscriber UE Usage Type, integer, parameter between 0 and 127', ueTypeTip: 'Operator-defined subscriber UE Usage Type, integer, parameter between 0 and 127',
cnFlag: 'Whether to enable 5G Core Network service', cnFlag: 'Whether to enable 5G Core Network service',
cnFlag0: 'No Access Allowed',
cnFlag1: 'Access Only 5G',
cnFlag2: 'Access Only 4G',
cnFlag3: 'Access 4G/5G',
epsFlagTip: 'Whether to enable 4G EPS service', epsFlagTip: 'Whether to enable 4G EPS service',
contextIdTip: 'To sign up for an APN Context ID, you must select it from the APN Context list.', contextIdTip: 'To sign up for an APN Context ID, you must select it from the APN Context list.',
apnContextTip: 'The list of APNs available to the phone, up to six, is defined in the HSS.', apnContextTip: 'The list of APNs available to the phone, up to six, is defined in the HSS.',

View File

@@ -877,6 +877,10 @@ export default {
rfspTip:'RFSP 索引,在 NG-RAN 中,特定 RRM 配置的索引,参数介于0到127之间', rfspTip:'RFSP 索引,在 NG-RAN 中,特定 RRM 配置的索引,参数介于0到127之间',
ueTypeTip: '运营商定义的用户 UE Usage Type整型参数介于0到127之间', ueTypeTip: '运营商定义的用户 UE Usage Type整型参数介于0到127之间',
cnFlag: '是否开启 5G Core Network 服务', cnFlag: '是否开启 5G Core Network 服务',
cnFlag0: '不允许接入',
cnFlag1: '只能接入 5G',
cnFlag2: '只能接入 4G',
cnFlag3: '允许接入 4G/5G',
epsFlagTip: '是否开启 4G EPS 服务', epsFlagTip: '是否开启 4G EPS 服务',
contextIdTip: '签约APN 上下文ID必须从APN Context list 中选择。', contextIdTip: '签约APN 上下文ID必须从APN Context list 中选择。',
apnContextTip: '手机可用的APN列表最多六个在HSS中定义。', apnContextTip: '手机可用的APN列表最多六个在HSS中定义。',

View File

@@ -5,8 +5,9 @@ import {
clearMenuItem, clearMenuItem,
MenuDataItem, MenuDataItem,
} from 'antdv-pro-layout'; } from 'antdv-pro-layout';
import RightContent from './components/RightContent.vue'; import HeaderContentRight from './components/HeaderContentRight/HeaderContentRight.vue';
import Tabs from './components/Tabs.vue'; import Tabs from './components/Tabs.vue';
import CoreSelect from './components/CoreSelect.vue';
import GlobalMask from '@/components/GlobalMask/index.vue'; import GlobalMask from '@/components/GlobalMask/index.vue';
import ForcePasswdChange from '@/components/ForcePasswdChange/index.vue'; import ForcePasswdChange from '@/components/ForcePasswdChange/index.vue';
import { scriptUrl } from '@/assets/js/icon_font_8d5l8fzk5b87iudi'; import { scriptUrl } from '@/assets/js/icon_font_8d5l8fzk5b87iudi';
@@ -21,7 +22,8 @@ import {
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import useLayoutStore from '@/store/modules/layout'; import useLayoutStore from '@/store/modules/layout';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import useNeListStore from '@/store/modules/ne_list'; import useCoreStore from '@/store/modules/core';
import useNeStore from '@/store/modules/ne';
import useRouterStore from '@/store/modules/router'; import useRouterStore from '@/store/modules/router';
import useTabsStore from '@/store/modules/tabs'; import useTabsStore from '@/store/modules/tabs';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
@@ -34,7 +36,6 @@ import { parseUrlPath } from '@/plugins/file-static-url';
const { proConfig, waterMarkContent } = useLayoutStore(); const { proConfig, waterMarkContent } = useLayoutStore();
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();
const routerStore = useRouterStore(); const routerStore = useRouterStore();
const neListStore = useNeListStore();
const tabsStore = useTabsStore(); const tabsStore = useTabsStore();
const appStore = useAppStore(); const appStore = useAppStore();
const router = useRouter(); const router = useRouter();
@@ -68,19 +69,6 @@ watch(
); );
// 动态路由添加到菜单面板 // 动态路由添加到菜单面板
// const rootRoute = router.getRoutes().find(r => r.name === 'Root');
// if (rootRoute) {
// const children = routerStore.setRootRouterData(rootRoute.children);
// const buildRouterData = routerStore.buildRouterData;
// if (buildRouterData.length > 0) {
// rootRoute.children = children.concat(buildRouterData);
// } else {
// rootRoute.children = children;
// }
// }
//
// const { menuData } = getMenuData(clearMenuItem(router.getRoutes()));
//
const menuData = computed(() => { const menuData = computed(() => {
const rootRoute = router.getRoutes().find(r => r.name === 'Root'); const rootRoute = router.getRoutes().find(r => r.name === 'Root');
if (rootRoute) { if (rootRoute) {
@@ -92,9 +80,12 @@ const menuData = computed(() => {
rootRoute.children = children; rootRoute.children = children;
} }
} }
const neTypes = neListStore.getNeSelectOtions.map(v => v.value);
let routes = clearMenuItem(router.getRoutes()); let routes = clearMenuItem(router.getRoutes());
routes = routerStore.clearMenuItemByNeList(routes, neTypes); const coreUid = useCoreStore().getCurrentCoreUid;
const neTypes = useNeStore()
.fnNeSelectOtions(coreUid)
.map(v => v.value);
routes = routerStore.clearMenuItemByNeList(routes, coreUid, neTypes);
const { menuData } = getMenuData(routes); const { menuData } = getMenuData(routes);
return menuData; return menuData;
}); });
@@ -151,10 +142,13 @@ tabsStore.clear();
// LOGO地址 // LOGO地址
const logoUrl = computed(() => { const logoUrl = computed(() => {
let url = let url = parseUrlPath(appStore.filePathIcon);
appStore.logoType === 'brand' if (appStore.logoType === 'brand') {
? parseUrlPath(appStore.filePathBrand) url = parseUrlPath(appStore.filePathBrand);
: parseUrlPath(appStore.filePathIcon); }
if (layoutState.collapsed) {
url = parseUrlPath(appStore.filePathIcon);
}
if (url.indexOf('{language}') === -1) { if (url.indexOf('{language}') === -1) {
return url; return url;
@@ -275,6 +269,7 @@ onUnmounted(() => {
v-model:openKeys="layoutState.openKeys" v-model:openKeys="layoutState.openKeys"
:menu-data="menuData" :menu-data="menuData"
:breadcrumb="{ routes: breadcrumb }" :breadcrumb="{ routes: breadcrumb }"
:siderWidth="248"
v-bind="proConfig" v-bind="proConfig"
:iconfont-url="scriptUrl" :iconfont-url="scriptUrl"
:locale="fnLocale" :locale="fnLocale"
@@ -294,13 +289,17 @@ onUnmounted(() => {
:alt="appStore.appName" :alt="appStore.appName"
:title="appStore.appName" :title="appStore.appName"
/> />
<h1 class="app-name" :title="appStore.appName"> <h1
class="app-name"
:title="appStore.appName"
v-show="!layoutState.collapsed"
>
<span class="marquee app-name_scrollable"> <span class="marquee app-name_scrollable">
{{ appStore.appName }} {{ appStore.appName }}
</span> </span>
</h1> </h1>
</template> </template>
<template v-if="appStore.logoType === 'brand'"> <template v-else-if="appStore.logoType === 'brand'">
<img <img
class="logo-brand" class="logo-brand"
:src="logoUrl" :src="logoUrl"
@@ -314,9 +313,14 @@ onUnmounted(() => {
<!--插槽-渲染顶部内容区域仅布局side有效--> <!--插槽-渲染顶部内容区域仅布局side有效-->
<template #headerContentRender></template> <template #headerContentRender></template>
<!--插槽-渲染顶部内容区域仅布局side有效-->
<template #menuHeaderExtraRender>
<CoreSelect></CoreSelect>
</template>
<!--插槽-渲染顶部内容右端区域--> <!--插槽-渲染顶部内容右端区域-->
<template #headerContentRightRender> <template #headerContentRightRender>
<RightContent /> <HeaderContentRight />
</template> </template>
<!--插槽-导航标签项--> <!--插槽-导航标签项-->

View File

@@ -0,0 +1,78 @@
<script lang="ts" setup>
import useCoreStore from '@/store/modules/core';
import useI18n from '@/hooks/useI18n';
import { ref } from 'vue';
const coreStore = useCoreStore();
const { t } = useI18n();
/**当前选中 */
const coreValue = ref(
coreStore.current?.value == 'all' ? 'Global' : coreStore.current?.value
);
/**选择列表数据 */
const coreOtions = ref(coreStore.getSelectOtions);
/**选择过滤名称 */
const coreName = ref();
/**选择 */
function handleSelect(v: any, item: any) {
if (v === 'all') {
coreValue.value = 'Global';
} else {
coreValue.value = v;
}
coreStore.setCurrent(item);
}
/**搜索过滤 */
function handleSearchFilter(e: any) {
const label = e.target.value;
coreOtions.value = coreStore.getSelectOtions.filter((item: any) => {
return item.label.indexOf(label) !== -1;
});
}
/**内容挂载DOM */
function getPopupContainer(): any {
return document.querySelector('.ant-pro-sider');
}
</script>
<template>
<a-select
v-model:value="coreValue"
:options="coreOtions"
style="width: 100%"
:getPopupContainer="getPopupContainer"
@change="handleSelect"
>
<template #option="{ label }">
<span>{{ label }}</span>
</template>
<template #dropdownRender="{ menuNode: menu }">
<strong>Core</strong>
<a-button
type="default"
:block="true"
@click="handleSelect('all', { label: 'Global', value: 'all' })"
>
<template #icon> <HomeOutlined /> </template>
Global
</a-button>
<a-input-search
placeholder="Search Core Name"
style="width: 100%; margin: 4px 0"
v-model:value="coreName"
@change="handleSearchFilter"
>
<template #enterButton>
<ReloadOutlined />
</template>
</a-input-search>
<a-divider style="margin: 4px 0" />
<component :is="menu" />
</template>
</a-select>
</template>
<style lang="css" scoped></style>

View File

@@ -0,0 +1,120 @@
<script setup lang="ts">
import svgLight from '@/assets/svg/light.svg';
import svgDark from '@/assets/svg/dark.svg';
import { viewTransitionTheme } from 'antdv-pro-layout';
import { useRouter } from 'vue-router';
import { useFullscreen } from '@vueuse/core';
import { hasPermissions } from '@/plugins/auth-user';
import useI18n from '@/hooks/useI18n';
import useLayoutStore from '@/store/modules/layout';
import useAppStore from '@/store/modules/app';
import useAlarmStore from '@/store/modules/alarm';
import LockScreen from './components/LockScreen.vue';
import UserProfile from './components/UserProfile.vue';
const { isFullscreen, toggle } = useFullscreen();
const { t, changeLocale, optionsLocale, currentLocale } = useI18n();
const layoutStore = useLayoutStore();
const appStore = useAppStore();
const router = useRouter();
/**告警数按钮提示跳转 */
function fnClickAlarm() {
router.push({ name: 'ActiveAlarm_2088' });
}
/**改变主题色 */
function fnClickTheme(e: any) {
viewTransitionTheme(isDarkMode => {
layoutStore.changeConf('theme', isDarkMode ? 'light' : 'dark');
}, e);
}
/**改变多语言 */
function fnChangeLocale(e: any) {
changeLocale(e.key);
}
</script>
<template>
<a-space :size="12" align="center">
<!-- 告警气泡 -->
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.alarm') }}</template>
<a-button type="text" style="color: inherit" @click="fnClickAlarm">
<template #icon>
<a-badge
:count="useAlarmStore().activeAlarmTotal"
:overflow-count="99"
status="warning"
style="color: inherit"
>
<BellOutlined />
</a-badge>
</template>
</a-button>
</a-tooltip>
<!-- 锁屏操作 -->
<LockScreen></LockScreen>
<!-- 全屏操作 -->
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.fullscreen') }}</template>
<a-button type="text" style="color: inherit" @click="toggle">
<template #icon>
<FullscreenExitOutlined v-if="isFullscreen" />
<FullscreenOutlined v-else />
</template>
</a-button>
</a-tooltip>
<!-- 明暗主题操作 -->
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.theme') }}</template>
<a-button type="text" @click="fnClickTheme">
<template #icon>
<img
v-if="layoutStore.proConfig.theme === 'dark'"
:src="svgDark"
class="theme-icon"
/>
<img v-else :src="svgLight" class="theme-icon" />
</template>
</a-button>
</a-tooltip>
<!-- 多语言操作 -->
<a-dropdown
placement="bottomRight"
trigger="click"
v-if="appStore.i18nOpen && hasPermissions(['system:setting:i18n'])"
>
<a-button type="text" style="color: inherit">
<template #icon> <TranslationOutlined /> </template>
</a-button>
<template #overlay>
<a-menu @click="fnChangeLocale">
<a-menu-item
v-for="opt in optionsLocale"
:key="opt.value"
:disabled="opt.value == currentLocale"
>
{{ opt.label }}
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<!-- 用户信息操作 -->
<UserProfile></UserProfile>
</a-space>
</template>
<style lang="css" scoped>
.theme-icon {
width: 18px;
height: 18px;
margin-bottom: 4px;
color: inherit;
}
</style>

View File

@@ -0,0 +1,71 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ProModal } from 'antdv-pro-modal';
import useMaskStore from '@/store/modules/mask';
import useI18n from '@/hooks/useI18n';
const maskStore = useMaskStore();
const route = useRoute();
const router = useRouter();
const { t } = useI18n();
/**锁屏确认 */
const lockConfirm = ref<boolean>(false);
/**锁屏密码 */
const lockPasswd = ref<string>('');
/**锁屏按钮提示 */
function fnClickLock() {
lockConfirm.value = true;
lockPasswd.value = '';
maskStore.lockPasswd = '';
}
/**锁屏确认跳转锁屏页面 */
function fnClickLockToPage() {
lockConfirm.value = false;
maskStore.lockPasswd = lockPasswd.value;
maskStore.handleMaskType('lock');
router.push({ name: 'LockScreen', query: { redirect: route.path } });
}
</script>
<template>
<span v-perms:has="['system:setting:lock']">
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
<a-button type="text" style="color: inherit" @click="fnClickLock()">
<template #icon>
<LockOutlined />
</template>
</a-button>
<ProModal
:drag="true"
:center-y="true"
:width="400"
:minHeight="200"
:mask-closable="false"
v-model:open="lockConfirm"
:title="t('loayouts.rightContent.lockTip')"
@ok="fnClickLockToPage()"
>
<a-space>
{{ t('loayouts.rightContent.lockPasswd') }}
<a-input-password
v-model:value="lockPasswd"
:placeholder="t('common.inputPlease')"
>
<template #prefix>
<a-tooltip
:title="t('loayouts.rightContent.lockPasswdTip')"
placement="topLeft"
>
<UnlockOutlined />
</a-tooltip>
</template>
</a-input-password>
</a-space>
</ProModal>
</a-tooltip>
</span>
</template>

View File

@@ -0,0 +1,83 @@
<script lang="ts" setup>
import { useRouter } from 'vue-router';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import useUserStore from '@/store/modules/user';
import useI18n from '@/hooks/useI18n';
const userStore = useUserStore();
const router = useRouter();
const { t } = useI18n();
/**头像展开项点击 */
function fnClick({ key }: MenuInfo) {
switch (key) {
case 'settings':
router.push({ name: 'Settings' });
break;
case 'profile':
router.push({ name: 'Profile' });
break;
case 'logout':
userStore.fnLogOut().finally(() => router.push({ name: 'Login' }));
break;
}
}
</script>
<template>
<a-dropdown placement="bottomRight" trigger="click">
<div class="user">
<a-avatar
shape="circle"
size="default"
:src="userStore.getAvatar"
:alt="userStore.userName"
></a-avatar>
<span class="nick">
{{ userStore.nickName }}
</span>
</div>
<template #overlay>
<a-menu @click="fnClick">
<!-- <a-menu-item key="profile">
<template #icon>
<UserOutlined />
</template>
<span>{{ t('loayouts.rightContent.profile') }}</span>
</a-menu-item> -->
<a-menu-item key="settings">
<template #icon>
<SettingOutlined />
</template>
<span>{{ t('loayouts.rightContent.settings') }}</span>
</a-menu-item>
<a-menu-divider />
<a-menu-item key="logout">
<template #icon>
<LogoutOutlined />
</template>
<span>{{ t('loayouts.rightContent.logout') }}</span>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
<style lang="less" scoped>
.user {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
cursor: pointer;
.nick {
padding-left: 8px;
padding-right: 16px;
font-size: 16px;
max-width: 164px;
white-space: nowrap;
text-align: start;
text-overflow: ellipsis;
overflow: hidden;
}
}
</style>

View File

@@ -1,241 +0,0 @@
<script setup lang="ts">
import svgLight from '@/assets/svg/light.svg';
import svgDark from '@/assets/svg/dark.svg';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { viewTransitionTheme } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useFullscreen } from '@vueuse/core';
import { hasPermissions } from '@/plugins/auth-user';
import useI18n from '@/hooks/useI18n';
import useLayoutStore from '@/store/modules/layout';
import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user';
import useAlarmStore from '@/store/modules/alarm';
import useMaskStore from '@/store/modules/mask';
const { isFullscreen, toggle } = useFullscreen();
const { t, changeLocale, optionsLocale } = useI18n();
const layoutStore = useLayoutStore();
const maskStore = useMaskStore();
const userStore = useUserStore();
const appStore = useAppStore();
const route = useRoute();
const router = useRouter();
/**头像展开项点击 */
function fnClick({ key }: MenuInfo) {
switch (key) {
case 'settings':
router.push({ name: 'Settings' });
break;
case 'profile':
router.push({ name: 'Profile' });
break;
case 'logout':
userStore.fnLogOut().finally(() => router.push({ name: 'Login' }));
break;
}
}
/**锁屏确认 */
const lockConfirm = ref<boolean>(false);
/**锁屏密码 */
const lockPasswd = ref<string>('');
/**锁屏按钮提示 */
function fnClickLock() {
lockConfirm.value = true;
lockPasswd.value = '';
maskStore.lockPasswd = '';
}
/**锁屏确认跳转锁屏页面 */
function fnClickLockToPage() {
lockConfirm.value = false;
maskStore.lockPasswd = lockPasswd.value;
maskStore.handleMaskType('lock');
router.push({ name: 'LockScreen', query: { redirect: route.path } });
}
/**告警数按钮提示跳转 */
function fnClickAlarm() {
router.push({ name: 'ActiveAlarm_2088' });
}
/**改变主题色 */
function fnClickTheme(e: any) {
viewTransitionTheme(isDarkMode => {
layoutStore.changeConf('theme', isDarkMode ? 'light' : 'dark');
}, e);
}
/**改变多语言 */
function fnChangeLocale(e: any) {
changeLocale(e.key);
}
</script>
<template>
<a-space :size="12" align="center">
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.alarm') }}</template>
<a-button type="text" style="color: inherit" @click="fnClickAlarm">
<template #icon>
<a-badge
:count="useAlarmStore().activeAlarmTotal"
:overflow-count="99"
status="warning"
style="color: inherit"
>
<BellOutlined />
</a-badge>
</template>
</a-button>
</a-tooltip>
<!-- 锁屏操作 -->
<span v-perms:has="['system:setting:lock']">
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
<a-button type="text" style="color: inherit" @click="fnClickLock()">
<template #icon>
<LockOutlined />
</template>
</a-button>
<ProModal
:drag="true"
:center-y="true"
:width="400"
:minHeight="200"
:mask-closable="false"
v-model:open="lockConfirm"
:title="t('loayouts.rightContent.lockTip')"
@ok="fnClickLockToPage()"
>
<a-space>
{{ t('loayouts.rightContent.lockPasswd') }}
<a-input-password
v-model:value="lockPasswd"
:placeholder="t('common.inputPlease')"
>
<template #prefix>
<a-tooltip
:title="t('loayouts.rightContent.lockPasswdTip')"
placement="topLeft"
>
<UnlockOutlined />
</a-tooltip>
</template>
</a-input-password>
</a-space>
</ProModal>
</a-tooltip>
</span>
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.fullscreen') }}</template>
<a-button type="text" style="color: inherit" @click="toggle">
<template #icon>
<FullscreenExitOutlined v-if="isFullscreen" />
<FullscreenOutlined v-else />
</template>
</a-button>
</a-tooltip>
<a-tooltip placement="bottomRight">
<template #title>{{ t('loayouts.rightContent.theme') }}</template>
<a-button type="text" @click="fnClickTheme">
<template #icon>
<img
v-if="layoutStore.proConfig.theme === 'dark'"
:src="svgDark"
class="theme-icon"
/>
<img v-else :src="svgLight" class="theme-icon" />
</template>
</a-button>
</a-tooltip>
<a-dropdown
placement="bottomRight"
trigger="click"
v-if="appStore.i18nOpen && hasPermissions(['system:setting:i18n'])"
>
<a-button type="text" style="color: inherit">
<template #icon> <TranslationOutlined /> </template>
</a-button>
<template #overlay>
<a-menu @click="fnChangeLocale">
<a-menu-item v-for="opt in optionsLocale" :key="opt.value">
{{ opt.label }}
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<a-dropdown placement="bottomRight" trigger="click">
<div class="user">
<a-avatar
shape="circle"
size="default"
:src="userStore.getAvatar"
:alt="userStore.userName"
></a-avatar>
<span class="nick">
{{ userStore.nickName }}
</span>
</div>
<template #overlay>
<a-menu @click="fnClick">
<!-- <a-menu-item key="profile">
<template #icon>
<UserOutlined />
</template>
<span>{{ t('loayouts.rightContent.profile') }}</span>
</a-menu-item> -->
<a-menu-item key="settings">
<template #icon>
<SettingOutlined />
</template>
<span>{{ t('loayouts.rightContent.settings') }}</span>
</a-menu-item>
<a-menu-divider />
<a-menu-item key="logout">
<template #icon>
<LogoutOutlined />
</template>
<span>{{ t('loayouts.rightContent.logout') }}</span>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-space>
</template>
<style lang="less" scoped>
.user {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
cursor: pointer;
.nick {
padding-left: 8px;
padding-right: 16px;
font-size: 16px;
max-width: 164px;
white-space: nowrap;
text-align: start;
text-overflow: ellipsis;
overflow: hidden;
}
}
.theme-icon {
width: 18px;
height: 18px;
margin-bottom: 4px;
color: inherit;
}
</style>

View File

@@ -22,6 +22,10 @@ import {
APP_DATA_API_KEY, APP_DATA_API_KEY,
} from '@/constants/app-constants'; } from '@/constants/app-constants';
import { import {
RESULT_CODE_AUTH,
RESULT_CODE_AUTH_DEVICE,
RESULT_CODE_AUTH_INVALID,
RESULT_CODE_AUTH_NOTOKEN,
RESULT_CODE_ENCRYPT, RESULT_CODE_ENCRYPT,
RESULT_CODE_ERROR, RESULT_CODE_ERROR,
RESULT_CODE_EXCEPTION, RESULT_CODE_EXCEPTION,
@@ -34,7 +38,7 @@ import {
RESULT_MSG_TIMEOUT, RESULT_MSG_TIMEOUT,
RESULT_MSG_URL_RESUBMIT, RESULT_MSG_URL_RESUBMIT,
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import { decryptAES, encryptAES } from '@/utils/encrypt-utils'; import { decryptAES, encryptAES, hexMD5 } from '@/utils/encrypt-utils';
import { localGet } from '@/utils/cache-local-utils'; import { localGet } from '@/utils/cache-local-utils';
import { refreshToken } from '@/api/auth'; import { refreshToken } from '@/api/auth';
@@ -52,9 +56,7 @@ export type ResultType = {
/**防止重复提交类型 */ /**防止重复提交类型 */
type RepeatSubmitType = { type RepeatSubmitType = {
/**请求地址 */ /**请求数据MD5 */
url: string;
/**请求数据 */
data: string; data: string;
/**请求时间 */ /**请求时间 */
time: number; time: number;
@@ -158,19 +160,19 @@ function beforeRequest(options: OptionsType): OptionsType | Promise<any> {
['POST', 'PUT'].includes(options.method) ['POST', 'PUT'].includes(options.method)
) { ) {
const requestObj: RepeatSubmitType = { const requestObj: RepeatSubmitType = {
url: options.url, data: hexMD5(
data: JSON.stringify(options.data) || '', JSON.stringify({
url: options.url,
data: JSON.stringify(options.data) || '',
})
),
time: Date.now(), time: Date.now(),
}; };
const sessionObj: RepeatSubmitType = sessionGetJSON(CACHE_SESSION_FATCH); const sessionObj: RepeatSubmitType = sessionGetJSON(CACHE_SESSION_FATCH);
if (sessionObj) { if (sessionObj) {
const { url, data, time } = sessionObj; const { data, time } = sessionObj;
const interval = 3000; // 间隔时间(ms),小于此时间视为重复提交 const interval = 3000; // 间隔时间(ms),小于此时间视为重复提交
if ( if (requestObj.data === data && requestObj.time - time < interval) {
requestObj.url === url &&
requestObj.data === data &&
requestObj.time - time < interval
) {
const message = RESULT_MSG_URL_RESUBMIT[language]; const message = RESULT_MSG_URL_RESUBMIT[language];
return Promise.resolve({ return Promise.resolve({
code: RESULT_CODE_ERROR, code: RESULT_CODE_ERROR,
@@ -232,27 +234,33 @@ async function beforeResponse(
): Promise<any> { ): Promise<any> {
// console.log('请求后的拦截', res); // console.log('请求后的拦截', res);
// 登录失效时,移除授权令牌并重新刷新页面 // 移除授权令牌并重新刷新页面
// 登录失效时,移除访问令牌并重新请求 function clearToken() {
if (res.code === 401001) { delAccessToken();
const result = await refreshToken(getRefreshToken()); delRefreshToken();
window.location.reload();
}
// 令牌失效时
if (res.code === RESULT_CODE_AUTH) {
const refreshTokenStr = getRefreshToken();
if (!refreshTokenStr) {
clearToken();
}
const result = await refreshToken(refreshTokenStr);
// 更新访问令牌和刷新令牌 // 更新访问令牌和刷新令牌
if (result.code === RESULT_CODE_SUCCESS) { if (result.code === RESULT_CODE_SUCCESS) {
setAccessToken(result.data.accessToken, result.data.refreshExpiresIn); setAccessToken(result.data.accessToken, result.data.refreshExpiresIn);
setRefreshToken(result.data.refreshToken, result.data.refreshExpiresIn); setRefreshToken(result.data.refreshToken, result.data.refreshExpiresIn);
return await request(options); return await request(options);
} else if (result.code === RESULT_CODE_AUTH_DEVICE) {
clearToken();
} else { } else {
debugger // clearToken();
console.warn(result)
// delAccessToken();
// delRefreshToken();
window.location.reload();
} }
} }
if ([401002, 401003].includes(res.code)) { // 令牌解析错误
delAccessToken(); if ([RESULT_CODE_AUTH_INVALID, RESULT_CODE_AUTH_NOTOKEN].includes(res.code)) {
delRefreshToken(); clearToken();
window.location.reload();
} }
// 响应数据解密 // 响应数据解密

View File

@@ -10,7 +10,8 @@ import { getAccessToken } from '@/plugins/auth-token';
import { validHttp } from '@/utils/regular-utils'; import { validHttp } from '@/utils/regular-utils';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import useNeListStore from '@/store/modules/ne_list'; import useCoreStore from '@/store/modules/core';
import useNeStore from '@/store/modules/ne';
import useRouterStore from '@/store/modules/router'; import useRouterStore from '@/store/modules/router';
// NProgress Configuration // NProgress Configuration
@@ -103,8 +104,11 @@ router.beforeEach(async (to, from, next) => {
const user = useUserStore(); const user = useUserStore();
if (user.roles && user.roles.length === 0) { if (user.roles && user.roles.length === 0) {
try { try {
// 获取核心网列表
await useCoreStore().fnCorelist();
// 获取网元信息 // 获取网元信息
await useNeListStore().fnNelist(); await useNeStore().fnNelist();
// 获取用户信息 // 获取用户信息
await user.fnGetInfo(); await user.fnGetInfo();
// 获取路由信息 // 获取路由信息
@@ -128,7 +132,7 @@ router.beforeEach(async (to, from, next) => {
} else if ( } else if (
to.meta.neType && to.meta.neType &&
to.meta.neType.length > 0 && to.meta.neType.length > 0 &&
!useNeListStore().fnHasNe(to.meta.neType) !useNeStore().fnHasNe(to.meta.neType)
) { ) {
next({ name: 'NotPermission' }); next({ name: 'NotPermission' });
} else { } else {

77
src/store/modules/core.ts Normal file
View File

@@ -0,0 +1,77 @@
import {
RESULT_CODE_SUCCESS,
RESULT_MSG_SUCCESS,
} from '@/constants/result-constants';
import { defineStore } from 'pinia';
import { listAllCoreInfo } from '@/api/core/coreInfo';
import { localGetJSON, localSetJSON } from '@/utils/cache-local-utils';
import { CACHE_SESSION_CORE } from '@/constants/cache-keys-constants';
/**核心网信息类型 */
type Core = {
/**核心网列表 */
coreList: Record<string, any>[];
/**当前选择 */
current: Record<string, any>;
/**选择器单级父类型 */
coreSelectOtions: Record<string, any>[];
};
const useCoreStore = defineStore('core', {
state: (): Core => ({
coreList: [],
current: localGetJSON(CACHE_SESSION_CORE) || {
label: 'Global',
value: 'all',
},
coreSelectOtions: [],
}),
getters: {
/**当前核心网Uid */
getCurrentCoreUid(): string {
return this.current.value;
},
/**选择器 */
getSelectOtions(): Record<string, any>[] {
return this.coreSelectOtions;
},
},
actions: {
setCurrent(value: Record<string, any> = {}) {
this.current = value;
localSetJSON(CACHE_SESSION_CORE, value);
},
// 刷新核心网列表
async fnCorelistRefresh() {
this.coreList = [];
return await this.fnCorelist();
},
// 获取核心网列表
async fnCorelist() {
// 有数据不请求
if (this.coreList.length > 0) {
return {
code: RESULT_CODE_SUCCESS,
msg: RESULT_MSG_SUCCESS['en_US'],
data: this.coreList,
};
}
const res = await listAllCoreInfo({});
if (res.code === RESULT_CODE_SUCCESS) {
// 原始列表
this.coreList = JSON.parse(JSON.stringify(res.data));
// 转选择器单级父类型
this.coreSelectOtions = res.data.map((item: any) => {
return {
label: item.name,
value: item.coreUid,
};
});
}
return res;
},
},
});
export default useCoreStore;

View File

@@ -70,9 +70,9 @@ const proRender = (render: any) => (render === false ? false : undefined);
const proConfigLocal: LayoutStore['proConfig'] = localGetJSON( const proConfigLocal: LayoutStore['proConfig'] = localGetJSON(
CACHE_LOCAL_PROCONFIG CACHE_LOCAL_PROCONFIG
) || { ) || {
layout: 'mix', layout: 'side',
theme: 'light', theme: 'light',
menuTheme: 'light', menuTheme: 'dark',
fixSiderbar: true, fixSiderbar: true,
fixedHeader: true, fixedHeader: true,
splitMenus: true, splitMenus: true,

View File

@@ -11,16 +11,16 @@ type NeList = {
/**网元列表 */ /**网元列表 */
neList: Record<string, any>[]; neList: Record<string, any>[];
/**级联options树结构 */ /**级联options树结构 */
neCascaderOptions: Record<string, any>[]; neCascaderOptions: Map<string, Record<string, any>[]>;
/**选择器单级父类型 */ /**选择器单级父类型 */
neSelectOtions: Record<string, any>[]; neSelectOtions: Map<string, Record<string, any>[]>;
}; };
const useNeListStore = defineStore('ne_list', { const useNeStore = defineStore('ne_list', {
state: (): NeList => ({ state: (): NeList => ({
neList: [], neList: [],
neCascaderOptions: [], neCascaderOptions: new Map(),
neSelectOtions: [], neSelectOtions: new Map(),
}), }),
getters: { getters: {
/** /**
@@ -72,33 +72,71 @@ const useNeListStore = defineStore('ne_list', {
// 原始列表 // 原始列表
this.neList = JSON.parse(JSON.stringify(res.data)); this.neList = JSON.parse(JSON.stringify(res.data));
// 转级联数据
const options = parseDataToOptions( const options = parseDataToOptions(
res.data, res.data,
'neType', 'neType',
'neName', 'neName',
'neId' 'neUid'
); );
this.neCascaderOptions = options;
// 转选择器单级父类型 for (const item of options) {
this.neSelectOtions = options.map(item => { const k = item.coreUid;
return { // 转级联数据
let cascaderMap = this.neCascaderOptions.get(k);
if (cascaderMap) {
cascaderMap.push(item);
} else {
cascaderMap = [item];
}
this.neCascaderOptions.set(k, cascaderMap);
// 转选择器单级父类型
let selectMap = this.neSelectOtions.get(k);
const selectItem = {
label: item.label, label: item.label,
value: item.value, value: item.value,
}; };
}); if (selectMap) {
selectMap.push(selectItem);
} else {
selectMap = [selectItem];
}
this.neSelectOtions.set(k, selectMap);
}
} }
return res; return res;
}, },
/**
* options树结构
* @param coreUid uid
*/
fnNeCascaderOptions(coreUid: string) {
const m = this.neCascaderOptions.get(coreUid);
if (!m) {
return [];
}
return m;
},
/**
*
* @param coreUid uid
*/
fnNeSelectOtions(coreUid: string) {
const m = this.neSelectOtions.get(coreUid);
if (!m) {
return [];
}
return m;
},
/** /**
* *
* @param coreUid uid
* @param metaNeType ['udm', 'ims', 'udm+ims', 'SGWC'] * @param metaNeType ['udm', 'ims', 'udm+ims', 'SGWC']
* @returns boolean * @returns boolean
*/ */
fnHasNe(metaNeType: string[]) { fnHasNe(coreUid: string, metaNeType: string[]) {
if (this.neList.length > 0) { if (this.neList.length > 0) {
const neTypes = this.neSelectOtions.map(item => item.value); const neTypes = this.fnNeSelectOtions(coreUid).map(item => item.value);
let match = false; // 匹配 let match = false; // 匹配
for (const netype of metaNeType) { for (const netype of metaNeType) {
if (netype.indexOf('+') > -1) { if (netype.indexOf('+') > -1) {
@@ -120,4 +158,4 @@ const useNeListStore = defineStore('ne_list', {
}, },
}); });
export default useNeListStore; export default useNeStore;

View File

@@ -58,16 +58,28 @@ const useRouterStore = defineStore('router', {
/** /**
* 根据网元类型过滤菜单 * 根据网元类型过滤菜单
* @param routes 经过clearMenuItem(router.getRoutes())处理 * @param routes 经过clearMenuItem(router.getRoutes())处理
* @param coreUid 核心网元uid
* @param neTypes 网元类型 * @param neTypes 网元类型
* @returns 过滤后的菜单 * @returns 过滤后的菜单
*/ */
clearMenuItemByNeList( clearMenuItemByNeList(
routes: RouteRecord[] | RouteRecordRaw[], routes: RouteRecord[] | RouteRecordRaw[],
coreUid: string,
neTypes: string[] neTypes: string[]
): RouteRecordRaw[] { ): RouteRecordRaw[] {
return routes return routes
.map((item: RouteRecord | RouteRecordRaw) => { .map((item: RouteRecord | RouteRecordRaw) => {
const finalItem = { ...item }; const finalItem = { ...item };
// 过滤核心网菜单
if (coreUid.length < 8 && finalItem.meta?.core == true) {
// 全局 网元菜单
return null;
}
if (coreUid.length == 8 && finalItem.meta?.core == false) {
// 核心网 非网元菜单
return null;
}
// 过滤网元类型 // 过滤网元类型
if ( if (
Array.isArray(finalItem.meta?.neType) && Array.isArray(finalItem.meta?.neType) &&
@@ -96,6 +108,7 @@ const useRouterStore = defineStore('router', {
if (finalItem.children && finalItem.children.length > 0) { if (finalItem.children && finalItem.children.length > 0) {
const children = this.clearMenuItemByNeList( const children = this.clearMenuItemByNeList(
finalItem.children, finalItem.children,
coreUid,
neTypes neTypes
); );
// 如果子菜单都被过滤掉了,就不显示 // 如果子菜单都被过滤掉了,就不显示

View File

@@ -9,6 +9,11 @@ declare module 'vue-router' {
permissions?: string[]; permissions?: string[];
/**角色 */ /**角色 */
roles?: string[]; roles?: string[];
/**租户标识 */
tenant?: boolean;
/**核心网标识 */
core?: boolean;
/**网元类型信息 */ /**网元类型信息 */
neType?: string[]; neType?: string[];
} }

View File

@@ -48,3 +48,12 @@ export function decryptAES(ciphertext: string, aeskey: string): string {
} }
return ''; return '';
} }
/**
* MD5 编码
* @param message 字符串信息
* @returns hax码
*/
export function hexMD5(message: string): string {
return CryptoJS.MD5(message).toString(CryptoJS.enc.Hex);
}

View File

@@ -11,7 +11,7 @@ import {
RESULT_CODE_SUCCESS, RESULT_CODE_SUCCESS,
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { listAMFDataUE, delAMFDataUE, exportAMFDataUE } from '@/api/neData/amf'; import { listAMFDataUE, delAMFDataUE, exportAMFDataUE } from '@/api/neData/amf';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { OptionsType, WS } from '@/plugins/ws-websocket'; import { OptionsType, WS } from '@/plugins/ws-websocket';
@@ -22,7 +22,7 @@ import { useClipboard } from '@vueuse/core';
const { copy } = useClipboard({ legacy: true }); const { copy } = useClipboard({ legacy: true });
const { t } = useI18n(); const { t } = useI18n();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const ws = new WS(); const ws = new WS();
const queue = new PQueue({ concurrency: 1, autoStart: true }); const queue = new PQueue({ concurrency: 1, autoStart: true });
/**网元可选 */ /**网元可选 */

View File

@@ -11,7 +11,7 @@ import {
RESULT_CODE_SUCCESS, RESULT_CODE_SUCCESS,
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { import {
delIMSDataCDR, delIMSDataCDR,
exportIMSDataCDR, exportIMSDataCDR,
@@ -26,7 +26,7 @@ import dayjs, { type Dayjs } from 'dayjs';
const { copy } = useClipboard({ legacy: true }); const { copy } = useClipboard({ legacy: true });
const { t } = useI18n(); const { t } = useI18n();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const ws = new WS(); const ws = new WS();
const queue = new PQueue({ concurrency: 1, autoStart: true }); const queue = new PQueue({ concurrency: 1, autoStart: true });

View File

@@ -12,7 +12,7 @@ import {
RESULT_CODE_SUCCESS, RESULT_CODE_SUCCESS,
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { listMMEDataUE, delMMEDataUE, exportMMEDataUE } from '@/api/neData/mme'; import { listMMEDataUE, delMMEDataUE, exportMMEDataUE } from '@/api/neData/mme';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { OptionsType, WS } from '@/plugins/ws-websocket'; import { OptionsType, WS } from '@/plugins/ws-websocket';
@@ -22,7 +22,7 @@ import { useClipboard } from '@vueuse/core';
const { copy } = useClipboard({ legacy: true }); const { copy } = useClipboard({ legacy: true });
const { t } = useI18n(); const { t } = useI18n();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const ws = new WS(); const ws = new WS();
const queue = new PQueue({ concurrency: 1, autoStart: true }); const queue = new PQueue({ concurrency: 1, autoStart: true });

View File

@@ -27,13 +27,13 @@ import useWS from './hooks/useWS';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { upfWhoId } from './hooks/useWS'; import { upfWhoId } from './hooks/useWS';
const router = useRouter(); const router = useRouter();
const appStore = useAppStore(); const appStore = useAppStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
const { wsSend, userActivitySend, upfTFSend, reSendUPF } = useWS(); const { wsSend, userActivitySend, upfTFSend, reSendUPF } = useWS();

View File

@@ -5,7 +5,7 @@ import { Modal, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { import {
RESULT_CODE_ERROR, RESULT_CODE_ERROR,
@@ -23,7 +23,7 @@ import saveAs from 'file-saver';
import { useClipboard } from '@vueuse/core'; import { useClipboard } from '@vueuse/core';
const { copy } = useClipboard({ legacy: true }); const { copy } = useClipboard({ legacy: true });
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const ws = new WS(); const ws = new WS();
const queue = new PQueue({ concurrency: 1, autoStart: true }); const queue = new PQueue({ concurrency: 1, autoStart: true });

View File

@@ -5,7 +5,7 @@ import { Modal, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { import {
RESULT_CODE_ERROR, RESULT_CODE_ERROR,
@@ -23,7 +23,7 @@ import dayjs, { type Dayjs } from 'dayjs';
import { useClipboard } from '@vueuse/core'; import { useClipboard } from '@vueuse/core';
const { copy } = useClipboard({ legacy: true }); const { copy } = useClipboard({ legacy: true });
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const ws = new WS(); const ws = new WS();
const queue = new PQueue({ concurrency: 1, autoStart: true }); const queue = new PQueue({ concurrency: 1, autoStart: true });

View File

@@ -35,10 +35,10 @@ import {
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import { parseSizeFromByte } from '@/utils/parse-utils'; import { parseSizeFromByte } from '@/utils/parse-utils';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import dayjs, { Dayjs } from 'dayjs'; import dayjs, { Dayjs } from 'dayjs';
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const ws = new WS(); const ws = new WS();
/**图DOM节点实例对象 */ /**图DOM节点实例对象 */

View File

@@ -11,7 +11,7 @@ import {
RESULT_CODE_ERROR, RESULT_CODE_ERROR,
RESULT_CODE_SUCCESS, RESULT_CODE_SUCCESS,
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { import {
delSMSCDataCDR, delSMSCDataCDR,
exportSMSCDataCDR, exportSMSCDataCDR,
@@ -26,7 +26,7 @@ import { hasPermissions } from '@/plugins/auth-user';
import dayjs, { type Dayjs } from 'dayjs'; import dayjs, { type Dayjs } from 'dayjs';
const { copy } = useClipboard({ legacy: true }); const { copy } = useClipboard({ legacy: true });
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
const ws = new WS(); const ws = new WS();
const queue = new PQueue({ concurrency: 1, autoStart: true }); const queue = new PQueue({ concurrency: 1, autoStart: true });

View File

@@ -17,7 +17,7 @@ import {
exportAlarm, exportAlarm,
} from '@/api/faultManage/actAlarm'; } from '@/api/faultManage/actAlarm';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
@@ -26,7 +26,7 @@ import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { readLoalXlsx } from '@/utils/execl-utils'; import { readLoalXlsx } from '@/utils/execl-utils';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import dayjs, { type Dayjs } from 'dayjs'; import dayjs, { type Dayjs } from 'dayjs';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();

View File

@@ -8,14 +8,14 @@ import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import { listAct, exportAll } from '@/api/faultManage/eventAlarm'; import { listAct, exportAll } from '@/api/faultManage/eventAlarm';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import { writeSheet } from '@/utils/execl-utils'; import { writeSheet } from '@/utils/execl-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import dayjs, { type Dayjs } from 'dayjs'; import dayjs, { type Dayjs } from 'dayjs';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
/**表格字段列排序 */ /**表格字段列排序 */

View File

@@ -14,13 +14,13 @@ import {
import { listAct, exportAlarm } from '@/api/faultManage/actAlarm'; import { listAct, exportAlarm } from '@/api/faultManage/actAlarm';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
import { writeSheet } from '@/utils/execl-utils'; import { writeSheet } from '@/utils/execl-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import dayjs, { type Dayjs } from 'dayjs'; import dayjs, { type Dayjs } from 'dayjs';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const { t } = useI18n(); const { t } = useI18n();

View File

@@ -7,13 +7,13 @@ import { ColumnsType } from 'ant-design-vue/es/table';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listAlarm } from '@/api/logManage/alarm'; import { listAlarm } from '@/api/logManage/alarm';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import dayjs, { type Dayjs } from 'dayjs'; import dayjs, { type Dayjs } from 'dayjs';
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**字典数据 */ /**字典数据 */
let dict: { let dict: {
/**告警状态 */ /**告警状态 */

View File

@@ -8,13 +8,13 @@ import BackupModal from '@/views/ne/neConfigBackup/components/BackupModal.vue';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
import { delFile, getFile, listFile } from '@/api/tool/file'; import { delFile, getFile, listFile } from '@/api/tool/file';
import { parseSizeFromFile } from '@/utils/parse-utils'; import { parseSizeFromFile } from '@/utils/parse-utils';
import { pushBackupFTP } from '@/api/neData/backup'; import { pushBackupFTP } from '@/api/neData/backup';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**文件来源 */ /**文件来源 */
let sourceState = reactive({ let sourceState = reactive({

View File

@@ -7,13 +7,13 @@ import { ColumnsType } from 'ant-design-vue/es/table';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listForwarding } from '@/api/logManage/forwarding'; import { listForwarding } from '@/api/logManage/forwarding';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import dayjs, { type Dayjs } from 'dayjs'; import dayjs, { type Dayjs } from 'dayjs';
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**字典数据 */ /**字典数据 */
let dict: { let dict: {
/**告警状态 */ /**告警状态 */

View File

@@ -4,13 +4,13 @@ import { PageContainer } from 'antdv-pro-layout';
import { Modal, message } from 'ant-design-vue/es'; import { Modal, message } from 'ant-design-vue/es';
import CodemirrorEdite from '@/components/CodemirrorEdite/index.vue'; import CodemirrorEdite from '@/components/CodemirrorEdite/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils'; import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { getMMLByNE, sendMMlByNE } from '@/api/mmlManage/neOperate'; import { getMMLByNE, sendMMlByNE } from '@/api/mmlManage/neOperate';
import { uploadFileToNE } from '@/api/tool/file'; import { uploadFileToNE } from '@/api/tool/file';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface'; import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
/**网元参数 */ /**网元参数 */

View File

@@ -4,14 +4,14 @@ import { PageContainer } from 'antdv-pro-layout';
import { Modal, message } from 'ant-design-vue/es'; import { Modal, message } from 'ant-design-vue/es';
import CodemirrorEdite from '@/components/CodemirrorEdite/index.vue'; import CodemirrorEdite from '@/components/CodemirrorEdite/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils'; import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { getMMLByOMC, sendMMlByOMC } from '@/api/mmlManage/omcOperate'; import { getMMLByOMC, sendMMlByOMC } from '@/api/mmlManage/omcOperate';
import { uploadFileToNE } from '@/api/tool/file'; import { uploadFileToNE } from '@/api/tool/file';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface'; import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**网元参数 */ /**网元参数 */
let neOptions = ref<Record<string, any>[]>([]); let neOptions = ref<Record<string, any>[]>([]);

View File

@@ -4,14 +4,14 @@ import { PageContainer } from 'antdv-pro-layout';
import { Modal, message } from 'ant-design-vue/es'; import { Modal, message } from 'ant-design-vue/es';
import CodemirrorEdite from '@/components/CodemirrorEdite/index.vue'; import CodemirrorEdite from '@/components/CodemirrorEdite/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils'; import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { getMMLByUDM, sendMMlByUDM } from '@/api/mmlManage/udmOperate'; import { getMMLByUDM, sendMMlByUDM } from '@/api/mmlManage/udmOperate';
import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface'; import { UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface';
import { uploadFileToNE } from '@/api/tool/file'; import { uploadFileToNE } from '@/api/tool/file';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**网元参数 */ /**网元参数 */
let neOptions = ref<Record<string, any>[]>([]); let neOptions = ref<Record<string, any>[]>([]);

View File

@@ -0,0 +1,85 @@
import { delNeConfigData } from '@/api/ne/neConfig';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { message } from 'ant-design-vue';
import { reactive, toRaw } from 'vue';
/**
* 批量删除array
* @param param 父级传入 { t, neTypeSelect, fnActiveConfigNode }
* @returns
*/
export default function useArrayBatch({
t,
neTypeSelect,
fnActiveConfigNode,
}: any) {
/**状态属性 */
const batchState = reactive({
open: false,
loading: false, //批量删除
paramName: '',
startIndex: 1,
num: 1,
});
/**对话框表格信息导入弹出窗口 */
function modalBatchOpen(paramName: string) {
batchState.paramName = paramName;
batchState.open = true;
}
function modalBatchClose() {
if (batchState.loading) {
message.error({
content: 'Delete is in progress, please wait for it to complete',
duration: 3,
});
return;
}
batchState.open = false;
batchState.loading = false;
batchState.startIndex = 1;
batchState.num = 1;
fnActiveConfigNode('#');
}
async function modalBatchOk() {
let okNum = 0;
let failNum = 0;
const endIndex = batchState.startIndex + batchState.num - 1;
for (let i = endIndex; i >= batchState.startIndex; i--) {
const res = await delNeConfigData({
neType: neTypeSelect.value[0],
neId: neTypeSelect.value[1],
paramName: batchState.paramName,
loc: `${i}`,
});
if (res.code === RESULT_CODE_SUCCESS) {
okNum++;
} else {
failNum++;
break;
}
}
if (okNum > 0) {
message.success({
content: `Successfully deleted ${okNum} items`,
duration: 3,
});
}
if (failNum > 0) {
message.error({
content: `Delete failed, please check the index range`,
duration: 3,
});
}
modalBatchClose();
}
return {
batchState,
modalBatchOpen,
modalBatchClose,
modalBatchOk,
};
}

View File

@@ -0,0 +1,205 @@
import { addNeConfigData, editNeConfigData } from '@/api/ne/neConfig';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { readSheet } from '@/utils/execl-utils';
import { message } from 'ant-design-vue';
import { reactive, toRaw } from 'vue';
import saveAs from 'file-saver';
/**
* 导入文件加array
* @param param 父级传入 { t, neTypeSelect, arrayState, fnActiveConfigNode }
* @returns
*/
export default function useArrayImport({
t,
neTypeSelect,
arrayState,
fnActiveConfigNode,
}: any) {
/**网元导入模板解析 */
const m: Record<string, any> = {
AMF: {
imeiWhitelist: {
filename: 'import_amf_imeiWhitelist_template',
fileetx: '.xlsx',
itemKey: 'imeiPrefixValue',
item: (row: Record<string, any>) => {
return {
imeiPrefixValue: row['IMEI Prefix'],
index: 0,
};
},
},
whitelist: {
filename: 'import_amf_whitelist_template',
fileetx: '.xlsx',
itemKey: 'imsiValue',
item: (row: Record<string, any>) => {
return {
imsiValue: row['IMSI Value'],
imeiValue: row['IMEI Value/Prefix'],
index: 0,
};
},
},
},
MME: {
white_list: {
filename: 'import_mme_imeiWhitelist_template',
fileetx: '.xlsx',
itemKey: 'imei',
item: (row: Record<string, any>) => {
return {
imei: row['IMEI'],
index: 0,
};
},
},
},
};
/**状态属性 */
const importState = reactive({
open: false,
msgArr: [] as string[],
loading: false, //开始导入
itemKey: '', // 解析item的key
item: null as any, // 解析item方法
paramName: '',
filename: '',
fileetx: '',
});
/**对话框表格信息导入弹出窗口 */
function modalImportOpen(neType: string, paramName: string) {
const tmpM = m[neType][paramName];
importState.itemKey = tmpM.itemKey;
importState.item = tmpM.item;
importState.paramName = paramName;
importState.filename = tmpM.filename;
importState.fileetx = tmpM.fileetx;
importState.open = true;
}
function modalImportClose() {
if (importState.loading) {
message.error({
content: 'Import is in progress, please wait for it to complete',
duration: 3,
});
return;
}
importState.open = false;
importState.msgArr = [];
importState.loading = false;
fnActiveConfigNode('#');
}
/**对话框表格信息导入上传 */
async function modalImportUpload(file: File) {
const hide = message.loading(t('common.loading'), 0);
const [neType, neId] = neTypeSelect.value;
importState.msgArr = [];
// 获取最大index
let index = 0;
if (arrayState.columnsData.length <= 0) {
index = 0;
} else {
const last = arrayState.columnsData[arrayState.columnsData.length - 1];
index = last.index.value + 1;
}
const reader = new FileReader();
reader.onload = function (e: any) {
const arrayBuffer = e.target.result;
readSheet(arrayBuffer).then(async rows => {
if (rows.length <= 0) {
hide();
message.error({
content: t('views.neData.baseStation.importDataEmpty'),
duration: 3,
});
return;
}
// 开始导入
importState.loading = true;
for (const row of rows) {
const rowItem = importState.item(row);
const rowKey = rowItem[importState.itemKey];
let result: any = null;
// 检查index是否定义
const has = arrayState.columnsData.find(
(item: any) => item[importState.itemKey].value === rowKey
);
if (has) {
// 已定义则更新
rowItem.index = has.index.value;
result = await editNeConfigData({
neType: neType,
neId: neId,
paramName: importState.paramName,
paramData: rowItem,
loc: `${rowItem.index}`,
});
let msg = `index:${rowItem.index} update fail`;
if (result.code === RESULT_CODE_SUCCESS) {
msg = `index:${rowItem.index} update success`;
}
importState.msgArr.push(msg);
} else {
// 未定义则新增
result = await addNeConfigData({
neType: neType,
neId: neId,
paramName: importState.paramName,
paramData: Object.assign(rowItem, { index }),
loc: `${index}`,
});
let msg = `index:${index} add fail`;
if (result.code === RESULT_CODE_SUCCESS) {
msg = `index:${index} add success`;
index += 1;
}
importState.msgArr.push(msg);
}
}
hide();
importState.loading = false;
});
};
reader.onerror = function (e) {
hide();
console.error('reader file error:', e);
};
reader.readAsArrayBuffer(file);
}
/**对话框表格信息导入模板 */
function modalImportTemplate() {
const hide = message.loading(t('common.loading'), 0);
const baseUrl = import.meta.env.VITE_HISTORY_BASE_URL;
const templateUrl = `${
baseUrl.length === 1 && baseUrl.indexOf('/') === 0
? ''
: baseUrl.indexOf('/') === -1
? '/' + baseUrl
: baseUrl
}/neDataImput`;
saveAs(
`${templateUrl}/${importState.filename}${importState.fileetx}`,
`${importState.filename}_${Date.now()}${importState.fileetx}`
);
hide();
}
return {
importState,
modalImportOpen,
modalImportClose,
modalImportUpload,
modalImportTemplate,
};
}

View File

@@ -7,13 +7,15 @@ import { DataNode } from 'ant-design-vue/es/tree';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useOptions from './hooks/useOptions'; import useOptions from './hooks/useOptions';
import useConfigList from './hooks/useConfigList'; import useConfigList from './hooks/useConfigList';
import useConfigArray from './hooks/useConfigArray'; import useConfigArray from './hooks/useConfigArray';
import useConfigArrayChild from './hooks/useConfigArrayChild'; import useConfigArrayChild from './hooks/useConfigArrayChild';
import useArrayImport from './hooks/useArrayImport';
import useArrayBatchDel from './hooks/useArrayBatchDel';
import { getAllNeConfig, getNeConfigData } from '@/api/ne/neConfig'; import { getAllNeConfig, getNeConfigData } from '@/api/ne/neConfig';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
const { ruleVerification, smfByUPFIdLoadData, smfByUPFIdOptions } = useOptions({ const { ruleVerification, smfByUPFIdLoadData, smfByUPFIdOptions } = useOptions({
t, t,
@@ -219,16 +221,26 @@ function fnGetNeConfig() {
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
const arr = []; const arr = [];
for (const item of res.data) { for (const item of res.data) {
// 是否可见
if (!item['visible']) {
item['visible'] = 'public';
} else if (item['visible'] == 'hide') {
continue;
}
// 权限控制
let paramPerms: string[] = []; let paramPerms: string[] = [];
if (item.paramPerms) { if (item.paramPerms) {
paramPerms = item.paramPerms.split(','); paramPerms = item.paramPerms.split(',');
} else { } else {
paramPerms = ['post', 'put', 'delete']; paramPerms = ['post', 'put', 'delete'];
} }
const title = item.paramDisplay;
// 处理字符串开头特殊字符
item.paramDisplay = title.replace(/[└─]+/, '');
arr.push({ arr.push({
...item, ...item,
children: undefined, children: undefined,
title: item.paramDisplay, title: title,
key: item.paramName, key: item.paramName,
paramPerms, paramPerms,
}); });
@@ -362,6 +374,21 @@ const {
arrayEditClose, arrayEditClose,
}); });
const {
importState,
modalImportOpen,
modalImportClose,
modalImportUpload,
modalImportTemplate,
} = useArrayImport({ t, neTypeSelect, arrayState, fnActiveConfigNode });
const { batchState, modalBatchOpen, modalBatchClose, modalBatchOk } =
useArrayBatchDel({
t,
neTypeSelect,
fnActiveConfigNode,
});
onMounted(() => { onMounted(() => {
// 获取网元网元列表 // 获取网元网元列表
neCascaderOptions.value = neListStore.getNeCascaderOptions.filter( neCascaderOptions.value = neListStore.getNeCascaderOptions.filter(
@@ -428,7 +455,7 @@ onMounted(() => {
<a-card <a-card
size="small" size="small"
:bordered="false" :bordered="false"
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }" :body-style="{ maxHeight: '680px', 'overflow-y': 'auto' }"
:loading="treeState.selectLoading" :loading="treeState.selectLoading"
> >
<template #title> <template #title>
@@ -575,9 +602,11 @@ onMounted(() => {
@dblclick="listEdit(record)" @dblclick="listEdit(record)"
> >
<template v-if="record['type'] === 'enum'"> <template v-if="record['type'] === 'enum'">
{{ JSON.parse(record['filter'])[text] || '&nbsp;' }} {{ JSON.parse(record['filter'])[text] }}
</template> </template>
<template v-else>{{ `${text}` || '&nbsp;' }}</template> <template v-else>{{ `${text}` }}</template>
&nbsp;
<!-- 空格占位 -->
<EditOutlined <EditOutlined
class="editable-cell__icon" class="editable-cell__icon"
@click="listEdit(record)" @click="listEdit(record)"
@@ -604,7 +633,7 @@ onMounted(() => {
:size="arrayState.size" :size="arrayState.size"
:pagination="tablePagination" :pagination="tablePagination"
:bordered="true" :bordered="true"
:scroll="{ x: arrayState.columnsDnd.length * 200, y: 480 }" :scroll="{ x: arrayState.columnsDnd.length * 200, y: '500px' }"
@resizeColumn="(w:number, col:any) => (col.width = w)" @resizeColumn="(w:number, col:any) => (col.width = w)"
:show-expand-column="false" :show-expand-column="false"
v-model:expanded-row-keys="arrayState.arrayChildExpandKeys" v-model:expanded-row-keys="arrayState.arrayChildExpandKeys"
@@ -627,6 +656,38 @@ onMounted(() => {
:columns="treeState.selectNode.paramPerms.includes('get') ? [...arrayState.columns.filter((s:any)=>s.key !== 'index')] : arrayState.columns" :columns="treeState.selectNode.paramPerms.includes('get') ? [...arrayState.columns.filter((s:any)=>s.key !== 'index')] : arrayState.columns"
v-model:columns-dnd="arrayState.columnsDnd" v-model:columns-dnd="arrayState.columnsDnd"
></TableColumnsDnd> ></TableColumnsDnd>
<!-- 特殊导入删除-->
<template
v-if="
['AMF', 'MME'].includes(neTypeSelect[0]) &&
['white_list', 'imeiWhitelist', 'whitelist'].includes(
treeState.selectNode.paramName
)
"
>
<a-button
@click.prevent="
modalImportOpen(
neTypeSelect[0],
treeState.selectNode.paramName
)
"
size="small"
>
<template #icon><ImportOutlined /></template>
{{ t('common.import') }}
</a-button>
<a-button
danger
@click.prevent="
modalBatchOpen(treeState.selectNode.paramName)
"
size="small"
>
<template #icon><DeleteOutlined /></template>
{{ t('views.neData.common.batchDelText') }}
</a-button>
</template>
</a-space> </a-space>
</template> </template>
@@ -698,7 +759,7 @@ onMounted(() => {
{{ JSON.parse(text['filter'])[text.value] }} {{ JSON.parse(text['filter'])[text.value] }}
</template> </template>
<template v-else> <template v-else>
{{ `${text.value}` || '&nbsp;' }} {{ `${text.value}` }}
</template> </template>
</div> </div>
</div> </div>
@@ -784,7 +845,7 @@ onMounted(() => {
{{ JSON.parse(text['filter'])[text.value] }} {{ JSON.parse(text['filter'])[text.value] }}
</template> </template>
<template v-else> <template v-else>
{{ `${text.value}` || '&nbsp;' }} {{ `${text.value}` }}
</template> </template>
</div> </div>
</div> </div>
@@ -904,6 +965,84 @@ onMounted(() => {
</a-form-item> </a-form-item>
</a-form> </a-form>
</ProModal> </ProModal>
<!-- 上传导入表格数据文件框 -->
<UploadModal
:title="t('common.import')"
@upload="modalImportUpload"
@close="modalImportClose"
v-model:open="importState.open"
:ext="['.xls', '.xlsx']"
:size="10"
>
<template #default>
<a-row justify="space-between" align="middle">
<a-col :span="12"> </a-col>
<a-col :span="6">
<a-button
type="link"
:title="t('views.system.user.downloadObj')"
@click.prevent="modalImportTemplate"
>
{{ t('views.system.user.downloadObj') }}
</a-button>
</a-col>
</a-row>
<a-textarea
:disabled="true"
:hidden="importState.msgArr.length <= 0"
:value="importState.msgArr.join('\r\n')"
:auto-size="{ minRows: 2, maxRows: 8 }"
style="background-color: transparent; color: rgba(0, 0, 0, 0.85)"
/>
</template>
</UploadModal>
<!-- 批量删除框 -->
<ProModal
:drag="true"
:destroyOnClose="true"
:keyboard="false"
:mask-closable="false"
:open="batchState.open"
:title="t('views.neData.common.batchDelText')"
:confirm-loading="batchState.loading"
@ok="modalBatchOk"
@cancel="modalBatchClose"
>
<a-form
name="batchStateForm"
:model="batchState"
layout="horizontal"
:label-col="{ span: 6 }"
:labelWrap="true"
>
<a-row>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="Start Index" name="startIndex" required>
<a-input-number
v-model:value="batchState.startIndex"
style="width: 100%"
allow-clear
:min="0"
:maxlength="5"
></a-input-number>
</a-form-item>
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="Num" name="num" required>
<a-input-number
v-model:value="batchState.num"
style="width: 100%"
:min="1"
:maxlength="5"
placeholder="<=500"
></a-input-number>
</a-form-item>
</a-col>
</a-row>
</a-form>
</ProModal>
</PageContainer> </PageContainer>
</template> </template>

View File

@@ -6,7 +6,7 @@ import { Form, Modal, TableColumnsType, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import BackupModal from './components/BackupModal.vue'; import BackupModal from './components/BackupModal.vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
@@ -21,7 +21,7 @@ import { pushBackupFTP } from '@/api/neData/backup';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
const { t } = useI18n(); const { t } = useI18n();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**字典数据-状态 */ /**字典数据-状态 */
let dictStatus = ref<DictType[]>([]); let dictStatus = ref<DictType[]>([]);

View File

@@ -7,13 +7,13 @@ import { DataNode } from 'ant-design-vue/es/tree';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useOptions from './hooks/useOptions'; import useOptions from './hooks/useOptions';
import useConfigList from './hooks/useConfigList'; import useConfigList from './hooks/useConfigList';
import useConfigArray from './hooks/useConfigArray'; import useConfigArray from './hooks/useConfigArray';
import useConfigArrayChild from './hooks/useConfigArrayChild'; import useConfigArrayChild from './hooks/useConfigArrayChild';
import { getAllNeConfig, getNeConfigData } from '@/api/ne/neConfig'; import { getAllNeConfig, getNeConfigData } from '@/api/ne/neConfig';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
const { ruleVerification, smfByUPFIdLoadData, smfByUPFIdOptions } = useOptions({ const { ruleVerification, smfByUPFIdLoadData, smfByUPFIdOptions } = useOptions({
t, t,

View File

@@ -7,13 +7,13 @@ import { Modal, message } from 'ant-design-vue/es';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { getNeFile, listNeFiles } from '@/api/tool/neFile'; import { getNeFile, listNeFiles } from '@/api/tool/neFile';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import ViewDrawer from './components/ViewDrawer.vue'; import ViewDrawer from './components/ViewDrawer.vue';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { parseSizeFromFile } from '@/utils/parse-utils'; import { parseSizeFromFile } from '@/utils/parse-utils';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();

View File

@@ -7,12 +7,12 @@ import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { listNeInfo, delNeInfo, stateNeInfo } from '@/api/ne/neInfo'; import { listNeInfo, delNeInfo, stateNeInfo } from '@/api/ne/neInfo';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useNeOptions from './hooks/useNeOptions'; import useNeOptions from './hooks/useNeOptions';
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
const { const {
fnNeStart, fnNeStart,

View File

@@ -4,7 +4,7 @@ import { PageContainer } from 'antdv-pro-layout';
import { Modal, TableColumnsType, message } from 'ant-design-vue/es'; import { Modal, TableColumnsType, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
@@ -12,7 +12,7 @@ import { listNeLicense, stateNeLicense } from '@/api/ne/neLicense';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
const { t } = useI18n(); const { t } = useI18n();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const EditModal = defineAsyncComponent( const EditModal = defineAsyncComponent(
() => import('./components/EditModal.vue') () => import('./components/EditModal.vue')
); );

View File

@@ -8,9 +8,9 @@ import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
import { fnRestStepState, fnToStepName, stepState } from '../hooks/useStep'; import { fnRestStepState, fnToStepName, stepState } from '../hooks/useStep';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
/**字典数据 */ /**字典数据 */

View File

@@ -1,8 +1,8 @@
import { reactive, toRaw } from 'vue'; import { reactive, toRaw } from 'vue';
import { getPara5GFilee, savePara5GFile, updateNeInfo } from '@/api/ne/neInfo'; import { getPara5GFilee, savePara5GFile, updateNeInfo } from '@/api/ne/neInfo';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**对象信息信息状态类型 */ /**对象信息信息状态类型 */
type StateType = { type StateType = {

View File

@@ -4,14 +4,14 @@ import { PageContainer } from 'antdv-pro-layout';
import { Modal, TableColumnsType, message } from 'ant-design-vue/es'; import { Modal, TableColumnsType, message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listNeSoftware, delNeSoftware } from '@/api/ne/neSoftware'; import { listNeSoftware, delNeSoftware } from '@/api/ne/neSoftware';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { downloadFile } from '@/api/tool/file'; import { downloadFile } from '@/api/tool/file';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
// 异步加载组件 // 异步加载组件

View File

@@ -10,7 +10,7 @@ import {
} from 'ant-design-vue/es'; } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listNeVersion, operateNeVersion } from '@/api/ne/neVersion'; import { listNeVersion, operateNeVersion } from '@/api/ne/neVersion';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
@@ -18,7 +18,7 @@ import useI18n from '@/hooks/useI18n';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useMaskStore from '@/store/modules/mask'; import useMaskStore from '@/store/modules/mask';
const maskStore = useMaskStore(); const maskStore = useMaskStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
const { getDict } = useDictStore(); const { getDict } = useDictStore();

View File

@@ -8,13 +8,13 @@ import BackupModal from '@/views/ne/neConfigBackup/components/BackupModal.vue';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useNeListStore from '@/store/modules/ne_list'; import useCoreStore from '@/store/modules/core';
import useNeStore from '@/store/modules/ne';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
import { delFile, getFile, listFile } from '@/api/tool/file'; import { delFile, getFile, listFile } from '@/api/tool/file';
import { parseSizeFromFile } from '@/utils/parse-utils'; import { parseSizeFromFile } from '@/utils/parse-utils';
import { pushBackupFTP } from '@/api/neData/backup'; import { pushBackupFTP } from '@/api/neData/backup';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore();
/**文件来源 */ /**文件来源 */
let sourceState = reactive({ let sourceState = reactive({
@@ -306,9 +306,10 @@ function fnSyncFileToFTP(fileName: string) {
} }
onMounted(() => { onMounted(() => {
const coreUid = useCoreStore().getCurrentCoreUid;
sourceState.list = sourceState.list.filter(item => { sourceState.list = sourceState.list.filter(item => {
if (!item.neType) return true; if (!item.neType) return true;
return neListStore.fnHasNe([item.neType]); return useNeStore().fnHasNe(coreUid, [item.neType]);
}); });
}); });
</script> </script>

View File

@@ -6,11 +6,11 @@ import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { listAMFNblist } from '@/api/neData/amf'; import { listAMFNblist } from '@/api/neData/amf';
import { listMMENblist } from '@/api/neData/mme'; import { listMMENblist } from '@/api/neData/mme';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();

View File

@@ -12,7 +12,7 @@ import { SizeType } from 'ant-design-vue/es/config-provider';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import { ProModal } from 'antdv-pro-modal'; import { ProModal } from 'antdv-pro-modal';
import UploadModal from '@/components/UploadModal/index.vue'; import UploadModal from '@/components/UploadModal/index.vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();
import { import {
@@ -32,7 +32,7 @@ import saveAs from 'file-saver';
import { readSheet, writeSheet } from '@/utils/execl-utils'; import { readSheet, writeSheet } from '@/utils/execl-utils';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
const route = useRoute(); const route = useRoute();
const neListStore = useNeListStore(); const neListStore = useNeStore();
// 异步加载组件 // 异步加载组件
const HistoryModal = defineAsyncComponent( const HistoryModal = defineAsyncComponent(

View File

@@ -5,7 +5,7 @@ import { listAMFNbStatelist } from '@/api/neData/amf';
import { parseBasePath } from '@/plugins/file-static-url'; import { parseBasePath } from '@/plugins/file-static-url';
import { edgeLineAnimateState } from '@/views/monitor/topologyBuild/hooks/registerEdge'; import { edgeLineAnimateState } from '@/views/monitor/topologyBuild/hooks/registerEdge';
import { nodeImageAnimateState } from '@/views/monitor/topologyBuild/hooks/registerNode'; import { nodeImageAnimateState } from '@/views/monitor/topologyBuild/hooks/registerNode';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { stateNeInfo } from '@/api/ne/neInfo'; import { stateNeInfo } from '@/api/ne/neInfo';
@@ -13,7 +13,7 @@ import { parseDateToStr } from '@/utils/date-utils';
import { useFullscreen } from '@vueuse/core'; import { useFullscreen } from '@vueuse/core';
import { listMMENbStatelist } from '@/api/neData/mme'; import { listMMENbStatelist } from '@/api/neData/mme';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**图DOM节点实例对象 */ /**图DOM节点实例对象 */
const graphG6Dom = useTemplateRef('graphG6Dom'); const graphG6Dom = useTemplateRef('graphG6Dom');

View File

@@ -5,12 +5,12 @@ import { message } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listIMSSessionList } from '@/api/neData/ims'; import { listIMSSessionList } from '@/api/neData/ims';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**网元参数 */ /**网元参数 */
let neOtions = ref<Record<string, any>[]>([]); let neOtions = ref<Record<string, any>[]>([]);

View File

@@ -6,7 +6,7 @@ import { message, Modal, Form, TableColumnsType } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import UploadModal from '@/components/UploadModal/index.vue'; import UploadModal from '@/components/UploadModal/index.vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { import {
addPCFRule, addPCFRule,
@@ -21,7 +21,7 @@ import { uploadFileToNE } from '@/api/tool/file';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**网元参数 */ /**网元参数 */
let neOtions = ref<Record<string, any>[]>([]); let neOtions = ref<Record<string, any>[]>([]);

View File

@@ -7,11 +7,11 @@ import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import { listSMFSubList } from '@/api/neData/smf'; import { listSMFSubList } from '@/api/neData/smf';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**网元参数 */ /**网元参数 */
let neOtions = ref<Record<string, any>[]>([]); let neOtions = ref<Record<string, any>[]>([]);

View File

@@ -8,7 +8,7 @@ import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import UploadModal from '@/components/UploadModal/index.vue'; import UploadModal from '@/components/UploadModal/index.vue';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
@@ -27,7 +27,7 @@ import {
import { uploadFile } from '@/api/tool/file'; import { uploadFile } from '@/api/tool/file';
import { getNeViewFile } from '@/api/tool/neFile'; import { getNeViewFile } from '@/api/tool/neFile';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**网元参数 */ /**网元参数 */
let neOtions = ref<Record<string, any>[]>([]); let neOtions = ref<Record<string, any>[]>([]);

View File

@@ -8,7 +8,7 @@ import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import UploadModal from '@/components/UploadModal/index.vue'; import UploadModal from '@/components/UploadModal/index.vue';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
@@ -27,7 +27,7 @@ import {
import { uploadFile } from '@/api/tool/file'; import { uploadFile } from '@/api/tool/file';
import { getNeViewFile } from '@/api/tool/neFile'; import { getNeViewFile } from '@/api/tool/neFile';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**网元参数 */ /**网元参数 */
let neOtions = ref<Record<string, any>[]>([]); let neOtions = ref<Record<string, any>[]>([]);
@@ -1668,10 +1668,16 @@ onMounted(() => {
> >
<a-select v-model:value="modalState.from.cnType"> <a-select v-model:value="modalState.from.cnType">
<a-select-option value="3"> <a-select-option value="3">
{{ t('views.neUser.sub.enable') }} {{ t('views.neUser.sub.cnFlag3') }}
</a-select-option>
<a-select-option value="2">
{{ t('views.neUser.sub.cnFlag2') }}
</a-select-option>
<a-select-option value="1">
{{ t('views.neUser.sub.cnFlag1') }}
</a-select-option> </a-select-option>
<a-select-option value="0"> <a-select-option value="0">
{{ t('views.neUser.sub.disable') }} {{ t('views.neUser.sub.cnFlag0') }}
</a-select-option> </a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>

View File

@@ -22,13 +22,14 @@ import {
listUDMVOIP, listUDMVOIP,
resetUDMVOIP, resetUDMVOIP,
} from '@/api/neData/udm_voip'; } from '@/api/neData/udm_voip';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
import { uploadFileToNE } from '@/api/tool/file'; import { uploadFile } from '@/api/tool/file';
import { getNeViewFile } from '@/api/tool/neFile';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**网元参数 */ /**网元参数 */
let neOtions = ref<Record<string, any>[]>([]); let neOtions = ref<Record<string, any>[]>([]);
@@ -489,15 +490,27 @@ function fnModalUploadImportUpload(file: File) {
} }
const hide = message.loading(t('common.loading'), 0); const hide = message.loading(t('common.loading'), 0);
uploadImportState.loading = true; uploadImportState.loading = true;
uploadFileToNE('UDM', neID, file, 5) // 上传文件
let formData = new FormData();
formData.append('file', file);
formData.append('subPath', 'import');
uploadFile(formData)
.then(res => { .then(res => {
if (res.code === RESULT_CODE_SUCCESS) { if (res.code === RESULT_CODE_SUCCESS) {
return importUDMVOIP({ return res.data.filePath;
neId: neID, } else {
uploadPath: res.data, uploadImportState.msg = res.msg;
}); uploadImportState.loading = false;
return '';
} }
return res; })
.then((filePath: string) => {
if (!filePath) return;
// 文件导入
return importUDMVOIP({
neId: neID,
uploadPath: filePath,
});
}) })
.then(res => { .then(res => {
if (!res) return; if (!res) return;
@@ -517,6 +530,33 @@ function fnModalUploadImportUpload(file: File) {
}); });
} }
/**对话框表格信息导入失败原因 */
function fnModalUploadImportFailReason() {
const neId = queryParams.neId;
if (!neId) return;
const hide = message.loading(t('common.loading'), 0);
getNeViewFile({
neType: 'UDM',
neId: neId,
path: '/tmp',
fileName: 'import_imsuser_err_records.txt',
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success(t('common.operateOk'), 3);
const blob = new Blob([res.data], {
type: 'text/plain',
});
saveAs(blob, `import_udmvoip_err_records_${Date.now()}.txt`);
} else {
message.error(`${res.msg}`, 3);
}
})
.finally(() => {
hide();
});
}
/**对话框表格信息导入模板 */ /**对话框表格信息导入模板 */
function fnModalDownloadImportTemplate() { function fnModalDownloadImportTemplate() {
const hide = message.loading(t('common.loading'), 0); const hide = message.loading(t('common.loading'), 0);
@@ -554,7 +594,7 @@ onMounted(() => {
if (neOtions.value.length > 0) { if (neOtions.value.length > 0) {
queryParams.neId = neOtions.value[0].value; queryParams.neId = neOtions.value[0].value;
} }
// 获取列表数据 // 获取列表数据
fnGetList(); fnGetList();
}); });
@@ -835,7 +875,7 @@ onMounted(() => {
v-model:value="modalState.from.username" v-model:value="modalState.from.username"
style="width: 100%" style="width: 100%"
:min="4" :min="4"
:maxlangth="16" :maxlength="16"
:placeholder="t('views.neData.udmVOIP.username')" :placeholder="t('views.neData.udmVOIP.username')"
> >
</a-input-number> </a-input-number>
@@ -868,14 +908,13 @@ onMounted(() => {
name="username" name="username"
v-bind="modalStateFrom.validateInfos.username" v-bind="modalStateFrom.validateInfos.username"
> >
<a-input-number <a-input
v-model:value="modalState.from.username" v-model:value="modalState.from.username"
style="width: 100%" style="width: 100%"
:min="4"
:maxlength="16" :maxlength="16"
:placeholder="t('views.neData.udmVOIP.username')" :placeholder="t('views.neData.udmVOIP.username')"
> >
</a-input-number> </a-input>
</a-form-item> </a-form-item>
<a-form-item <a-form-item
:label="t('views.neData.udmVOIP.password')" :label="t('views.neData.udmVOIP.password')"
@@ -917,13 +956,23 @@ onMounted(() => {
</a-button> </a-button>
</a-col> </a-col>
</a-row> </a-row>
<a-textarea <a-alert
:disabled="true" :message="uploadImportState.msg"
:hidden="!uploadImportState.msg" :type="uploadImportState.hasFail ? 'warning' : 'info'"
:value="uploadImportState.msg" v-show="uploadImportState.msg.length > 0"
:auto-size="{ minRows: 2, maxRows: 8 }" >
style="background-color: transparent; color: rgba(0, 0, 0, 0.85)" <template #action>
/> <a-button
size="small"
type="link"
danger
@click="fnModalUploadImportFailReason"
v-if="uploadImportState.hasFail"
>
{{ t('views.neUser.auth.importFail') }}
</a-button>
</template>
</a-alert>
</template> </template>
</UploadModal> </UploadModal>
</PageContainer> </PageContainer>

View File

@@ -12,11 +12,12 @@ import {
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import UploadModal from '@/components/UploadModal/index.vue'; import UploadModal from '@/components/UploadModal/index.vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
import { uploadFileToNE } from '@/api/tool/file'; import { uploadFile } from '@/api/tool/file';
import { getNeViewFile } from '@/api/tool/neFile';
import { import {
addUDMVolteIMS, addUDMVolteIMS,
batchAddUDMVolteIMS, batchAddUDMVolteIMS,
@@ -28,7 +29,7 @@ import {
resetUDMVolteIMS, resetUDMVolteIMS,
} from '@/api/neData/udm_volte_ims'; } from '@/api/neData/udm_volte_ims';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**字典数据 */ /**字典数据 */
let dict: { let dict: {
/**Tag标签类型 0=VoIP, 1=VoLTE */ /**Tag标签类型 0=VoIP, 1=VoLTE */
@@ -93,7 +94,7 @@ type TabeStateType = {
data: object[]; data: object[];
/**勾选记录 */ /**勾选记录 */
selectedRowKeys: (string | number)[]; selectedRowKeys: (string | number)[];
selectedRowIMSIs: (string | number)[]; selectedRowIMSIs: Record<string, any>[];
}; };
/**表格状态 */ /**表格状态 */
@@ -202,7 +203,13 @@ function fnTableSize({ key }: MenuInfo) {
/**表格多选 */ /**表格多选 */
function fnTableSelectedRowKeys(keys: (string | number)[], rows: any[]) { function fnTableSelectedRowKeys(keys: (string | number)[], rows: any[]) {
tableState.selectedRowKeys = keys; tableState.selectedRowKeys = keys;
tableState.selectedRowIMSIs = rows.map(item => item.imsi); tableState.selectedRowIMSIs = rows.map(item => {
return {
imsi: item.imsi,
msisdn: item.msisdn,
tag: item.tag,
};
});
} }
/**对话框对象信息状态类型 */ /**对话框对象信息状态类型 */
@@ -308,7 +315,12 @@ function fnModalOk() {
result = batchAddUDMVolteIMS(from, from.num); result = batchAddUDMVolteIMS(from, from.num);
} }
if (modalState.type === 'delete') { if (modalState.type === 'delete') {
result = batchDelUDMVolteIMS(from.neId, from.imsi, from.num); result = batchDelUDMVolteIMS(
from.neId,
`${from.imsi}_${from.msisdn}`,
from.num,
from.tag
);
} }
} else { } else {
if (modalState.type === 'add') { if (modalState.type === 'add') {
@@ -374,15 +386,14 @@ function fnModalVisibleByBatch(type: 'delete' | 'add') {
/** /**
* 记录删除 * 记录删除
* @param imsi 网元编号ID * @param id 记录ID
*/ */
function fnRecordDelete(imsi: string) { function fnRecordDelete(id: string) {
const neID = queryParams.neId; const neID = queryParams.neId;
if (!neID) return; if (!neID) return;
let msg = imsi; let msg = id;
if (imsi === '0') { if (id === '0') {
msg = `${tableState.selectedRowIMSIs[0]}... ${tableState.selectedRowIMSIs.length}`; msg = `${tableState.selectedRowIMSIs[0].imsi}... ${tableState.selectedRowIMSIs.length}`;
imsi = tableState.selectedRowIMSIs.join(',');
} }
Modal.confirm({ Modal.confirm({
@@ -390,17 +401,34 @@ function fnRecordDelete(imsi: string) {
content: t('views.neData.udmVolteIMS.delTip', { num: msg }), content: t('views.neData.udmVolteIMS.delTip', { num: msg }),
onOk() { onOk() {
const hide = message.loading(t('common.loading'), 0); const hide = message.loading(t('common.loading'), 0);
delUDMVolteIMS(neID, imsi) let reqArr: any[] = [];
.then(res => { if (id === '0') {
if (res.code === RESULT_CODE_SUCCESS) { const volteArr = tableState.selectedRowIMSIs
message.success(t('common.operateOk'), 3); .filter(item => item.tag == '1')
fnGetList(); .map(item => `${item.imsi}_${item.msisdn}`)
} else { .join(',');
message.error({ if (volteArr.length > 0) {
content: `${res.msg}`, reqArr.push(delUDMVolteIMS(neID, volteArr, '1'));
duration: 3, }
}); const voipArr = tableState.selectedRowIMSIs
} .filter(item => item.tag == '0')
.map(item => `${item.imsi}_${item.msisdn}`)
.join(',');
if (voipArr.length > 0) {
reqArr.push(delUDMVolteIMS(neID, voipArr, '0'));
}
} else {
const record: any = tableState.data.find((item: any) => item.id === id);
if (record) {
reqArr = [
delUDMVolteIMS(neID, `${record.imsi}_${record.msisdn}`, record.tag),
];
}
}
Promise.all(reqArr)
.then(() => {
message.success(t('common.operateOk'), 3);
fnGetList();
}) })
.finally(() => { .finally(() => {
hide(); hide();
@@ -541,15 +569,27 @@ function fnModalUploadImportUpload(file: File) {
} }
const hide = message.loading(t('common.loading'), 0); const hide = message.loading(t('common.loading'), 0);
uploadImportState.loading = true; uploadImportState.loading = true;
uploadFileToNE('UDM', neID, file, 5) // 上传文件
let formData = new FormData();
formData.append('file', file);
formData.append('subPath', 'import');
uploadFile(formData)
.then(res => { .then(res => {
if (res.code === RESULT_CODE_SUCCESS) { if (res.code === RESULT_CODE_SUCCESS) {
return importUDMVolteIMS({ return res.data.filePath;
neId: neID, } else {
uploadPath: res.data, uploadImportState.msg = res.msg;
}); uploadImportState.loading = false;
return '';
} }
return res; })
.then((filePath: string) => {
if (!filePath) return;
// 文件导入
return importUDMVolteIMS({
neId: neID,
uploadPath: filePath,
});
}) })
.then(res => { .then(res => {
if (!res) return; if (!res) return;
@@ -569,6 +609,33 @@ function fnModalUploadImportUpload(file: File) {
}); });
} }
/**对话框表格信息导入失败原因 */
function fnModalUploadImportFailReason() {
const neId = queryParams.neId;
if (!neId) return;
const hide = message.loading(t('common.loading'), 0);
getNeViewFile({
neType: 'UDM',
neId: neId,
path: '/tmp',
fileName: 'import_imsuser_err_records.txt',
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success(t('common.operateOk'), 3);
const blob = new Blob([res.data], {
type: 'text/plain',
});
saveAs(blob, `import_udmvolte_err_records_${Date.now()}.txt`);
} else {
message.error(`${res.msg}`, 3);
}
})
.finally(() => {
hide();
});
}
/**对话框表格信息导入模板 */ /**对话框表格信息导入模板 */
function fnModalDownloadImportTemplate() { function fnModalDownloadImportTemplate() {
const hide = message.loading(t('common.loading'), 0); const hide = message.loading(t('common.loading'), 0);
@@ -847,7 +914,7 @@ onMounted(() => {
<template #title>{{ t('common.deleteText') }}</template> <template #title>{{ t('common.deleteText') }}</template>
<a-button <a-button
type="link" type="link"
@click.prevent="fnRecordDelete(record.imsi)" @click.prevent="fnRecordDelete(record.id)"
> >
<template #icon> <template #icon>
<DeleteOutlined /> <DeleteOutlined />
@@ -906,36 +973,73 @@ onMounted(() => {
> >
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item
v-if="modalState.from.tag === '1'" <template v-if="modalState.from.tag === '1'">
:label=" <a-form-item
modalState.isBatch ? t('views.neData.common.startIMSI') : 'IMSI' :label="
" modalState.isBatch ? t('views.neData.common.startIMSI') : 'IMSI'
name="imsi" "
v-bind="modalStateFrom.validateInfos.imsi" name="imsi"
> v-bind="modalStateFrom.validateInfos.imsi"
<a-input
v-model:value="modalState.from.imsi"
allow-clear
:maxlength="15"
> >
<template #prefix> <a-input
<a-tooltip placement="topLeft"> v-model:value="modalState.from.imsi"
<template #title> allow-clear
{{ t('views.neData.common.imsiTip') }}<br /> :maxlength="15"
{{ t('views.neData.common.imsiTip1') }}<br /> >
{{ t('views.neData.common.imsiTip2') }}<br /> <template #prefix>
{{ t('views.neData.common.imsiTip3') }} <a-tooltip placement="topLeft">
</template> <template #title>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" /> {{ t('views.neData.common.imsiTip') }}<br />
</a-tooltip> {{ t('views.neData.common.imsiTip1') }}<br />
</template> {{ t('views.neData.common.imsiTip2') }}<br />
</a-input> {{ t('views.neData.common.imsiTip3') }}
</a-form-item> </template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
</a-tooltip>
</template>
</a-input>
</a-form-item>
<a-form-item
:extra="
modalState.from.tag == '0'
? t('views.neData.udmVolteIMS.voipTip')
: ''
"
:label="
modalState.isBatch
? t('views.neData.udmVolteIMS.startMSISDN')
: 'MSISDN'
"
name="msisdn"
v-bind="modalStateFrom.validateInfos.msisdn"
>
<a-input
v-model:value="modalState.from.msisdn"
allow-clear
:maxlength="32"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neData.common.msisdn') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
</a-tooltip>
</template>
</a-input>
</a-form-item>
</template>
<a-form-item <a-form-item
v-else v-if="modalState.from.tag === '0'"
:extra="
modalState.from.tag == '0'
? t('views.neData.udmVolteIMS.voipTip')
: ''
"
:label=" :label="
modalState.isBatch && modalState.from.tag === '0' modalState.isBatch
? t('views.neData.udmVolteIMS.startMSISDN') ? t('views.neData.udmVolteIMS.startMSISDN')
: 'MSISDN' : 'MSISDN'
" "
@@ -1021,7 +1125,7 @@ onMounted(() => {
: '' : ''
" "
:label=" :label="
modalState.isBatch && modalState.from.tag === '0' modalState.isBatch
? t('views.neData.udmVolteIMS.startMSISDN') ? t('views.neData.udmVolteIMS.startMSISDN')
: 'MSISDN' : 'MSISDN'
" "
@@ -1089,13 +1193,23 @@ onMounted(() => {
</a-button> </a-button>
</a-col> </a-col>
</a-row> </a-row>
<a-textarea <a-alert
:disabled="true" :message="uploadImportState.msg"
:hidden="!uploadImportState.msg" :type="uploadImportState.hasFail ? 'warning' : 'info'"
:value="uploadImportState.msg" v-show="uploadImportState.msg.length > 0"
:auto-size="{ minRows: 2, maxRows: 8 }" >
style="background-color: transparent; color: rgba(0, 0, 0, 0.85)" <template #action>
/> <a-button
size="small"
type="link"
danger
@click="fnModalUploadImportFailReason"
v-if="uploadImportState.hasFail"
>
{{ t('views.neUser.auth.importFail') }}
</a-button>
</template>
</a-alert>
</template> </template>
</UploadModal> </UploadModal>
</PageContainer> </PageContainer>

View File

@@ -6,11 +6,11 @@ import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import { listN3iwf } from '@/api/neUser/n3iwf'; import { listN3iwf } from '@/api/neUser/n3iwf';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
const { t } = useI18n(); const { t } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**网元参数 */ /**网元参数 */
let neOtions = ref<Record<string, any>[]>([]); let neOtions = ref<Record<string, any>[]>([]);

View File

@@ -8,7 +8,7 @@ import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { import {
addCustom, addCustom,
delCustom, delCustom,
@@ -19,7 +19,7 @@ import { getKPITitle } from '@/api/perfManage/goldTarget';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
/**字典数据 */ /**字典数据 */
let dict: { let dict: {
/**状态 */ /**状态 */

View File

@@ -35,7 +35,7 @@ import {
RESULT_CODE_ERROR, RESULT_CODE_ERROR,
RESULT_CODE_SUCCESS, RESULT_CODE_SUCCESS,
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { getKPITitle, listKPIData } from '@/api/perfManage/goldTarget'; import { getKPITitle, listKPIData } from '@/api/perfManage/goldTarget';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
@@ -47,7 +47,7 @@ import { useRoute } from 'vue-router';
import { LineOutlined } from '@ant-design/icons-vue'; import { LineOutlined } from '@ant-design/icons-vue';
import useLayoutStore from '@/store/modules/layout'; import useLayoutStore from '@/store/modules/layout';
const layoutStore = useLayoutStore(); const layoutStore = useLayoutStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const route = useRoute(); const route = useRoute();
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();
const ws = new WS(); const ws = new WS();

View File

@@ -34,7 +34,7 @@ import {
RESULT_CODE_ERROR, RESULT_CODE_ERROR,
RESULT_CODE_SUCCESS, RESULT_CODE_SUCCESS,
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { listCustom } from '@/api/perfManage/customTarget'; import { listCustom } from '@/api/perfManage/customTarget';
import { listCustomData } from '@/api/perfManage/customData'; import { listCustomData } from '@/api/perfManage/customData';
@@ -48,7 +48,7 @@ import { useRoute } from 'vue-router';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import useLayoutStore from '@/store/modules/layout'; import useLayoutStore from '@/store/modules/layout';
const layoutStore = useLayoutStore(); const layoutStore = useLayoutStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const route = useRoute(); const route = useRoute();
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();
const ws = new WS(); const ws = new WS();

View File

@@ -20,7 +20,7 @@ import { listKPIData, getKPITitle } from '@/api/perfManage/goldTarget';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { generateColorRGBA } from '@/utils/generate-utils'; import { generateColorRGBA } from '@/utils/generate-utils';
import { LineSeriesOption } from 'echarts/charts'; import { LineSeriesOption } from 'echarts/charts';
@@ -30,7 +30,7 @@ import { useDebounceFn } from '@vueuse/core';
import { LineOutlined } from '@ant-design/icons-vue'; import { LineOutlined } from '@ant-design/icons-vue';
import { TableColumnType } from 'ant-design-vue'; import { TableColumnType } from 'ant-design-vue';
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();
const neListStore = useNeListStore(); const neListStore = useNeStore();
//日期快捷选择 //日期快捷选择
const ranges = ref([ const ranges = ref([
{ {

View File

@@ -7,7 +7,7 @@ import { ColumnsType } from 'ant-design-vue/es/table';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listperfData } from '@/api/perfManage/perfData'; import { listperfData } from '@/api/perfManage/perfData';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
const { getDict } = useDictStore(); const { getDict } = useDictStore();
@@ -223,7 +223,7 @@ onMounted(() => {
} }
}); });
// 获取网元网元列表 // 获取网元网元列表
useNeListStore().fnNelist(); useNeStore().fnNelist();
// 获取列表数据 // 获取列表数据
fnGetList(); fnGetList();
}); });
@@ -246,7 +246,7 @@ onMounted(() => {
> >
<a-auto-complete <a-auto-complete
v-model:value="queryParams.neType" v-model:value="queryParams.neType"
:options="useNeListStore().getNeSelectOtions" :options="useNeStore().getNeSelectOtions"
allow-clear allow-clear
/> />
</a-form-item> </a-form-item>

View File

@@ -9,7 +9,7 @@ import { ColumnsType } from 'ant-design-vue/es/table';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { import {
addPerfThre, addPerfThre,
delPerfThre, delPerfThre,
@@ -269,7 +269,7 @@ const modalStateFrom = Form.useForm(
function fnSelectPerformanceInit(value: any) { function fnSelectPerformanceInit(value: any) {
//console.logg(currentLocale.value); //当前语言 //console.logg(currentLocale.value); //当前语言
const performance: any = []; const performance: any = [];
// const performance = useNeListStore().perMeasurementList.filter( // const performance = useNeStore().perMeasurementList.filter(
// i => i.neType === value // i => i.neType === value
// ); // );
//进行分组选择 //进行分组选择
@@ -492,9 +492,9 @@ onMounted(() => {
Promise.allSettled([ Promise.allSettled([
// 获取网元网元列表 // 获取网元网元列表
useNeListStore().fnNelist(), useNeStore().fnNelist(),
// 获取性能测量集列表 // 获取性能测量集列表
// useNeListStore().fnNeTaskPerformance(), // useNeStore().fnNeTaskPerformance(),
// getNePerformanceList(), // getNePerformanceList(),
]).finally(() => { ]).finally(() => {
// 获取列表数据 // 获取列表数据
@@ -517,7 +517,7 @@ onMounted(() => {
<a-form-item :label="t('views.ne.common.neType')" name="neType "> <a-form-item :label="t('views.ne.common.neType')" name="neType ">
<a-auto-complete <a-auto-complete
v-model:value="queryParams.neType" v-model:value="queryParams.neType"
:options="useNeListStore().getNeSelectOtions" :options="useNeStore().getNeSelectOtions"
allow-clear allow-clear
:placeholder="t('views.ne.common.neTypePlease')" :placeholder="t('views.ne.common.neTypePlease')"
/> />
@@ -691,7 +691,7 @@ onMounted(() => {
> >
<a-select <a-select
v-model:value="modalState.from.neType" v-model:value="modalState.from.neType"
:options="useNeListStore().getNeSelectOtions" :options="useNeStore().getNeSelectOtions"
@change="fnSelectPerformanceInit" @change="fnSelectPerformanceInit"
:allow-clear="false" :allow-clear="false"
:placeholder="t('views.ne.common.neTypePlease')" :placeholder="t('views.ne.common.neTypePlease')"

View File

@@ -10,7 +10,7 @@ import { parseDateToStr } from '@/utils/date-utils';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { import {
addPerfTask, addPerfTask,
delPerfTask, delPerfTask,
@@ -20,7 +20,7 @@ import {
taskStop, taskStop,
taskRun, taskRun,
} from '@/api/perfManage/taskManage'; } from '@/api/perfManage/taskManage';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();
const generateOptions = (start: any, end: any) => { const generateOptions = (start: any, end: any) => {

View File

@@ -8,9 +8,9 @@ import {
RESULT_CODE_SUCCESS, RESULT_CODE_SUCCESS,
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import TerminalSSHView from '@/components/TerminalSSHView/index.vue'; import TerminalSSHView from '@/components/TerminalSSHView/index.vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { iperfI, iperfV } from '@/api/tool/iperf'; import { iperfI, iperfV } from '@/api/tool/iperf';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
/**网元参数 */ /**网元参数 */

View File

@@ -8,9 +8,9 @@ import {
RESULT_CODE_SUCCESS, RESULT_CODE_SUCCESS,
} from '@/constants/result-constants'; } from '@/constants/result-constants';
import TerminalSSHView from '@/components/TerminalSSHView/index.vue'; import TerminalSSHView from '@/components/TerminalSSHView/index.vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { pingV } from '@/api/tool/ping'; import { pingV } from '@/api/tool/ping';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
/**网元参数 */ /**网元参数 */

View File

@@ -5,10 +5,10 @@ import { ColumnsType } from 'ant-design-vue/es/table';
import { Modal, message } from 'ant-design-vue/es'; import { Modal, message } from 'ant-design-vue/es';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { delNeHost, listNeHost } from '@/api/ne/neHost'; import { delNeHost, listNeHost } from '@/api/ne/neHost';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useDictStore from '@/store/modules/dict'; import useDictStore from '@/store/modules/dict';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const { t } = useI18n(); const { t } = useI18n();
const EditModal = defineAsyncComponent( const EditModal = defineAsyncComponent(

View File

@@ -5,16 +5,17 @@ import { SizeType } from 'ant-design-vue/es/config-provider';
import { ColumnsType } from 'ant-design-vue/es/table'; import { ColumnsType } from 'ant-design-vue/es/table';
import { Modal, message } from 'ant-design-vue/es'; import { Modal, message } from 'ant-design-vue/es';
import { parseDateToStr } from '@/utils/date-utils'; import { parseDateToStr } from '@/utils/date-utils';
import { parseSizeFromFile } from '@/utils/parse-utils';
import { getNeDirZip, getNeFile, listNeFiles } from '@/api/tool/neFile'; import { getNeDirZip, getNeFile, listNeFiles } from '@/api/tool/neFile';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import ViewDrawer from '@/views/ne/neFile/components/ViewDrawer.vue'; import ViewDrawer from '@/views/ne/neFile/components/ViewDrawer.vue';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import useTabsStore from '@/store/modules/tabs'; import useTabsStore from '@/store/modules/tabs';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
const tabsStore = useTabsStore(); const tabsStore = useTabsStore();
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
@@ -69,6 +70,9 @@ let tableColumns: ColumnsType = reactive([
title: t('views.logManage.neFile.size'), title: t('views.logManage.neFile.size'),
dataIndex: 'size', dataIndex: 'size',
align: 'left', align: 'left',
customRender(opt) {
return parseSizeFromFile(opt.value);
},
width: 100, width: 100,
}, },
{ {
@@ -243,7 +247,7 @@ function fnDirCD(dir: string, index?: number) {
queryParams.search = `${neType}_${queryParams.neId}`; queryParams.search = `${neType}_${queryParams.neId}`;
} else { } else {
nePathArr.value = [ nePathArr.value = [
`/tmp/omc/tcpdump/${neType.toLowerCase()}/${queryParams.neId}`, `/usr/local/omc/tcpdump/${neType.toLowerCase()}/${queryParams.neId}`,
]; ];
queryParams.search = ''; queryParams.search = '';
} }
@@ -269,7 +273,7 @@ function fnNeChange(keys: any, _: any) {
nePathArr.value = ['/tmp']; nePathArr.value = ['/tmp'];
queryParams.search = `${neType}_${neId}`; queryParams.search = `${neType}_${neId}`;
} else { } else {
nePathArr.value = [`/tmp/omc/tcpdump/${neType.toLowerCase()}/${neId}`]; nePathArr.value = [`/usr/local/omc/tcpdump/${neType.toLowerCase()}/${neId}`];
queryParams.search = ''; queryParams.search = '';
} }
fnGetList(1); fnGetList(1);

View File

@@ -438,7 +438,7 @@ function fnDownPCAP(row?: Record<string, any>) {
); );
} else { } else {
const { neType, neId } = from.data; const { neType, neId } = from.data;
const path = `/tmp/omc/tcpdump/${neType.toLowerCase()}/${neId}/${taskCode}`; const path = `/usr/local/omc/tcpdump/${neType.toLowerCase()}/${neId}/${taskCode}`;
reqArr.push( reqArr.push(
getNeDirZip({ getNeDirZip({
neType, neType,
@@ -518,7 +518,7 @@ function fnModalVisibleByVive(id: string | number) {
const from = modalState.from[id]; const from = modalState.from[id];
if (!from) return; if (!from) return;
const { neType, neId } = from.data; const { neType, neId } = from.data;
const path = `/tmp/omc/tcpdump/${neType.toLowerCase()}/${neId}/${ const path = `/usr/local/omc/tcpdump/${neType.toLowerCase()}/${neId}/${
from.taskCode from.taskCode
}`; }`;
const files = from.taskFiles.filter(f => f.endsWith('log')); const files = from.taskFiles.filter(f => f.endsWith('log'));

View File

@@ -11,7 +11,7 @@ import { parseDateToStr } from '@/utils/date-utils';
import { MENU_PATH_INLINE } from '@/constants/menu-constants'; import { MENU_PATH_INLINE } from '@/constants/menu-constants';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useNeListStore from '@/store/modules/ne_list'; import useNeStore from '@/store/modules/ne';
import { import {
addTraceTask, addTraceTask,
delTraceTask, delTraceTask,
@@ -23,7 +23,7 @@ import useDictStore from '@/store/modules/dict';
import { regExpIPv4 } from '@/utils/regular-utils'; import { regExpIPv4 } from '@/utils/regular-utils';
import dayjs, { Dayjs } from 'dayjs'; import dayjs, { Dayjs } from 'dayjs';
import { parseObjHumpToLine } from '@/utils/parse-utils'; import { parseObjHumpToLine } from '@/utils/parse-utils';
const neListStore = useNeListStore(); const neListStore = useNeStore();
const { getDict } = useDictStore(); const { getDict } = useDictStore();
const { t } = useI18n(); const { t } = useI18n();
const router = useRouter(); const router = useRouter();