Compare commits
263
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
618499e777 | ||
|
|
71c0306587 | ||
|
|
a3cd8f05fb | ||
|
|
d8ca0ca5ef | ||
|
|
da08e1cc5b | ||
|
|
8e4c5d0b90 | ||
|
|
467c93f710 | ||
|
|
22ced8bdb2 | ||
|
|
2ee26a6958 | ||
|
|
c63e892544 | ||
|
|
cce3088f73 | ||
|
|
2211896768 | ||
|
|
5bb3cd814c | ||
|
|
266d816a21 | ||
|
|
90c64c029a | ||
|
|
d06e2da72e | ||
|
|
7714d506c4 | ||
|
|
0b7a198235 | ||
|
|
68362ba3e3 | ||
|
|
a9633e652f | ||
|
|
6592561bca | ||
|
|
09e0353053 | ||
|
|
c1e95fd1e9 | ||
|
|
89857e0c1b | ||
|
|
7aa37ee330 | ||
|
|
4c16888184 | ||
|
|
a61716d40d | ||
|
|
3f02cb628b | ||
|
|
22805924fb | ||
|
|
e00229e5ff | ||
|
|
939a235a87 | ||
|
|
cd49162dfc | ||
|
|
b7f2df5d1c | ||
|
|
8b24bc55b9 | ||
|
|
9f2b80718e | ||
|
|
38cb406687 | ||
|
|
c25fe63a26 | ||
|
|
b84d6bb9fc | ||
|
|
b325cde5c0 | ||
|
|
34266da44e | ||
|
|
d82d6b7b47 | ||
|
|
b1c7a068cf | ||
|
|
c155160cf7 | ||
|
|
2ae4559958 | ||
|
|
782283bba6 | ||
|
|
1b50708786 | ||
|
|
206d3755a0 | ||
|
|
6470effbda | ||
|
|
f94b1ef44a | ||
|
|
7c78eab431 | ||
|
|
814b7b0058 | ||
|
|
624f67ecca | ||
|
|
c1a9497b77 | ||
|
|
1ad2ed2d26 | ||
|
|
48f278997f | ||
|
|
9b9d6222e1 | ||
|
|
2e8a878365 | ||
|
|
bc59dc67e6 | ||
|
|
df6022b4a8 | ||
|
|
f2c67d087b | ||
|
|
7a0298a419 | ||
|
|
b40e798090 | ||
|
|
d48d5d6c95 | ||
|
|
69f3347a4d | ||
|
|
85ae7dc5ea | ||
|
|
531cd6d03d | ||
|
|
9fd8c4597a | ||
|
|
7060a3d887 | ||
|
|
c12ffa583c | ||
|
|
05aabb8c61 | ||
|
|
6b461ead7c | ||
|
|
7c54e372e5 | ||
|
|
5be95a7af6 | ||
|
|
08515541b4 | ||
|
|
3948924f61 | ||
|
|
ce1944881a | ||
|
|
f6122c0758 | ||
|
|
3d3f4c2cc6 | ||
|
|
e8e5b92a57 | ||
|
|
4ad704398d | ||
|
|
26289b7787 | ||
|
|
7ad8c1706e | ||
|
|
424a596613 | ||
|
|
6d5b9f417c | ||
|
|
7278e24dce | ||
|
|
76839ae18a | ||
|
|
c8a6aa3210 | ||
|
|
9b4bbcedc5 | ||
|
|
3b793c107c | ||
|
|
a076e6d079 | ||
|
|
fb2a7c51f9 | ||
|
|
1e2c2b5170 | ||
|
|
56833b654e | ||
|
|
f50e02e6e7 | ||
|
|
52cc24813f | ||
|
|
c8a0d4c3f7 | ||
|
|
7560f21f11 | ||
|
|
8a5f80fe47 | ||
|
|
29eb1f08b1 | ||
|
|
9981de2271 | ||
|
|
207acb3f3d | ||
|
|
873a76f48f | ||
|
|
4ca700092a | ||
|
|
ad9f8574bd | ||
|
|
75faae6d7c | ||
|
|
c88c146a5e | ||
|
|
c65cda1468 | ||
|
|
d8059341fe | ||
|
|
ad86bee5f9 | ||
|
|
f44cc44a1b | ||
|
|
ad93588796 | ||
|
|
b5f6a5d24a | ||
|
|
fa4be253f7 | ||
|
|
2db0220c98 | ||
|
|
05fd678ce2 | ||
|
|
165b28bab1 | ||
|
|
dc67cdc262 | ||
|
|
c97394a0ed | ||
|
|
6b9297d30e | ||
|
|
ace7f26b53 | ||
|
|
976f72f79a | ||
|
|
530e7fd43f | ||
|
|
b76fed7dcf | ||
|
|
60a26dd015 | ||
|
|
7bdfc257c1 | ||
|
|
e3395b47cf | ||
|
|
4c9b4de12f | ||
|
|
1cfe5e2777 | ||
|
|
0cae26a1ee | ||
|
|
ed4d556384 | ||
|
|
6d9d7362a4 | ||
|
|
5a40733f20 | ||
|
|
45ee884529 | ||
|
|
7de3f7f05d | ||
|
|
97bb4db1eb | ||
|
|
fc6dfe9894 | ||
|
|
607660124a | ||
|
|
c50b3add95 | ||
|
|
2f7f0e9e20 | ||
|
|
6875ffd113 | ||
|
|
44844bfa7f | ||
|
|
21ab066761 | ||
|
|
83bdf289fa | ||
|
|
d7aa0fc91a | ||
|
|
a6be5190ec | ||
|
|
03cd06e835 | ||
|
|
2d7fe5a73b | ||
|
|
dd5604c8b7 | ||
|
|
7bf2672981 | ||
|
|
6e616c63f0 | ||
|
|
3ded481cce | ||
|
|
1baff582d8 | ||
|
|
957868cc27 | ||
|
|
efb98ac577 | ||
|
|
ff228daae7 | ||
|
|
c93e693517 | ||
|
|
55863c1c58 | ||
|
|
8a2d6c91ba | ||
|
|
86a939f206 | ||
|
|
2b86f724b1 | ||
|
|
68fbc45b7c | ||
|
|
4629ef28ff | ||
|
|
e3a11b0ede | ||
|
|
3df9ee4f3a | ||
|
|
e64d558c27 | ||
|
|
5a2aa383fe | ||
|
|
fe9f458465 | ||
|
|
8e2e9aec67 | ||
|
|
ad48e8e2e1 | ||
|
|
6f8b1000ba | ||
|
|
f5549992c2 | ||
|
|
19771ea6dc | ||
|
|
5965737384 | ||
|
|
b3cb40fd8c | ||
|
|
0ab5141369 | ||
|
|
a23284da4c | ||
|
|
1c8cc13436 | ||
|
|
e6a439faea | ||
|
|
f8b1b1f6c3 | ||
|
|
3844e07258 | ||
|
|
1fab9b3d97 | ||
|
|
1bfacbf2e0 | ||
|
|
c01f9f3830 | ||
|
|
28f9d365fd | ||
|
|
1085fa16aa | ||
|
|
e351960229 | ||
|
|
03caa354da | ||
|
|
34754ea0b6 | ||
|
|
86e1f07f08 | ||
|
|
2add7547d6 | ||
|
|
ecb89e9f26 | ||
|
|
7a9b38dc66 | ||
|
|
979b18092d | ||
|
|
ba43a647dd | ||
|
|
3be14590c6 | ||
|
|
857f8c4313 | ||
|
|
c9c39d2d4a | ||
|
|
845084f77f | ||
|
|
becba4919e | ||
|
|
b797055df9 | ||
|
|
8101c852c8 | ||
|
|
9bbeb9fc9a | ||
|
|
19a9bd3f5c | ||
|
|
399bddc635 | ||
|
|
5a67a1a51c | ||
|
|
9a168d2ba0 | ||
|
|
e42a620aed | ||
|
|
eb902594b8 | ||
|
|
817fd97496 | ||
|
|
96aab47003 | ||
|
|
432666b1ab | ||
|
|
662583c73b | ||
|
|
f73c21e6e6 | ||
|
|
17e72f1db1 | ||
|
|
55d4a36efb | ||
|
|
d3794ba904 | ||
|
|
832f18e2ee | ||
|
|
cd2e282624 | ||
|
|
3db88f1d3a | ||
|
|
f291bb0907 | ||
|
|
69c32b2593 | ||
|
|
1a2939ab01 | ||
|
|
8bf4a2a9ce | ||
|
|
efd389f98a | ||
|
|
f1125cc042 | ||
|
|
f1a0e200dc | ||
|
|
70c025f0f5 | ||
|
|
b9f0a3923d | ||
|
|
5c942c9ef7 | ||
|
|
4294fe82c5 | ||
|
|
4e7fb90544 | ||
|
|
f050e500e9 | ||
|
|
6bc10babba | ||
|
|
4d36f9952a | ||
|
|
b03f4bb1d6 | ||
|
|
4aaedf0f77 | ||
|
|
c1ea851705 | ||
|
|
47103249ef | ||
|
|
2642f18204 | ||
|
|
e2e22eabf5 | ||
|
|
325ecc8029 | ||
|
|
dc6f4560d5 | ||
|
|
3970797d5b | ||
|
|
73776ed0f9 | ||
|
|
aca842f8c2 | ||
|
|
612fb77861 | ||
|
|
6ba695ceaf | ||
|
|
070f77d3b8 | ||
|
|
15de63212f | ||
|
|
2202540763 | ||
|
|
c674b9b3f9 | ||
|
|
43d30e7bfa | ||
|
|
cd0633d519 | ||
|
|
b8bff2a159 | ||
|
|
638f890228 | ||
|
|
4460f7201c | ||
|
|
d0bbfafedc | ||
|
|
16dc1c2e20 | ||
|
|
73ed5f5285 | ||
|
|
50cb92a95b | ||
|
|
3888fd2bca | ||
|
|
4194d8cca6 | ||
|
|
ac84a0ca0a |
No files matched your search
+1
-1
@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network EMS"
|
|||||||
VITE_APP_CODE = "CN EMS"
|
VITE_APP_CODE = "CN EMS"
|
||||||
|
|
||||||
# 应用版本
|
# 应用版本
|
||||||
VITE_APP_VERSION = "2.240330.1"
|
VITE_APP_VERSION = "2.240530.1"
|
||||||
|
|
||||||
# 接口基础URL地址-不带/后缀
|
# 接口基础URL地址-不带/后缀
|
||||||
VITE_API_BASE_URL = "/omc-api"
|
VITE_API_BASE_URL = "/omc-api"
|
||||||
+1
-1
@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network EMS"
|
|||||||
VITE_APP_CODE = "CN EMS"
|
VITE_APP_CODE = "CN EMS"
|
||||||
|
|
||||||
# 应用版本
|
# 应用版本
|
||||||
VITE_APP_VERSION = "2.240330.1"
|
VITE_APP_VERSION = "2.240530.1"
|
||||||
|
|
||||||
# 接口基础URL地址-不带/后缀
|
# 接口基础URL地址-不带/后缀
|
||||||
VITE_API_BASE_URL = "/omc-api"
|
VITE_API_BASE_URL = "/omc-api"
|
||||||
+14
-13
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ems_frontend_vue3",
|
"name": "ems_frontend_vue3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "核心网管理平台",
|
"description": "Core Network EMS",
|
||||||
"author": "TsMask",
|
"author": "TsMask",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
@@ -15,17 +15,20 @@
|
|||||||
"@ant-design/icons-vue": "^7.0.1",
|
"@ant-design/icons-vue": "^7.0.1",
|
||||||
"@antv/g6": "~4.8.24",
|
"@antv/g6": "~4.8.24",
|
||||||
"@codemirror/lang-javascript": "^6.2.1",
|
"@codemirror/lang-javascript": "^6.2.1",
|
||||||
"@codemirror/lang-yaml": "^6.0.0",
|
"@codemirror/lang-yaml": "^6.1.1",
|
||||||
"@codemirror/merge": "^6.6.1",
|
"@codemirror/merge": "^6.6.1",
|
||||||
"@codemirror/theme-one-dark": "^6.1.2",
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
"@tato30/vue-pdf": "^1.9.6",
|
"@tato30/vue-pdf": "^1.9.6",
|
||||||
"@vueuse/core": "~10.9.0",
|
"@vueuse/core": "~10.9.0",
|
||||||
|
"@xterm/xterm": "^5.5.0",
|
||||||
|
"@xterm/addon-fit": "^0.10.0",
|
||||||
"ant-design-vue": "^3.2.20",
|
"ant-design-vue": "^3.2.20",
|
||||||
"antdv-pro-layout": "^3.2.6",
|
"antdv-pro-layout": "^3.2.6",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.11",
|
||||||
"echarts": "~5.5.0",
|
"echarts": "~5.5.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
|
"intl-tel-input": "~22.0.2",
|
||||||
"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",
|
||||||
@@ -33,12 +36,10 @@
|
|||||||
"p-queue": "^8.0.1",
|
"p-queue": "^8.0.1",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"vue": "~3.3.13",
|
"vue": "~3.3.13",
|
||||||
"vue-i18n": "~9.10.0",
|
"vue-i18n": "^9.13.1",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.3.2",
|
||||||
"vue3-smooth-dnd": "^0.0.6",
|
"vue3-smooth-dnd": "^0.0.6",
|
||||||
"xlsx": "^0.18.5",
|
"xlsx": "~0.18.5"
|
||||||
"xterm": "^5.3.0",
|
|
||||||
"xterm-addon-fit": "^0.8.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/file-saver": "^2.0.7",
|
"@types/file-saver": "^2.0.7",
|
||||||
@@ -47,10 +48,10 @@
|
|||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"less": "^4.2.0",
|
"less": "^4.2.0",
|
||||||
"typescript": "^5.4.3",
|
"typescript": "~5.4.5",
|
||||||
"unplugin-vue-components": "^0.26.0",
|
"unplugin-vue-components": "~0.26.0",
|
||||||
"vite": "^5.2.6",
|
"vite": "~5.2.10",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "~0.5.1",
|
||||||
"vue-tsc": "^1.8.27"
|
"vue-tsc": "~1.8.27"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -4,13 +4,15 @@ import { usePrimaryColor } from '@/hooks/useTheme';
|
|||||||
import zhCN from 'ant-design-vue/lib/locale/zh_CN';
|
import zhCN from 'ant-design-vue/lib/locale/zh_CN';
|
||||||
import enUS from 'ant-design-vue/lib/locale/en_US';
|
import enUS from 'ant-design-vue/lib/locale/en_US';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import advancedFormat from 'dayjs/plugin/advancedFormat';
|
||||||
import 'dayjs/locale/zh-cn';
|
import 'dayjs/locale/zh-cn';
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import useAppStore from '@/store/modules/app';
|
import useAppStore from '@/store/modules/app';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
const { t, currentLocale } = useI18n();
|
const { t, currentLocale } = useI18n();
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
dayjs.extend(advancedFormat)
|
||||||
dayjs.locale('zh-cn'); // 默认中文
|
dayjs.locale('zh-cn'); // 默认中文
|
||||||
usePrimaryColor(); // 载入用户自定义主题色
|
usePrimaryColor(); // 载入用户自定义主题色
|
||||||
|
|
||||||
|
|||||||
+177
-158
@@ -38,13 +38,13 @@ export async function getParamConfigTopTab(neType: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询配置参数标签栏对应信息
|
* 查询配置参数标签栏对应信息和规则
|
||||||
* @param neType 网元类型
|
* @param neType 网元类型
|
||||||
* @param topTag
|
* @param topTag
|
||||||
* @param neId
|
* @param neId
|
||||||
* @returns object { wrRule, dataArr }
|
* @returns object { wrRule, dataArr }
|
||||||
*/
|
*/
|
||||||
async function getParamConfigInfo(
|
async function getParamConfigInfoAndRule(
|
||||||
neType: string,
|
neType: string,
|
||||||
topTag: string,
|
topTag: string,
|
||||||
neId: string
|
neId: string
|
||||||
@@ -57,7 +57,6 @@ async function getParamConfigInfo(
|
|||||||
params: {
|
params: {
|
||||||
SQL: `SELECT param_json FROM param_config WHERE ne_type = '${neType}' AND top_tag='${topTag}'`,
|
SQL: `SELECT param_json FROM param_config WHERE ne_type = '${neType}' AND top_tag='${topTag}'`,
|
||||||
},
|
},
|
||||||
timeout: 1_000,
|
|
||||||
}),
|
}),
|
||||||
// 获取对应信息
|
// 获取对应信息
|
||||||
request({
|
request({
|
||||||
@@ -66,7 +65,6 @@ async function getParamConfigInfo(
|
|||||||
params: {
|
params: {
|
||||||
ne_id: neId,
|
ne_id: neId,
|
||||||
},
|
},
|
||||||
timeout: 1_000,
|
|
||||||
}),
|
}),
|
||||||
]).then(resArr => {
|
]).then(resArr => {
|
||||||
let wrRule: Record<string, any> = {};
|
let wrRule: Record<string, any> = {};
|
||||||
@@ -108,159 +106,6 @@ async function getParamConfigInfo(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询配置参数标签栏对应信息-表格处理
|
|
||||||
* @param neType 网元类型
|
|
||||||
* @param topTag
|
|
||||||
* @param neId
|
|
||||||
* @returns object
|
|
||||||
*/
|
|
||||||
export async function getParamConfigInfoTable(
|
|
||||||
neType: string,
|
|
||||||
topTag: string,
|
|
||||||
neId: string
|
|
||||||
) {
|
|
||||||
const { wrRule, dataArr } = await getParamConfigInfo(neType, topTag, neId);
|
|
||||||
|
|
||||||
// UPF参数不统一
|
|
||||||
// if (neType === 'UPF') {
|
|
||||||
// if (Reflect.has(wrRule, 'list')) {
|
|
||||||
// for (const arr of wrRule['list']) {
|
|
||||||
// arr['name'] = parseFirstLower(arr['name']);
|
|
||||||
// }
|
|
||||||
// for (const item of dataArr) {
|
|
||||||
// for (const k in item) {
|
|
||||||
// item[parseFirstLower(k)] = item[k];
|
|
||||||
// Reflect.deleteProperty(item, k);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (Reflect.has(wrRule, 'array')) {
|
|
||||||
// for (const arr of wrRule['array']) {
|
|
||||||
// if (Array.isArray(arr['array'])) {
|
|
||||||
// for (const child of arr['array']) {
|
|
||||||
// child['name'] = parseFirstLower(child['name']);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// arr['name'] = parseFirstLower(arr['name']);
|
|
||||||
// }
|
|
||||||
// for (const item of dataArr) {
|
|
||||||
// for (const k in item) {
|
|
||||||
// // 处理子列表
|
|
||||||
// if (Array.isArray(item[k])) {
|
|
||||||
// for (const child of item[k]) {
|
|
||||||
// for (const childKey in child) {
|
|
||||||
// child[parseFirstLower(childKey)] = child[childKey];
|
|
||||||
// Reflect.deleteProperty(child, childKey);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// item[parseFirstLower(k)] = item[k];
|
|
||||||
// Reflect.deleteProperty(item, k);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 拼装数据
|
|
||||||
const result = {
|
|
||||||
code: RESULT_CODE_SUCCESS,
|
|
||||||
msg: RESULT_MSG_SUCCESS,
|
|
||||||
data: {
|
|
||||||
type: 'list' as 'list' | 'array',
|
|
||||||
data: [] as any[],
|
|
||||||
dataRule: {},
|
|
||||||
columns: [] as any[],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// kv单列表
|
|
||||||
if (Reflect.has(wrRule, 'list')) {
|
|
||||||
result.data.type = 'list';
|
|
||||||
const ruleArr = Object.freeze(wrRule['list']);
|
|
||||||
|
|
||||||
// 列表项数据
|
|
||||||
let dataList = [];
|
|
||||||
for (const item of dataArr) {
|
|
||||||
for (const key of Object.keys(item)) {
|
|
||||||
// 规则为准
|
|
||||||
for (const rule of ruleArr) {
|
|
||||||
if (rule['name'] === key) {
|
|
||||||
const ruleItem = Object.assign({ optional: 'true' }, rule, {
|
|
||||||
value: item[key],
|
|
||||||
});
|
|
||||||
dataList.push(ruleItem);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.data.data = dataList;
|
|
||||||
|
|
||||||
// 列表字段
|
|
||||||
result.data.columns = [
|
|
||||||
{
|
|
||||||
title: 'Key',
|
|
||||||
dataIndex: 'display',
|
|
||||||
align: 'left',
|
|
||||||
width: '30%',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Value',
|
|
||||||
dataIndex: 'value',
|
|
||||||
align: 'left',
|
|
||||||
width: '70%',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 多列表
|
|
||||||
if (Reflect.has(wrRule, 'array')) {
|
|
||||||
result.data.type = 'array';
|
|
||||||
const ruleArr = Object.freeze(wrRule['array']);
|
|
||||||
|
|
||||||
// 列表项数据
|
|
||||||
const dataArray = [];
|
|
||||||
for (const item of dataArr) {
|
|
||||||
let record: Record<string, any> = {};
|
|
||||||
for (const key of Object.keys(item)) {
|
|
||||||
// 规则为准
|
|
||||||
for (const rule of ruleArr) {
|
|
||||||
if (rule['name'] === key) {
|
|
||||||
const ruleItem = Object.assign({ optional: 'true' }, rule, {
|
|
||||||
value: item[key],
|
|
||||||
});
|
|
||||||
record[ruleItem.name] = ruleItem;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dataArray.push(record);
|
|
||||||
}
|
|
||||||
result.data.data = dataArray;
|
|
||||||
|
|
||||||
// 无数据时,用于新增
|
|
||||||
let dataRule: Record<string, any> = {};
|
|
||||||
for (const rule of ruleArr) {
|
|
||||||
dataRule[rule.name] = rule;
|
|
||||||
}
|
|
||||||
result.data.dataRule = dataRule;
|
|
||||||
|
|
||||||
// 列表字段
|
|
||||||
const columns: Record<string, any>[] = [];
|
|
||||||
for (const rule of ruleArr) {
|
|
||||||
columns.push({
|
|
||||||
title: rule.display,
|
|
||||||
dataIndex: rule.name,
|
|
||||||
align: 'left',
|
|
||||||
width: 5,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
result.data.columns = columns;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询配置参数标签栏对应信息-表单结构处理
|
* 查询配置参数标签栏对应信息-表单结构处理
|
||||||
* @param neType 网元类型
|
* @param neType 网元类型
|
||||||
@@ -273,7 +118,11 @@ export async function getParamConfigInfoForm(
|
|||||||
topTag: string,
|
topTag: string,
|
||||||
neId: string
|
neId: string
|
||||||
) {
|
) {
|
||||||
const { wrRule, dataArr } = await getParamConfigInfo(neType, topTag, neId);
|
const { wrRule, dataArr } = await getParamConfigInfoAndRule(
|
||||||
|
neType,
|
||||||
|
topTag,
|
||||||
|
neId
|
||||||
|
);
|
||||||
|
|
||||||
// 拼装数据
|
// 拼装数据
|
||||||
const result = {
|
const result = {
|
||||||
@@ -340,6 +189,35 @@ export async function getParamConfigInfoForm(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询配置参数标签栏对应信息
|
||||||
|
* @param neType 网元类型
|
||||||
|
* @param topTag
|
||||||
|
* @param neId
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export async function getParamConfigInfo(
|
||||||
|
neType: string,
|
||||||
|
topTag: string,
|
||||||
|
neId: string
|
||||||
|
) {
|
||||||
|
// 发起请求
|
||||||
|
const result = await request({
|
||||||
|
url: `/api/rest/systemManagement/v1/elementType/${neType.toLowerCase()}/objectType/config/${topTag}`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
ne_id: neId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// 解析数据
|
||||||
|
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
|
||||||
|
return Object.assign(result, {
|
||||||
|
data: parseObjLineToHump(result.data.data),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询配置参数标签栏对应信息子节点
|
* 查询配置参数标签栏对应信息子节点
|
||||||
* @param neType 网元类型
|
* @param neType 网元类型
|
||||||
@@ -462,3 +340,144 @@ export async function updateNeConfigReload(neType: string, neId: string) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从参数配置PCF中获取对应信息提供给PCC用户策略输入框
|
||||||
|
* @param neType 网元类型
|
||||||
|
* @param topTag
|
||||||
|
* @param neId
|
||||||
|
* @returns object { wrRule, dataArr }
|
||||||
|
*/
|
||||||
|
export async function getPCCRule(neId: any) {
|
||||||
|
return await Promise.allSettled([
|
||||||
|
// 获取参数规则
|
||||||
|
request({
|
||||||
|
url: `/api/rest/systemManagement/v1/elementType/pcf/objectType/config/pccRules`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
ne_id: neId,
|
||||||
|
},
|
||||||
|
timeout: 1_000,
|
||||||
|
}),
|
||||||
|
// 获取对应信息
|
||||||
|
request({
|
||||||
|
url: `/api/rest/systemManagement/v1/elementType/pcf/objectType/config/sessionRules`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
ne_id: neId,
|
||||||
|
},
|
||||||
|
timeout: 1_000,
|
||||||
|
}),
|
||||||
|
request({
|
||||||
|
url: `/api/rest/systemManagement/v1/elementType/pcf/objectType/config/qosTemplate`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
ne_id: neId,
|
||||||
|
},
|
||||||
|
timeout: 1_000,
|
||||||
|
}),
|
||||||
|
request({
|
||||||
|
url: `/api/rest/systemManagement/v1/elementType/pcf/objectType/config/headerEnrichTemplate`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
ne_id: neId,
|
||||||
|
},
|
||||||
|
timeout: 1_000,
|
||||||
|
}),
|
||||||
|
request({
|
||||||
|
url: `/api/rest/systemManagement/v1/elementType/pcf/objectType/config/serviceAreaRestriction`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
ne_id: neId,
|
||||||
|
},
|
||||||
|
timeout: 1_000,
|
||||||
|
}),
|
||||||
|
]).then(resArr => {
|
||||||
|
let pccJson: any = new Map();
|
||||||
|
let sessJson: any = new Map();
|
||||||
|
let qosJson: any = new Map();
|
||||||
|
let headerJson: any = new Map();
|
||||||
|
let sarJson: any = new Map();
|
||||||
|
// 规则数据
|
||||||
|
if (resArr[0].status === 'fulfilled') {
|
||||||
|
const itemV = resArr[0].value;
|
||||||
|
// 解析数据
|
||||||
|
if (
|
||||||
|
itemV.code === RESULT_CODE_SUCCESS &&
|
||||||
|
Array.isArray(itemV.data?.data)
|
||||||
|
) {
|
||||||
|
let itemData = itemV.data.data;
|
||||||
|
itemData.forEach((item: any) => {
|
||||||
|
pccJson.set(item.ruleId, { value: item.ruleId, label: item.ruleId });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resArr[1].status === 'fulfilled') {
|
||||||
|
const itemV = resArr[1].value;
|
||||||
|
// 解析数据
|
||||||
|
if (
|
||||||
|
itemV.code === RESULT_CODE_SUCCESS &&
|
||||||
|
Array.isArray(itemV.data?.data)
|
||||||
|
) {
|
||||||
|
let itemData = itemV.data.data;
|
||||||
|
itemData.forEach((item: any) => {
|
||||||
|
sessJson.set(item.ruleId, { value: item.ruleId, label: item.ruleId });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resArr[2].status === 'fulfilled') {
|
||||||
|
const itemV = resArr[2].value;
|
||||||
|
// 解析数据
|
||||||
|
if (
|
||||||
|
itemV.code === RESULT_CODE_SUCCESS &&
|
||||||
|
Array.isArray(itemV.data?.data)
|
||||||
|
) {
|
||||||
|
let itemData = itemV.data.data;
|
||||||
|
itemData.forEach((item: any) => {
|
||||||
|
qosJson.set(item.qosId, { value: item.qosId, label: item.qosId });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resArr[3].status === 'fulfilled') {
|
||||||
|
const itemV = resArr[3].value;
|
||||||
|
// 解析数据
|
||||||
|
if (
|
||||||
|
itemV.code === RESULT_CODE_SUCCESS &&
|
||||||
|
Array.isArray(itemV.data?.data)
|
||||||
|
) {
|
||||||
|
let itemData = itemV.data.data;
|
||||||
|
itemData.forEach((item: any) => {
|
||||||
|
headerJson.set(item.templateName, {
|
||||||
|
value: item.templateName,
|
||||||
|
label: item.templateName,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resArr[4].status === 'fulfilled') {
|
||||||
|
const itemV = resArr[4].value;
|
||||||
|
// 解析数据
|
||||||
|
if (
|
||||||
|
itemV.code === RESULT_CODE_SUCCESS &&
|
||||||
|
Array.isArray(itemV.data?.data)
|
||||||
|
) {
|
||||||
|
let itemData = itemV.data.data;
|
||||||
|
itemData.forEach((item: any) => {
|
||||||
|
sarJson.set(item.name, { value: item.name, label: item.name });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pccJson = Array.from(pccJson.values());
|
||||||
|
sessJson = Array.from(sessJson.values());
|
||||||
|
qosJson = Array.from(qosJson.values());
|
||||||
|
headerJson = Array.from(headerJson.values());
|
||||||
|
sarJson = Array.from(sarJson.values());
|
||||||
|
|
||||||
|
return { pccJson, sessJson, qosJson, headerJson, sarJson };
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ export async function listLicense(query: Record<string, any>) {
|
|||||||
|
|
||||||
// 分页
|
// 分页
|
||||||
const pageNum = (query.pageNum - 1) * query.pageSize;
|
const pageNum = (query.pageNum - 1) * query.pageSize;
|
||||||
const limtSql = ` order by created_at desc limit ${pageNum},${query.pageSize} `;
|
const limtSql = ` order by create_time desc limit ${pageNum},${query.pageSize} `;
|
||||||
|
|
||||||
// 发起请求
|
// 发起请求
|
||||||
const result = await request({
|
const result = await request({
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
} from '@/constants/result-constants';
|
} from '@/constants/result-constants';
|
||||||
import { language, request } from '@/plugins/http-fetch';
|
import { language, request } from '@/plugins/http-fetch';
|
||||||
import { parseObjLineToHump } from '@/utils/parse-utils';
|
import { parseObjLineToHump } from '@/utils/parse-utils';
|
||||||
|
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询网元列表
|
* 查询网元列表
|
||||||
@@ -15,24 +16,6 @@ export async function listNeInfo(query: Record<string, any>) {
|
|||||||
let totalSQL = 'select count(*) as total from ne_info where 1=1 ';
|
let totalSQL = 'select count(*) as total from ne_info where 1=1 ';
|
||||||
let rowsSQL = 'select * from ne_info where 1=1 ';
|
let rowsSQL = 'select * from ne_info where 1=1 ';
|
||||||
|
|
||||||
// 系统特定顺序
|
|
||||||
const specificOrder = [
|
|
||||||
'OMC',
|
|
||||||
'MME',
|
|
||||||
'AMF',
|
|
||||||
'AUSF',
|
|
||||||
'UDM',
|
|
||||||
'SMF',
|
|
||||||
'PCF',
|
|
||||||
'UPF',
|
|
||||||
'NRF',
|
|
||||||
'NSSF',
|
|
||||||
'IMS',
|
|
||||||
'N3IWF',
|
|
||||||
'NEF',
|
|
||||||
'LMF',
|
|
||||||
];
|
|
||||||
|
|
||||||
// 查询
|
// 查询
|
||||||
let querySQL = '';
|
let querySQL = '';
|
||||||
if (query.neType) {
|
if (query.neType) {
|
||||||
@@ -70,8 +53,8 @@ export async function listNeInfo(query: Record<string, any>) {
|
|||||||
data.rows = itemData.map(v => parseObjLineToHump(v));
|
data.rows = itemData.map(v => parseObjLineToHump(v));
|
||||||
//通过sort进行冒泡排序
|
//通过sort进行冒泡排序
|
||||||
data.rows.sort((a: any, b: any) => {
|
data.rows.sort((a: any, b: any) => {
|
||||||
const typeA = specificOrder.indexOf(a.neType);
|
const typeA = NE_TYPE_LIST.indexOf(a.neType);
|
||||||
const typeB = specificOrder.indexOf(b.neType);
|
const typeB = NE_TYPE_LIST.indexOf(b.neType);
|
||||||
if (typeA === -1) return 1; // 如果不在特定顺序中,排到后面
|
if (typeA === -1) return 1; // 如果不在特定顺序中,排到后面
|
||||||
if (typeB === -1) return -1; // 如果不在特定顺序中,排到后面
|
if (typeB === -1) return -1; // 如果不在特定顺序中,排到后面
|
||||||
return typeA - typeB;
|
return typeA - typeB;
|
||||||
@@ -156,7 +139,7 @@ export async function delNeInfo(data: Record<string, any>) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出网元配置文件
|
* 导出网元配置文件
|
||||||
* @param
|
* @param data data {neType neId}
|
||||||
* @returns bolb
|
* @returns bolb
|
||||||
*/
|
*/
|
||||||
export function exportSet(data: Record<string, any>) {
|
export function exportSet(data: Record<string, any>) {
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ export async function sendNeSoftware(data: Record<string, any>) {
|
|||||||
url: `/api/rest/systemManagement/v1/${data.neType}/software/${data.version}/${data.neId}`,
|
url: `/api/rest/systemManagement/v1/${data.neType}/software/${data.version}/${data.neId}`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
timeout: 180_000,
|
timeout: 180_000,
|
||||||
|
repeatSubmit: false,
|
||||||
});
|
});
|
||||||
// 解析数据
|
// 解析数据
|
||||||
if (result.code === RESULT_CODE_SUCCESS) {
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
@@ -130,6 +131,7 @@ export async function runNeSoftware(data: Record<string, any>) {
|
|||||||
url: `/api/rest/systemManagement/v1/${data.neType}/software/${data.version}/${data.neId}`,
|
url: `/api/rest/systemManagement/v1/${data.neType}/software/${data.version}/${data.neId}`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
timeout: 180_000,
|
timeout: 180_000,
|
||||||
|
repeatSubmit: false,
|
||||||
});
|
});
|
||||||
// 解析数据
|
// 解析数据
|
||||||
if (result.code === RESULT_CODE_SUCCESS) {
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
@@ -149,6 +151,7 @@ export async function backNeSoftware(data: Record<string, any>) {
|
|||||||
url: `/api/rest/systemManagement/v1/${data.neType}/software/${data.version}/${data.neId}`,
|
url: `/api/rest/systemManagement/v1/${data.neType}/software/${data.version}/${data.neId}`,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
timeout: 180_000,
|
timeout: 180_000,
|
||||||
|
repeatSubmit: false,
|
||||||
});
|
});
|
||||||
// 解析数据
|
// 解析数据
|
||||||
if (result.code === RESULT_CODE_SUCCESS) {
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ export async function exportAll(query: Record<string, any>) {
|
|||||||
* @returns bolb
|
* @returns bolb
|
||||||
*/
|
*/
|
||||||
export async function origGet() {
|
export async function origGet() {
|
||||||
let totalSQL = `select count(*) as value,orig_severity as name from alarm group by orig_severity`;
|
let totalSQL = `select count(*) as value,orig_severity as name from alarm WHERE alarm_status='1' and orig_severity!='Event' group by orig_severity`;
|
||||||
|
|
||||||
// 发起请求
|
// 发起请求
|
||||||
const result = await request({
|
const result = await request({
|
||||||
@@ -329,10 +329,10 @@ export async function origGet() {
|
|||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export async function top3Sel(filterFlag?: string) {
|
export async function top3Sel(filterFlag?: string) {
|
||||||
let filter = ` WHERE orig_severity='${filterFlag}'`;
|
let filter = ` WHERE alarm_status='1'and orig_severity='${filterFlag}'`;
|
||||||
if (!filterFlag) filter = '';
|
if (!filterFlag) filter = "WHERE alarm_status='1'";
|
||||||
|
|
||||||
let top3SQL = `select count(*) as value,ne_type as name from alarm ${filter} group by ne_type ORDER BY value desc limit 0,3 `;
|
let top3SQL = `select count(*) as value,ne_type as name from alarm ${filter} and orig_severity!='Event' group by ne_type ORDER BY value desc limit 0,3 `;
|
||||||
|
|
||||||
// 发起请求
|
// 发起请求
|
||||||
const result = await request({
|
const result = await request({
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { request } from '@/plugins/http-fetch';
|
||||||
|
import { parseObjLineToHump } from '@/utils/parse-utils';
|
||||||
|
import { parseDateToStr } from '@/utils/date-utils';
|
||||||
|
import useUserStore from '@/store/modules/user';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询列表
|
||||||
|
* @param query 查询参数
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export async function listAct(query: Record<string, any>) {
|
||||||
|
let totalSQL = `select count(*) as total from alarm_event where 1=1 `;
|
||||||
|
let rowsSQL = `select * from alarm_event where 1=1 `;
|
||||||
|
// 查询
|
||||||
|
let querySQL = '';
|
||||||
|
if (query.alarmCode) {
|
||||||
|
querySQL += ` and alarm_code = '${query.alarmCode}' `;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.alarmType) {
|
||||||
|
querySQL += ` and alarm_type = '${query.alarmType}' `;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.pvFlag) {
|
||||||
|
querySQL += ` and pv_flag = '${query.pvFlag}' `;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (query.neId) {
|
||||||
|
querySQL += ` and ne_id like '%${query.neId}%' `;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.neName) {
|
||||||
|
querySQL += ` and ne_name like '%${query.neName}%' `;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.neType) {
|
||||||
|
querySQL += ` and ne_type like '%${query.neType}%' `;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.beginTime && query.endTime) {
|
||||||
|
querySQL += ` and event_time BETWEEN '${query.beginTime}' and ' ${query.endTime}'`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
const pageNum = (query.pageNum - 1) * query.pageSize;
|
||||||
|
const limtSql = ` order by event_time desc limit ${pageNum},${query.pageSize} `;
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
const result = await request({
|
||||||
|
url: `/api/rest/databaseManagement/v1/select/omc_db/alarm_event`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
SQL: totalSQL + querySQL,
|
||||||
|
rowsSQL: rowsSQL + querySQL + limtSql,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 解析数据
|
||||||
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
|
const data: DataList = {
|
||||||
|
total: 0,
|
||||||
|
rows: [],
|
||||||
|
code: result.code,
|
||||||
|
msg: result.msg,
|
||||||
|
};
|
||||||
|
result.data.data.forEach((item: any) => {
|
||||||
|
console.log(item)
|
||||||
|
const itemData = item['alarm_event'];
|
||||||
|
if (Array.isArray(itemData)) {
|
||||||
|
if (itemData.length === 1 && itemData[0]['total'] >= 0) {
|
||||||
|
data.total = itemData[0]['total'];
|
||||||
|
} else {
|
||||||
|
data.rows = itemData.map(v => parseObjLineToHump(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件告警导出
|
||||||
|
* @param query 查询参数
|
||||||
|
* @returns bolb
|
||||||
|
*/
|
||||||
|
export async function exportAll(query: Record<string, any>) {
|
||||||
|
let rowsSQL = `select * from alarm_event where 1=1`;
|
||||||
|
// 查询
|
||||||
|
let querySQL = '';
|
||||||
|
querySQL += query.alarm_code
|
||||||
|
? ` and alarm_code = '${query.alarm_code}' `
|
||||||
|
: '';
|
||||||
|
querySQL += query.alarm_type
|
||||||
|
? ` and alarm_type = '${query.alarm_type}' `
|
||||||
|
: '';
|
||||||
|
querySQL += query.pv_flag ? ` and pv_flag = '${query.pv_flag}' ` : '';
|
||||||
|
querySQL += query.orig_severity
|
||||||
|
? ` and orig_severity in('${query.orig_severity}' )`
|
||||||
|
: '';
|
||||||
|
querySQL += query.ne_id ? ` and ne_id like '%${query.ne_id}%' ` : '';
|
||||||
|
querySQL += query.ne_name ? ` and ne_name like '%${query.ne_name}%' ` : '';
|
||||||
|
querySQL += query.ne_type ? ` and ne_type like '%${query.ne_type}%' ` : '';
|
||||||
|
querySQL +=
|
||||||
|
query.beginTime && query.endTime
|
||||||
|
? ` and event_time BETWEEN '${query.beginTime}' and ' ${query.endTime}'`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
const result = await request({
|
||||||
|
url: `/api/rest/databaseManagement/v1/select/omc_db/alarm_event`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
rowsSQL: rowsSQL + querySQL,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
|
let v = result.data.data[0];
|
||||||
|
const vArr = parseObjLineToHump(v['alarm_event']);
|
||||||
|
result.data = vArr == null ? [] : vArr;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+6
-21
@@ -1,29 +1,14 @@
|
|||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
import { request } from '@/plugins/http-fetch';
|
import { request } from '@/plugins/http-fetch';
|
||||||
import { parseDateToStr } from '@/utils/date-utils';
|
import { parseDateToStr } from '@/utils/date-utils';
|
||||||
|
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询公告列表
|
* 查询公告列表
|
||||||
* @param query 查询参数
|
* @param query 查询参数
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export async function listMain() {
|
export async function listMain() {
|
||||||
// 系统特定顺序
|
|
||||||
const specificOrder = [
|
|
||||||
'OMC',
|
|
||||||
'MME',
|
|
||||||
'AMF',
|
|
||||||
'AUSF',
|
|
||||||
'UDM',
|
|
||||||
'SMF',
|
|
||||||
'PCF',
|
|
||||||
'UPF',
|
|
||||||
'NRF',
|
|
||||||
'NSSF',
|
|
||||||
'IMS',
|
|
||||||
'N3IWF',
|
|
||||||
'NEF',
|
|
||||||
'LMF',
|
|
||||||
];
|
|
||||||
const result = await request({
|
const result = await request({
|
||||||
url: '/api/rest/systemManagement/v1/elementType/all/objectType/systemState',
|
url: '/api/rest/systemManagement/v1/elementType/all/objectType/systemState',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
@@ -39,7 +24,6 @@ export async function listMain() {
|
|||||||
const serialNum = (value as any).serialNum;
|
const serialNum = (value as any).serialNum;
|
||||||
const version = (value as any).version;
|
const version = (value as any).version;
|
||||||
|
|
||||||
|
|
||||||
const errCode = systemState && systemState['errorCode'];
|
const errCode = systemState && systemState['errorCode'];
|
||||||
var time = new Date();
|
var time = new Date();
|
||||||
// console.log(key, value);
|
// console.log(key, value);
|
||||||
@@ -59,7 +43,7 @@ export async function listMain() {
|
|||||||
ipAddress,
|
ipAddress,
|
||||||
serialNum,
|
serialNum,
|
||||||
name: key.split('/').join('_'),
|
name: key.split('/').join('_'),
|
||||||
expiryDate:'-',
|
expiryDate: '-',
|
||||||
status: 'Abnormal',
|
status: 'Abnormal',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -67,8 +51,8 @@ export async function listMain() {
|
|||||||
});
|
});
|
||||||
//通过sort进行冒泡排序
|
//通过sort进行冒泡排序
|
||||||
mergedData.sort((a: any, b: any) => {
|
mergedData.sort((a: any, b: any) => {
|
||||||
const typeA = specificOrder.indexOf(a.name.split('_')[0]);
|
const typeA = NE_TYPE_LIST.indexOf(a.name.split('_')[0]);
|
||||||
const typeB = specificOrder.indexOf(b.name.split('_')[0]);
|
const typeB = NE_TYPE_LIST.indexOf(b.name.split('_')[0]);
|
||||||
if (typeA === -1) return 1; // 如果不在特定顺序中,排到后面
|
if (typeA === -1) return 1; // 如果不在特定顺序中,排到后面
|
||||||
if (typeB === -1) return -1; // 如果不在特定顺序中,排到后面
|
if (typeB === -1) return -1; // 如果不在特定顺序中,排到后面
|
||||||
return typeA - typeB;
|
return typeA - typeB;
|
||||||
@@ -104,5 +88,6 @@ export function getSysConf() {
|
|||||||
return request({
|
return request({
|
||||||
url: `/sys-conf`,
|
url: `/sys-conf`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
whithToken: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
import {
|
|
||||||
RESULT_CODE_ERROR,
|
|
||||||
RESULT_CODE_SUCCESS,
|
|
||||||
RESULT_MSG_ERROR,
|
|
||||||
} from '@/constants/result-constants';
|
|
||||||
import { language, request } from '@/plugins/http-fetch';
|
|
||||||
import { parseObjLineToHump } from '@/utils/parse-utils';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询用户会话列表
|
|
||||||
* @param query 查询参数
|
|
||||||
* @returns object
|
|
||||||
*/
|
|
||||||
export async function listSession(query: Record<string, any>) {
|
|
||||||
let totalSQL = 'select count(*) as total from session where 1=1 ';
|
|
||||||
let rowsSQL = 'select * from session where 1=1 ';
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
let querySQL = '';
|
|
||||||
if (query.accountId) {
|
|
||||||
querySQL += ` and account_id like '%${query.accountId}%' `;
|
|
||||||
}
|
|
||||||
if (query.ip) {
|
|
||||||
querySQL += ` and host like '%${query.ip}%' `;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分页
|
|
||||||
const pageNum = (query.pageNum - 1) * query.pageSize;
|
|
||||||
const limtSql = ` limit ${pageNum},${query.pageSize} `;
|
|
||||||
|
|
||||||
// 排序
|
|
||||||
let sortSql = ' order by login_time ';
|
|
||||||
if (query.sortOrder === 'desc') {
|
|
||||||
sortSql += ' desc ';
|
|
||||||
} else {
|
|
||||||
sortSql += ' asc ';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发起请求
|
|
||||||
const result = await request({
|
|
||||||
url: `/api/rest/databaseManagement/v1/omc_db/session`,
|
|
||||||
method: 'get',
|
|
||||||
params: {
|
|
||||||
totalSQL: totalSQL + querySQL,
|
|
||||||
rowsSQL: rowsSQL + querySQL + sortSql + limtSql,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 解析数据
|
|
||||||
if (result.code === RESULT_CODE_SUCCESS) {
|
|
||||||
const data: DataList = {
|
|
||||||
total: 0,
|
|
||||||
rows: [],
|
|
||||||
code: result.code,
|
|
||||||
msg: result.msg,
|
|
||||||
};
|
|
||||||
result.data.data.forEach((item: any) => {
|
|
||||||
const itemData = item['session'];
|
|
||||||
if (Array.isArray(itemData)) {
|
|
||||||
if (itemData.length === 1 && itemData[0]['total'] >= 0) {
|
|
||||||
data.total = itemData[0]['total'];
|
|
||||||
} else {
|
|
||||||
data.rows = itemData.map(v => parseObjLineToHump(v));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 强退用户会话
|
|
||||||
* @param tokenId 授权标识
|
|
||||||
* @returns object
|
|
||||||
*/
|
|
||||||
export async function logoutSession(id: string) {
|
|
||||||
const result = await request({
|
|
||||||
url: `/api/rest/databaseManagement/v1/omc_db/session?WHERE=id='${id}'`,
|
|
||||||
method: 'delete',
|
|
||||||
});
|
|
||||||
// 解析数据
|
|
||||||
if (result.code === RESULT_CODE_SUCCESS && result.data.data) {
|
|
||||||
let rows = result.data.data.affectedRows;
|
|
||||||
if (rows) {
|
|
||||||
delete result.data;
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
return { code: RESULT_CODE_ERROR, msg: RESULT_MSG_ERROR[language] };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
+51
-10
@@ -67,7 +67,7 @@ export function delNeInfo(infoIds: string | number) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询网元列表全部无分页
|
* 查询网元列表全部无分页
|
||||||
* @param query 查询参数 neType neId bandStatus
|
* @param query 查询参数 neType neId bandStatus bandHost
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export function listAllNeInfo(query: Record<string, any>) {
|
export function listAllNeInfo(query: Record<string, any>) {
|
||||||
@@ -99,7 +99,7 @@ export function stateNeInfo(neType: string, neId: string) {
|
|||||||
* @param neId 网元ID
|
* @param neId 网元ID
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export function getTypeAndIDNeInfo(neType: string, neId: string) {
|
export function getNeInfoByTypeAndID(neType: string, neId: string) {
|
||||||
return request({
|
return request({
|
||||||
url: '/ne/info/byTypeAndID',
|
url: '/ne/info/byTypeAndID',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
@@ -108,28 +108,69 @@ export function getTypeAndIDNeInfo(neType: string, neId: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网元端配置文件读取
|
* 网元端OAM配置文件读取
|
||||||
* @param neType 网元类型
|
* @param neType 网元类型
|
||||||
* @param neId 网元ID
|
* @param neId 网元ID
|
||||||
* @param filePath 不带文件时重新覆盖返回目录列表
|
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export function getConfigFile(neType: string, neId: string, filePath: string) {
|
export function getOAMFile(neType: string, neId: string) {
|
||||||
return request({
|
return request({
|
||||||
url: '/ne/info/configFile',
|
url: '/ne/info/oamFile',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: { neType, neId, filePath },
|
params: { neType, neId },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网元端配置文件写入
|
* 网元端配置文件写入
|
||||||
* @param data neType网元类型 neId网元ID filePath文件 content内容 sync同步到网元
|
* @param neType 网元类型
|
||||||
|
* @param neId 网元ID
|
||||||
|
* @param content 用json对象
|
||||||
|
* @param sync 同步到网元
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export function saveConfigFile(data: Record<string, any>) {
|
export function saveOAMFile(data: Record<string, any>) {
|
||||||
return request({
|
return request({
|
||||||
url: `/ne/info/configFile`,
|
url: `/ne/info/oamFile`,
|
||||||
|
method: 'put',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元端公共配置文件读取
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export function getPara5GFilee() {
|
||||||
|
return request({
|
||||||
|
url: '/ne/info/para5GFile',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元端公共配置文件写入
|
||||||
|
* @param content txt内容为字符串 其他文件格式都用json对象
|
||||||
|
* @param syncNe 同步到网元端 NeType@ NeId
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export function savePara5GFile(data: Record<string, any>) {
|
||||||
|
return request({
|
||||||
|
url: `/ne/info/para5GFile`,
|
||||||
|
method: 'put',
|
||||||
|
data: data,
|
||||||
|
timeout: 60_000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元服务操作
|
||||||
|
* @param data 对象 {neType,neId,action}
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export function serviceNeAction(data: Record<string, any>) {
|
||||||
|
return request({
|
||||||
|
url: `/ne/action/service`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data: data,
|
data: data,
|
||||||
});
|
});
|
||||||
|
|||||||
+8
-33
@@ -27,41 +27,16 @@ export function getNeLicense(licenseId: string | number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网元授权新增
|
* 网元neType和neID查询
|
||||||
* @param data 网元对象
|
* @param neType 网元类型
|
||||||
|
* @param neId 网元ID
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export function addNeLicense(data: Record<string, any>) {
|
export function getNeLicenseByTypeAndID(neType: string, neId: string) {
|
||||||
return request({
|
return request({
|
||||||
url: `/ne/license`,
|
url: `/ne/license/byTypeAndID`,
|
||||||
method: 'post',
|
method: 'get',
|
||||||
data: data,
|
params: { neType, neId },
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 网元授权修改
|
|
||||||
* @param data 网元对象
|
|
||||||
* @returns object
|
|
||||||
*/
|
|
||||||
export function updateNeLicense(data: Record<string, any>) {
|
|
||||||
return request({
|
|
||||||
url: `/ne/license`,
|
|
||||||
method: 'put',
|
|
||||||
data: data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 网元授权删除
|
|
||||||
* @param id 信息ID
|
|
||||||
* @returns object
|
|
||||||
*/
|
|
||||||
export function delNeLicense(licenseIds: string | number) {
|
|
||||||
return request({
|
|
||||||
url: `/ne/license/${licenseIds}`,
|
|
||||||
method: 'delete',
|
|
||||||
timeout: 60_000,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +56,7 @@ export function codeNeLicense(neType: string, neId: string) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 网元授权激活授权文件替换
|
* 网元授权激活授权文件替换
|
||||||
* @param data 网元对象
|
* @param data 网元对象 {"neType": "", "neId": "", "licensePath": "", "reload": true}
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export function changeNeLicense(data: Record<string, any>) {
|
export function changeNeLicense(data: Record<string, any>) {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export function addNeSoftware(data: Record<string, any>) {
|
|||||||
url: `/ne/software`,
|
url: `/ne/software`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data,
|
data: data,
|
||||||
|
repeatSubmit: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,15 +67,14 @@ export function delNeSoftware(softwareIds: string | number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网元软件包安装检查
|
* 网元软件包设为网元新版本
|
||||||
* @param data 网元对象
|
* @param data data { "version": "2.2404.18", "neType": "SMF", "name": "smf-r2.2404.18-ub22.deb"}
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export function checkInstallNeSoftware(data: Record<string, any>) {
|
export function newNeVersion(data: Record<string, any>) {
|
||||||
return request({
|
return request({
|
||||||
url: `/ne/software/checkInstall`,
|
url: `/ne/software/newNeVersion`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data,
|
data: data,
|
||||||
timeout: 180_000,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
+5
-30
@@ -27,40 +27,15 @@ export function getNeVersion(versionId: string | number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网元版本新增
|
* 网元版本操作
|
||||||
* @param data 网元对象
|
* @param data {neType,neId,preinput:{参数},action:"upgrade"}
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export function addNeVersion(data: Record<string, any>) {
|
export function operateNeVersion(data: Record<string, any>) {
|
||||||
return request({
|
return request({
|
||||||
url: `/ne/version`,
|
url: `/ne/version/operate`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data,
|
data: data,
|
||||||
});
|
timeout: 180_000,
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 网元版本修改
|
|
||||||
* @param data 网元对象
|
|
||||||
* @returns object
|
|
||||||
*/
|
|
||||||
export function updateNeVersion(data: Record<string, any>) {
|
|
||||||
return request({
|
|
||||||
url: `/ne/version`,
|
|
||||||
method: 'put',
|
|
||||||
data: data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 网元版本删除
|
|
||||||
* @param id 信息ID
|
|
||||||
* @returns object
|
|
||||||
*/
|
|
||||||
export function delNeVersion(versionIds: string | number) {
|
|
||||||
return request({
|
|
||||||
url: `/ne/version/${versionIds}`,
|
|
||||||
method: 'delete',
|
|
||||||
timeout: 60_000,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -136,6 +136,7 @@ export async function batchUpdateRule(data: Record<string, any>) {
|
|||||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
|
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data: data,
|
data: data,
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
// 解析数据
|
// 解析数据
|
||||||
if (result.code === RESULT_CODE_SUCCESS) {
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
@@ -164,6 +165,7 @@ export async function addRule(data: Record<string, any>) {
|
|||||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${data.neId}`,
|
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${data.neId}`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data,
|
data: data,
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
// 解析数据
|
// 解析数据
|
||||||
if (result.code === RESULT_CODE_SUCCESS && result.data?.status) {
|
if (result.code === RESULT_CODE_SUCCESS && result.data?.status) {
|
||||||
@@ -186,6 +188,7 @@ export async function batchAddRule(data: Record<string, any>) {
|
|||||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
|
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data,
|
data: data,
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
// 解析数据
|
// 解析数据
|
||||||
if (result.code === RESULT_CODE_SUCCESS) {
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
@@ -209,10 +212,11 @@ export async function batchAddRule(data: Record<string, any>) {
|
|||||||
* @param data 规则对象
|
* @param data 规则对象
|
||||||
* @returns object
|
* @returns object
|
||||||
*/
|
*/
|
||||||
export function delRule(neId: string, data: Record<string, any>) {
|
export function delRule(neId: string, imsi: string) {
|
||||||
return request({
|
return request({
|
||||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${neId}&imsi=${data.imsi}`,
|
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${neId}&imsi=${imsi}`,
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,5 +229,6 @@ export async function batchDelRule(data: Record<string, any>) {
|
|||||||
return request({
|
return request({
|
||||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}&imsi=${data.imsi}`,
|
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}&imsi=${data.imsi}`,
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
+22
-19
@@ -28,35 +28,38 @@ export async function listUEInfoBySMF(query: Record<string, any>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 模拟数据
|
// 模拟数据
|
||||||
|
// data.code = RESULT_CODE_SUCCESS;
|
||||||
// data.rows = [
|
// data.rows = [
|
||||||
// {
|
// {
|
||||||
// imsi: 'imsi-460029004200044',
|
// imsi: 'imsi-460002082101038',
|
||||||
// msisdn: 'msisdn-12346002044',
|
// msisdn: 'msisdn-12307550000',
|
||||||
// pduSessionInfo: [
|
// pduSessionInfo: [
|
||||||
// {
|
// {
|
||||||
// activeTime: '2023-11-29 18:39:06',
|
// activeTime: '2024-05-08 11:08:22',
|
||||||
// dnn: 'ims',
|
// dnn: 'ims',
|
||||||
// ipv4: '10.10.48.97',
|
// ipv4: '10.10.86.2',
|
||||||
// ipv6: '',
|
|
||||||
// pduSessionID: 6,
|
|
||||||
// ranN3IP: '192.168.8.223',
|
|
||||||
// sstSD: '1-000001',
|
|
||||||
// tai: '46000-0001',
|
|
||||||
// upfN3IP: '192.168.1.161',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// activeTime: '2023-11-29 18:39:05',
|
|
||||||
// dnn: 'cmnet',
|
|
||||||
// ipv4: '10.10.48.62',
|
|
||||||
// ipv6: '',
|
// ipv6: '',
|
||||||
// pduSessionID: 5,
|
// pduSessionID: 5,
|
||||||
// ranN3IP: '192.168.8.223',
|
// ranN3IP: '192.168.5.100',
|
||||||
// sstSD: '1-000001',
|
// sstSD: '1-000001',
|
||||||
// tai: '46000-0001',
|
// tai: '46000-001124',
|
||||||
// upfN3IP: '192.168.1.163',
|
// upState: 'Active',
|
||||||
|
// upfN3IP: '192.168.14.201',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// activeTime: '2024-05-08 11:08:23',
|
||||||
|
// dnn: 'cmnet',
|
||||||
|
// ipv4: '10.10.86.201',
|
||||||
|
// ipv6: '',
|
||||||
|
// pduSessionID: 6,
|
||||||
|
// ranN3IP: '192.168.5.100',
|
||||||
|
// sstSD: '1-000001',
|
||||||
|
// tai: '46000-001124',
|
||||||
|
// upState: 'Active',
|
||||||
|
// upfN3IP: '192.168.14.201',
|
||||||
// },
|
// },
|
||||||
// ],
|
// ],
|
||||||
// ratType: 'EUTRAN',
|
// ratType: 'NR',
|
||||||
// },
|
// },
|
||||||
// ];
|
// ];
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { request } from '@/plugins/http-fetch';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首次引导开始
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export function bootloaderStart() {
|
||||||
|
return request({
|
||||||
|
url: `/bootloader`,
|
||||||
|
method: 'post',
|
||||||
|
whithToken: false,
|
||||||
|
repeatSubmit: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首次引导完成
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export function bootloaderDone() {
|
||||||
|
return request({
|
||||||
|
url: `/bootloader`,
|
||||||
|
method: 'put',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 引导系统数据重置
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export function bootloaderReset() {
|
||||||
|
return request({
|
||||||
|
url: `/bootloader`,
|
||||||
|
method: 'delete',
|
||||||
|
timeout: 180_000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员账号变更
|
||||||
|
* @returns object
|
||||||
|
*/
|
||||||
|
export function bootloaderAccount(username: string, password: string) {
|
||||||
|
return request({
|
||||||
|
url: `/bootloader/account`,
|
||||||
|
method: 'put',
|
||||||
|
data: {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ export async function downloadFile(filePath: string, range?: string) {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
headers: range ? { range } : {},
|
headers: range ? { range } : {},
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +80,7 @@ export function uploadFile(data: FormData) {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data,
|
data,
|
||||||
dataType: 'form-data',
|
dataType: 'form-data',
|
||||||
|
timeout: 180_000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +171,7 @@ export function chunkCheck(identifier: string, fileName: string) {
|
|||||||
url: '/file/chunkCheck',
|
url: '/file/chunkCheck',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: { identifier, fileName },
|
data: { identifier, fileName },
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +191,7 @@ export function chunkMerge(
|
|||||||
url: '/file/chunkMerge',
|
url: '/file/chunkMerge',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: { identifier, fileName, subPath },
|
data: { identifier, fileName, subPath },
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +206,7 @@ export function chunkUpload(data: FormData) {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data,
|
data,
|
||||||
dataType: 'form-data',
|
dataType: 'form-data',
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +219,7 @@ export function transferStaticFile(data: Record<string, any>) {
|
|||||||
url: `/file/transferStaticFile`,
|
url: `/file/transferStaticFile`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data,
|
data,
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,6 +247,7 @@ export async function uploadFileToNE(
|
|||||||
neType,
|
neType,
|
||||||
neId,
|
neId,
|
||||||
},
|
},
|
||||||
|
timeout: 60_000,
|
||||||
});
|
});
|
||||||
return transferToNeFileRes;
|
return transferToNeFileRes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,252 @@
|
|||||||
|
//* THIS FILE IS AUTO-GENERATED. DO NOT EDIT.
|
||||||
|
export default {
|
||||||
|
af: "Afghanistan",
|
||||||
|
ax: "Åland Islands",
|
||||||
|
al: "Albania",
|
||||||
|
dz: "Algeria",
|
||||||
|
as: "American Samoa",
|
||||||
|
ad: "Andorra",
|
||||||
|
ao: "Angola",
|
||||||
|
ai: "Anguilla",
|
||||||
|
aq: "Antarctica",
|
||||||
|
ag: "Antigua & Barbuda",
|
||||||
|
ar: "Argentina",
|
||||||
|
am: "Armenia",
|
||||||
|
aw: "Aruba",
|
||||||
|
au: "Australia",
|
||||||
|
at: "Austria",
|
||||||
|
az: "Azerbaijan",
|
||||||
|
bs: "Bahamas",
|
||||||
|
bh: "Bahrain",
|
||||||
|
bd: "Bangladesh",
|
||||||
|
bb: "Barbados",
|
||||||
|
by: "Belarus",
|
||||||
|
be: "Belgium",
|
||||||
|
bz: "Belize",
|
||||||
|
bj: "Benin",
|
||||||
|
bm: "Bermuda",
|
||||||
|
bt: "Bhutan",
|
||||||
|
bo: "Bolivia",
|
||||||
|
ba: "Bosnia & Herzegovina",
|
||||||
|
bw: "Botswana",
|
||||||
|
bv: "Bouvet Island",
|
||||||
|
br: "Brazil",
|
||||||
|
io: "British Indian Ocean Territory",
|
||||||
|
vg: "British Virgin Islands",
|
||||||
|
bn: "Brunei",
|
||||||
|
bg: "Bulgaria",
|
||||||
|
bf: "Burkina Faso",
|
||||||
|
bi: "Burundi",
|
||||||
|
kh: "Cambodia",
|
||||||
|
cm: "Cameroon",
|
||||||
|
ca: "Canada",
|
||||||
|
cv: "Cape Verde",
|
||||||
|
bq: "Caribbean Netherlands",
|
||||||
|
ky: "Cayman Islands",
|
||||||
|
cf: "Central African Republic",
|
||||||
|
td: "Chad",
|
||||||
|
cl: "Chile",
|
||||||
|
cn: "China",
|
||||||
|
cx: "Christmas Island",
|
||||||
|
cc: "Cocos (Keeling) Islands",
|
||||||
|
co: "Colombia",
|
||||||
|
km: "Comoros",
|
||||||
|
cg: "Congo - Brazzaville",
|
||||||
|
cd: "Congo - Kinshasa",
|
||||||
|
ck: "Cook Islands",
|
||||||
|
cr: "Costa Rica",
|
||||||
|
ci: "Côte d’Ivoire",
|
||||||
|
hr: "Croatia",
|
||||||
|
cu: "Cuba",
|
||||||
|
cw: "Curaçao",
|
||||||
|
cy: "Cyprus",
|
||||||
|
cz: "Czechia",
|
||||||
|
dk: "Denmark",
|
||||||
|
dj: "Djibouti",
|
||||||
|
dm: "Dominica",
|
||||||
|
do: "Dominican Republic",
|
||||||
|
ec: "Ecuador",
|
||||||
|
eg: "Egypt",
|
||||||
|
sv: "El Salvador",
|
||||||
|
gq: "Equatorial Guinea",
|
||||||
|
er: "Eritrea",
|
||||||
|
ee: "Estonia",
|
||||||
|
sz: "Eswatini",
|
||||||
|
et: "Ethiopia",
|
||||||
|
fk: "Falkland Islands",
|
||||||
|
fo: "Faroe Islands",
|
||||||
|
fj: "Fiji",
|
||||||
|
fi: "Finland",
|
||||||
|
fr: "France",
|
||||||
|
gf: "French Guiana",
|
||||||
|
pf: "French Polynesia",
|
||||||
|
tf: "French Southern Territories",
|
||||||
|
ga: "Gabon",
|
||||||
|
gm: "Gambia",
|
||||||
|
ge: "Georgia",
|
||||||
|
de: "Germany",
|
||||||
|
gh: "Ghana",
|
||||||
|
gi: "Gibraltar",
|
||||||
|
gr: "Greece",
|
||||||
|
gl: "Greenland",
|
||||||
|
gd: "Grenada",
|
||||||
|
gp: "Guadeloupe",
|
||||||
|
gu: "Guam",
|
||||||
|
gt: "Guatemala",
|
||||||
|
gg: "Guernsey",
|
||||||
|
gn: "Guinea",
|
||||||
|
gw: "Guinea-Bissau",
|
||||||
|
gy: "Guyana",
|
||||||
|
ht: "Haiti",
|
||||||
|
hm: "Heard & McDonald Islands",
|
||||||
|
hn: "Honduras",
|
||||||
|
hk: "Hong Kong SAR China",
|
||||||
|
hu: "Hungary",
|
||||||
|
is: "Iceland",
|
||||||
|
in: "India",
|
||||||
|
id: "Indonesia",
|
||||||
|
ir: "Iran",
|
||||||
|
iq: "Iraq",
|
||||||
|
ie: "Ireland",
|
||||||
|
im: "Isle of Man",
|
||||||
|
il: "Israel",
|
||||||
|
it: "Italy",
|
||||||
|
jm: "Jamaica",
|
||||||
|
jp: "Japan",
|
||||||
|
je: "Jersey",
|
||||||
|
jo: "Jordan",
|
||||||
|
kz: "Kazakhstan",
|
||||||
|
ke: "Kenya",
|
||||||
|
ki: "Kiribati",
|
||||||
|
kw: "Kuwait",
|
||||||
|
kg: "Kyrgyzstan",
|
||||||
|
la: "Laos",
|
||||||
|
lv: "Latvia",
|
||||||
|
lb: "Lebanon",
|
||||||
|
ls: "Lesotho",
|
||||||
|
lr: "Liberia",
|
||||||
|
ly: "Libya",
|
||||||
|
li: "Liechtenstein",
|
||||||
|
lt: "Lithuania",
|
||||||
|
lu: "Luxembourg",
|
||||||
|
mo: "Macao SAR China",
|
||||||
|
mg: "Madagascar",
|
||||||
|
mw: "Malawi",
|
||||||
|
my: "Malaysia",
|
||||||
|
mv: "Maldives",
|
||||||
|
ml: "Mali",
|
||||||
|
mt: "Malta",
|
||||||
|
mh: "Marshall Islands",
|
||||||
|
mq: "Martinique",
|
||||||
|
mr: "Mauritania",
|
||||||
|
mu: "Mauritius",
|
||||||
|
yt: "Mayotte",
|
||||||
|
mx: "Mexico",
|
||||||
|
fm: "Micronesia",
|
||||||
|
md: "Moldova",
|
||||||
|
mc: "Monaco",
|
||||||
|
mn: "Mongolia",
|
||||||
|
me: "Montenegro",
|
||||||
|
ms: "Montserrat",
|
||||||
|
ma: "Morocco",
|
||||||
|
mz: "Mozambique",
|
||||||
|
mm: "Myanmar (Burma)",
|
||||||
|
na: "Namibia",
|
||||||
|
nr: "Nauru",
|
||||||
|
np: "Nepal",
|
||||||
|
nl: "Netherlands",
|
||||||
|
nc: "New Caledonia",
|
||||||
|
nz: "New Zealand",
|
||||||
|
ni: "Nicaragua",
|
||||||
|
ne: "Niger",
|
||||||
|
ng: "Nigeria",
|
||||||
|
nu: "Niue",
|
||||||
|
nf: "Norfolk Island",
|
||||||
|
kp: "North Korea",
|
||||||
|
mk: "North Macedonia",
|
||||||
|
mp: "Northern Mariana Islands",
|
||||||
|
no: "Norway",
|
||||||
|
om: "Oman",
|
||||||
|
pk: "Pakistan",
|
||||||
|
pw: "Palau",
|
||||||
|
ps: "Palestinian Territories",
|
||||||
|
pa: "Panama",
|
||||||
|
pg: "Papua New Guinea",
|
||||||
|
py: "Paraguay",
|
||||||
|
pe: "Peru",
|
||||||
|
ph: "Philippines",
|
||||||
|
pn: "Pitcairn Islands",
|
||||||
|
pl: "Poland",
|
||||||
|
pt: "Portugal",
|
||||||
|
pr: "Puerto Rico",
|
||||||
|
qa: "Qatar",
|
||||||
|
re: "Réunion",
|
||||||
|
ro: "Romania",
|
||||||
|
ru: "Russia",
|
||||||
|
rw: "Rwanda",
|
||||||
|
ws: "Samoa",
|
||||||
|
sm: "San Marino",
|
||||||
|
st: "São Tomé & Príncipe",
|
||||||
|
sa: "Saudi Arabia",
|
||||||
|
sn: "Senegal",
|
||||||
|
rs: "Serbia",
|
||||||
|
sc: "Seychelles",
|
||||||
|
sl: "Sierra Leone",
|
||||||
|
sg: "Singapore",
|
||||||
|
sx: "Sint Maarten",
|
||||||
|
sk: "Slovakia",
|
||||||
|
si: "Slovenia",
|
||||||
|
sb: "Solomon Islands",
|
||||||
|
so: "Somalia",
|
||||||
|
za: "South Africa",
|
||||||
|
gs: "South Georgia & South Sandwich Islands",
|
||||||
|
kr: "South Korea",
|
||||||
|
ss: "South Sudan",
|
||||||
|
es: "Spain",
|
||||||
|
lk: "Sri Lanka",
|
||||||
|
bl: "St. Barthélemy",
|
||||||
|
sh: "St. Helena",
|
||||||
|
kn: "St. Kitts & Nevis",
|
||||||
|
lc: "St. Lucia",
|
||||||
|
mf: "St. Martin",
|
||||||
|
pm: "St. Pierre & Miquelon",
|
||||||
|
vc: "St. Vincent & Grenadines",
|
||||||
|
sd: "Sudan",
|
||||||
|
sr: "Suriname",
|
||||||
|
sj: "Svalbard & Jan Mayen",
|
||||||
|
se: "Sweden",
|
||||||
|
ch: "Switzerland",
|
||||||
|
sy: "Syria",
|
||||||
|
tw: "Taiwan",
|
||||||
|
tj: "Tajikistan",
|
||||||
|
tz: "Tanzania",
|
||||||
|
th: "Thailand",
|
||||||
|
tl: "Timor-Leste",
|
||||||
|
tg: "Togo",
|
||||||
|
tk: "Tokelau",
|
||||||
|
to: "Tonga",
|
||||||
|
tt: "Trinidad & Tobago",
|
||||||
|
tn: "Tunisia",
|
||||||
|
tr: "Turkey",
|
||||||
|
tm: "Turkmenistan",
|
||||||
|
tc: "Turks & Caicos Islands",
|
||||||
|
tv: "Tuvalu",
|
||||||
|
um: "U.S. Outlying Islands",
|
||||||
|
vi: "U.S. Virgin Islands",
|
||||||
|
ug: "Uganda",
|
||||||
|
ua: "Ukraine",
|
||||||
|
ae: "United Arab Emirates",
|
||||||
|
gb: "United Kingdom",
|
||||||
|
us: "United States",
|
||||||
|
uy: "Uruguay",
|
||||||
|
uz: "Uzbekistan",
|
||||||
|
vu: "Vanuatu",
|
||||||
|
va: "Vatican City",
|
||||||
|
ve: "Venezuela",
|
||||||
|
vn: "Vietnam",
|
||||||
|
wf: "Wallis & Futuna",
|
||||||
|
eh: "Western Sahara",
|
||||||
|
ye: "Yemen",
|
||||||
|
zm: "Zambia",
|
||||||
|
zw: "Zimbabwe",
|
||||||
|
};
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import countryTranslations from './countries';
|
||||||
|
import interfaceTranslations from './interface';
|
||||||
|
|
||||||
|
export default { ...countryTranslations, ...interfaceTranslations };
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
//* English. Translated by: Jack O'Connor (jackocnr).
|
||||||
|
export default {
|
||||||
|
selectedCountryAriaLabel: "Selected country",
|
||||||
|
noCountrySelected: "No country selected",
|
||||||
|
countryListAriaLabel: "List of countries",
|
||||||
|
searchPlaceholder: "Search",
|
||||||
|
zeroSearchResults: "No results found",
|
||||||
|
oneSearchResult: "1 result found",
|
||||||
|
multipleSearchResults: "${count} results found",
|
||||||
|
|
||||||
|
// additional countries (not supported by country-list library)
|
||||||
|
ac: "Ascension Island",
|
||||||
|
xk: "Kosovo",
|
||||||
|
};
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
//* THIS FILE IS AUTO-GENERATED. DO NOT EDIT.
|
||||||
|
export default {
|
||||||
|
al: "阿尔巴尼亚",
|
||||||
|
dz: "阿尔及利亚",
|
||||||
|
af: "阿富汗",
|
||||||
|
ar: "阿根廷",
|
||||||
|
ae: "阿拉伯联合酋长国",
|
||||||
|
aw: "阿鲁巴",
|
||||||
|
om: "阿曼",
|
||||||
|
az: "阿塞拜疆",
|
||||||
|
eg: "埃及",
|
||||||
|
et: "埃塞俄比亚",
|
||||||
|
ie: "爱尔兰",
|
||||||
|
ee: "爱沙尼亚",
|
||||||
|
ad: "安道尔",
|
||||||
|
ao: "安哥拉",
|
||||||
|
ai: "安圭拉",
|
||||||
|
ag: "安提瓜和巴布达",
|
||||||
|
at: "奥地利",
|
||||||
|
ax: "奥兰群岛",
|
||||||
|
au: "澳大利亚",
|
||||||
|
bb: "巴巴多斯",
|
||||||
|
pg: "巴布亚新几内亚",
|
||||||
|
bs: "巴哈马",
|
||||||
|
pk: "巴基斯坦",
|
||||||
|
py: "巴拉圭",
|
||||||
|
ps: "巴勒斯坦领土",
|
||||||
|
bh: "巴林",
|
||||||
|
pa: "巴拿马",
|
||||||
|
br: "巴西",
|
||||||
|
by: "白俄罗斯",
|
||||||
|
bm: "百慕大",
|
||||||
|
bg: "保加利亚",
|
||||||
|
mp: "北马里亚纳群岛",
|
||||||
|
mk: "北马其顿",
|
||||||
|
bj: "贝宁",
|
||||||
|
be: "比利时",
|
||||||
|
is: "冰岛",
|
||||||
|
pr: "波多黎各",
|
||||||
|
pl: "波兰",
|
||||||
|
ba: "波斯尼亚和黑塞哥维那",
|
||||||
|
bo: "玻利维亚",
|
||||||
|
bz: "伯利兹",
|
||||||
|
bw: "博茨瓦纳",
|
||||||
|
bt: "不丹",
|
||||||
|
bf: "布基纳法索",
|
||||||
|
bi: "布隆迪",
|
||||||
|
bv: "布韦岛",
|
||||||
|
kp: "朝鲜",
|
||||||
|
gq: "赤道几内亚",
|
||||||
|
dk: "丹麦",
|
||||||
|
de: "德国",
|
||||||
|
tl: "东帝汶",
|
||||||
|
tg: "多哥",
|
||||||
|
do: "多米尼加共和国",
|
||||||
|
dm: "多米尼克",
|
||||||
|
ru: "俄罗斯",
|
||||||
|
ec: "厄瓜多尔",
|
||||||
|
er: "厄立特里亚",
|
||||||
|
fr: "法国",
|
||||||
|
fo: "法罗群岛",
|
||||||
|
pf: "法属波利尼西亚",
|
||||||
|
gf: "法属圭亚那",
|
||||||
|
tf: "法属南部领地",
|
||||||
|
mf: "法属圣马丁",
|
||||||
|
va: "梵蒂冈",
|
||||||
|
ph: "菲律宾",
|
||||||
|
fj: "斐济",
|
||||||
|
fi: "芬兰",
|
||||||
|
cv: "佛得角",
|
||||||
|
fk: "福克兰群岛",
|
||||||
|
gm: "冈比亚",
|
||||||
|
cg: "刚果(布)",
|
||||||
|
cd: "刚果(金)",
|
||||||
|
co: "哥伦比亚",
|
||||||
|
cr: "哥斯达黎加",
|
||||||
|
gd: "格林纳达",
|
||||||
|
gl: "格陵兰",
|
||||||
|
ge: "格鲁吉亚",
|
||||||
|
gg: "根西岛",
|
||||||
|
cu: "古巴",
|
||||||
|
gp: "瓜德罗普",
|
||||||
|
gu: "关岛",
|
||||||
|
gy: "圭亚那",
|
||||||
|
kz: "哈萨克斯坦",
|
||||||
|
ht: "海地",
|
||||||
|
kr: "韩国",
|
||||||
|
nl: "荷兰",
|
||||||
|
bq: "荷属加勒比区",
|
||||||
|
sx: "荷属圣马丁",
|
||||||
|
hm: "赫德岛和麦克唐纳群岛",
|
||||||
|
me: "黑山",
|
||||||
|
hn: "洪都拉斯",
|
||||||
|
ki: "基里巴斯",
|
||||||
|
dj: "吉布提",
|
||||||
|
kg: "吉尔吉斯斯坦",
|
||||||
|
gn: "几内亚",
|
||||||
|
gw: "几内亚比绍",
|
||||||
|
ca: "加拿大",
|
||||||
|
gh: "加纳",
|
||||||
|
ga: "加蓬",
|
||||||
|
kh: "柬埔寨",
|
||||||
|
cz: "捷克",
|
||||||
|
zw: "津巴布韦",
|
||||||
|
cm: "喀麦隆",
|
||||||
|
qa: "卡塔尔",
|
||||||
|
ky: "开曼群岛",
|
||||||
|
cc: "科科斯(基林)群岛",
|
||||||
|
km: "科摩罗",
|
||||||
|
ci: "科特迪瓦",
|
||||||
|
kw: "科威特",
|
||||||
|
hr: "克罗地亚",
|
||||||
|
ke: "肯尼亚",
|
||||||
|
ck: "库克群岛",
|
||||||
|
cw: "库拉索",
|
||||||
|
lv: "拉脱维亚",
|
||||||
|
ls: "莱索托",
|
||||||
|
la: "老挝",
|
||||||
|
lb: "黎巴嫩",
|
||||||
|
lt: "立陶宛",
|
||||||
|
lr: "利比里亚",
|
||||||
|
ly: "利比亚",
|
||||||
|
li: "列支敦士登",
|
||||||
|
re: "留尼汪",
|
||||||
|
lu: "卢森堡",
|
||||||
|
rw: "卢旺达",
|
||||||
|
ro: "罗马尼亚",
|
||||||
|
mg: "马达加斯加",
|
||||||
|
im: "马恩岛",
|
||||||
|
mv: "马尔代夫",
|
||||||
|
mt: "马耳他",
|
||||||
|
mw: "马拉维",
|
||||||
|
my: "马来西亚",
|
||||||
|
ml: "马里",
|
||||||
|
mh: "马绍尔群岛",
|
||||||
|
mq: "马提尼克",
|
||||||
|
yt: "马约特",
|
||||||
|
mu: "毛里求斯",
|
||||||
|
mr: "毛里塔尼亚",
|
||||||
|
us: "美国",
|
||||||
|
um: "美国本土外小岛屿",
|
||||||
|
as: "美属萨摩亚",
|
||||||
|
vi: "美属维尔京群岛",
|
||||||
|
mn: "蒙古",
|
||||||
|
ms: "蒙特塞拉特",
|
||||||
|
bd: "孟加拉国",
|
||||||
|
pe: "秘鲁",
|
||||||
|
fm: "密克罗尼西亚",
|
||||||
|
mm: "缅甸",
|
||||||
|
md: "摩尔多瓦",
|
||||||
|
ma: "摩洛哥",
|
||||||
|
mc: "摩纳哥",
|
||||||
|
mz: "莫桑比克",
|
||||||
|
mx: "墨西哥",
|
||||||
|
na: "纳米比亚",
|
||||||
|
za: "南非",
|
||||||
|
aq: "南极洲",
|
||||||
|
gs: "南乔治亚和南桑威奇群岛",
|
||||||
|
ss: "南苏丹",
|
||||||
|
nr: "瑙鲁",
|
||||||
|
ni: "尼加拉瓜",
|
||||||
|
np: "尼泊尔",
|
||||||
|
ne: "尼日尔",
|
||||||
|
ng: "尼日利亚",
|
||||||
|
nu: "纽埃",
|
||||||
|
no: "挪威",
|
||||||
|
nf: "诺福克岛",
|
||||||
|
pw: "帕劳",
|
||||||
|
pn: "皮特凯恩群岛",
|
||||||
|
pt: "葡萄牙",
|
||||||
|
jp: "日本",
|
||||||
|
se: "瑞典",
|
||||||
|
ch: "瑞士",
|
||||||
|
sv: "萨尔瓦多",
|
||||||
|
ws: "萨摩亚",
|
||||||
|
rs: "塞尔维亚",
|
||||||
|
sl: "塞拉利昂",
|
||||||
|
sn: "塞内加尔",
|
||||||
|
cy: "塞浦路斯",
|
||||||
|
sc: "塞舌尔",
|
||||||
|
sa: "沙特阿拉伯",
|
||||||
|
bl: "圣巴泰勒米",
|
||||||
|
cx: "圣诞岛",
|
||||||
|
st: "圣多美和普林西比",
|
||||||
|
sh: "圣赫勒拿",
|
||||||
|
kn: "圣基茨和尼维斯",
|
||||||
|
lc: "圣卢西亚",
|
||||||
|
sm: "圣马力诺",
|
||||||
|
pm: "圣皮埃尔和密克隆群岛",
|
||||||
|
vc: "圣文森特和格林纳丁斯",
|
||||||
|
lk: "斯里兰卡",
|
||||||
|
sk: "斯洛伐克",
|
||||||
|
si: "斯洛文尼亚",
|
||||||
|
sj: "斯瓦尔巴和扬马延",
|
||||||
|
sz: "斯威士兰",
|
||||||
|
sd: "苏丹",
|
||||||
|
sr: "苏里南",
|
||||||
|
sb: "所罗门群岛",
|
||||||
|
so: "索马里",
|
||||||
|
tj: "塔吉克斯坦",
|
||||||
|
tw: "台湾",
|
||||||
|
th: "泰国",
|
||||||
|
tz: "坦桑尼亚",
|
||||||
|
to: "汤加",
|
||||||
|
tc: "特克斯和凯科斯群岛",
|
||||||
|
tt: "特立尼达和多巴哥",
|
||||||
|
tn: "突尼斯",
|
||||||
|
tv: "图瓦卢",
|
||||||
|
tr: "土耳其",
|
||||||
|
tm: "土库曼斯坦",
|
||||||
|
tk: "托克劳",
|
||||||
|
wf: "瓦利斯和富图纳",
|
||||||
|
vu: "瓦努阿图",
|
||||||
|
gt: "危地马拉",
|
||||||
|
ve: "委内瑞拉",
|
||||||
|
bn: "文莱",
|
||||||
|
ug: "乌干达",
|
||||||
|
ua: "乌克兰",
|
||||||
|
uy: "乌拉圭",
|
||||||
|
uz: "乌兹别克斯坦",
|
||||||
|
es: "西班牙",
|
||||||
|
eh: "西撒哈拉",
|
||||||
|
gr: "希腊",
|
||||||
|
sg: "新加坡",
|
||||||
|
nc: "新喀里多尼亚",
|
||||||
|
nz: "新西兰",
|
||||||
|
hu: "匈牙利",
|
||||||
|
sy: "叙利亚",
|
||||||
|
jm: "牙买加",
|
||||||
|
am: "亚美尼亚",
|
||||||
|
ye: "也门",
|
||||||
|
iq: "伊拉克",
|
||||||
|
ir: "伊朗",
|
||||||
|
il: "以色列",
|
||||||
|
it: "意大利",
|
||||||
|
in: "印度",
|
||||||
|
id: "印度尼西亚",
|
||||||
|
gb: "英国",
|
||||||
|
vg: "英属维尔京群岛",
|
||||||
|
io: "英属印度洋领地",
|
||||||
|
jo: "约旦",
|
||||||
|
vn: "越南",
|
||||||
|
zm: "赞比亚",
|
||||||
|
je: "泽西岛",
|
||||||
|
td: "乍得",
|
||||||
|
gi: "直布罗陀",
|
||||||
|
cl: "智利",
|
||||||
|
cf: "中非共和国",
|
||||||
|
cn: "中国",
|
||||||
|
mo: "中国澳门特别行政区",
|
||||||
|
hk: "中国香港特别行政区",
|
||||||
|
};
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import countryTranslations from './countries';
|
||||||
|
import interfaceTranslations from './interface';
|
||||||
|
|
||||||
|
export default { ...countryTranslations, ...interfaceTranslations };
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//* Chinese (Simplified). Translated by: Google Translate.
|
||||||
|
export default {
|
||||||
|
selectedCountryAriaLabel: "所选国家",
|
||||||
|
noCountrySelected: "未选择国家/地区",
|
||||||
|
countryListAriaLabel: "国家名单",
|
||||||
|
searchPlaceholder: "搜索",
|
||||||
|
zeroSearchResults: "未找到结果",
|
||||||
|
oneSearchResult: "找到 1 个结果",
|
||||||
|
multipleSearchResults: "找到 ${count} 个结果",
|
||||||
|
|
||||||
|
// additional countries (not supported by country-list library)
|
||||||
|
ac: "阿森松岛",
|
||||||
|
xk: "科索沃",
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
<!-- https://github.com/jackocnr/intl-tel-input/blob/master/react/src/intl-tel-input/react.tsx -->
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import intlTelInput, { Iti, SomeOptions } from 'intl-tel-input';
|
||||||
|
import 'intl-tel-input/build/css/intlTelInput.min.css';
|
||||||
|
import 'intl-tel-input/build/js/utils.js';
|
||||||
|
import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
const { currentLocale } = useI18n();
|
||||||
|
const emit = defineEmits(['update:value', 'update:change']);
|
||||||
|
const props = defineProps({
|
||||||
|
/**有效检验 */
|
||||||
|
preciseValidation: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**手机号 */
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
/**禁用输入 */
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**手机号输入提示 */
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
/**手机号输入最大字符串长度 */
|
||||||
|
maxlength: {
|
||||||
|
type: Number,
|
||||||
|
default: 255,
|
||||||
|
},
|
||||||
|
/**允许清空手机号输入框 */
|
||||||
|
allowClear: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputRef = ref<HTMLInputElement | null>(null);
|
||||||
|
const itiRef = ref<Iti | null>(null);
|
||||||
|
|
||||||
|
function fnChange() {
|
||||||
|
if (!itiRef.value) return;
|
||||||
|
|
||||||
|
const num = itiRef.value?.getNumber() || '';
|
||||||
|
const countryIso = itiRef.value?.getSelectedCountryData().iso2 || '';
|
||||||
|
// note: this number will be in standard E164 format, but any container component can use
|
||||||
|
// intlTelInputUtils.formatNumber() to convert this to another format
|
||||||
|
// as well as intlTelInputUtils.getNumberType() etc. if need be
|
||||||
|
let data = {
|
||||||
|
num,
|
||||||
|
countryIso,
|
||||||
|
validity: false,
|
||||||
|
errorCode: -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const isValid = props.preciseValidation
|
||||||
|
? itiRef.value.isValidNumberPrecise()
|
||||||
|
: itiRef.value.isValidNumber();
|
||||||
|
if (isValid) {
|
||||||
|
data.validity = true;
|
||||||
|
data.errorCode = 0;
|
||||||
|
} else {
|
||||||
|
const errorCode = itiRef.value.getValidationError();
|
||||||
|
data.validity = false;
|
||||||
|
data.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
// console.log(data);
|
||||||
|
emit('update:value', num);
|
||||||
|
emit('update:change', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
v => {
|
||||||
|
if (v) {
|
||||||
|
itiRef.value?.setNumber(v);
|
||||||
|
} else {
|
||||||
|
itiRef.value?.setNumber('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(async () => {
|
||||||
|
if (inputRef.value) {
|
||||||
|
let i18n = undefined;
|
||||||
|
let initialCountry = 'us';
|
||||||
|
// 语言文件导入问题只能复制到项目内处理
|
||||||
|
// import fr from "intl-tel-input/i18n/fr";
|
||||||
|
if (currentLocale.value.startsWith('zh')) {
|
||||||
|
const { default: zh } = await import('./i18n/zh');
|
||||||
|
i18n = zh;
|
||||||
|
initialCountry = 'cn';
|
||||||
|
} else {
|
||||||
|
const { default: en } = await import('./i18n/en');
|
||||||
|
i18n = en;
|
||||||
|
initialCountry = 'us';
|
||||||
|
}
|
||||||
|
|
||||||
|
itiRef.value = intlTelInput(inputRef.value, {
|
||||||
|
initialCountry: initialCountry,
|
||||||
|
formatOnDisplay: true,
|
||||||
|
autoPlaceholder: 'polite',
|
||||||
|
i18n: i18n,
|
||||||
|
} as SomeOptions);
|
||||||
|
inputRef.value.addEventListener('countrychange', fnChange);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (inputRef.value) {
|
||||||
|
inputRef.value.removeEventListener('countrychange', fnChange);
|
||||||
|
}
|
||||||
|
itiRef.value?.destroy();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
class="ant-input"
|
||||||
|
ref="inputRef"
|
||||||
|
:value="value"
|
||||||
|
:disabled="disabled"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:maxlength="maxlength"
|
||||||
|
:allow-clear="allowClear"
|
||||||
|
@input="fnChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css">
|
||||||
|
.iti {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iti .iti__country-container .iti__search-input {
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -53,30 +53,32 @@ function backLogin() {
|
|||||||
const isLocked = computed(() => lockedStore.type !== 'none');
|
const isLocked = computed(() => lockedStore.type !== 'none');
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getConfigKey('sys.lockTime')
|
// 本地锁定类型设置;
|
||||||
.then(res => {
|
lockedStore.fnLock(lockedStore.type);
|
||||||
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
// getConfigKey('sys.lockTime')
|
||||||
lockedStore.lockTimeout = res.data;
|
// .then(res => {
|
||||||
timeoutDuration = res.data * 1000;
|
// if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
||||||
}
|
// lockedStore.lockTimeout = res.data;
|
||||||
// 本地锁定类型设置
|
// timeoutDuration = res.data * 1000;
|
||||||
lockedStore.fnLock(lockedStore.type);
|
// }
|
||||||
})
|
// // 本地锁定类型设置
|
||||||
.finally(() => {
|
// lockedStore.fnLock(lockedStore.type);
|
||||||
if (timeoutDuration !== 0) {
|
// })
|
||||||
resetTimeout();
|
// .finally(() => {
|
||||||
// 监听用户的操作,重置超时时间
|
// if (timeoutDuration !== 0) {
|
||||||
window.addEventListener('mousemove', resetTimeout);
|
// resetTimeout();
|
||||||
window.addEventListener('keydown', resetTimeout);
|
// // 监听用户的操作,重置超时时间
|
||||||
}
|
// window.addEventListener('mousemove', resetTimeout);
|
||||||
});
|
// window.addEventListener('keydown', resetTimeout);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
/**组件实例被卸载之后调用 */
|
/**组件实例被卸载之后调用 */
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (timeoutId) {
|
// if (timeoutId) {
|
||||||
clearTimeout(timeoutId);
|
// clearTimeout(timeoutId);
|
||||||
}
|
// }
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
@@ -141,6 +143,17 @@ onUnmounted(() => {
|
|||||||
{{ t('components.LockScreen.backReload2') }}
|
{{ t('components.LockScreen.backReload2') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 锁屏-OMC系统重置 -->
|
||||||
|
<div class="lock-screen_reload" v-if="lockedStore.type === 'reset'">
|
||||||
|
<LoadingOutlined style="font-size: 56px" />
|
||||||
|
<div class="text">
|
||||||
|
{{ t('components.LockScreen.systemReset') }}
|
||||||
|
</div>
|
||||||
|
<div class="desc">
|
||||||
|
{{ t('components.LockScreen.systemReset2') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ function fnTableColumnsCheckAllChange(e: any) {
|
|||||||
/**表格字段列拖拽操作 */
|
/**表格字段列拖拽操作 */
|
||||||
function fnTableColumnsDrop(dropResult: any) {
|
function fnTableColumnsDrop(dropResult: any) {
|
||||||
const { removedIndex, addedIndex, payload } = dropResult;
|
const { removedIndex, addedIndex, payload } = dropResult;
|
||||||
if (!removedIndex || !addedIndex) {
|
if (removedIndex === null || addedIndex === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let itemToAdd = payload;
|
let itemToAdd = payload;
|
||||||
@@ -184,6 +184,7 @@ onMounted(() => {
|
|||||||
<a-button
|
<a-button
|
||||||
v-if="c.fixed !== undefined"
|
v-if="c.fixed !== undefined"
|
||||||
size="small"
|
size="small"
|
||||||
|
:title="c.fixed ? `Fixed ${c.fixed} side` : ''"
|
||||||
:type="c.fixed ? 'primary' : 'dashed'"
|
:type="c.fixed ? 'primary' : 'dashed'"
|
||||||
@click="fnTableColumnsFixed(c)"
|
@click="fnTableColumnsFixed(c)"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
||||||
import { FitAddon } from 'xterm-addon-fit';
|
import { FitAddon } from '@xterm/addon-fit';
|
||||||
import { Terminal } from 'xterm';
|
import { Terminal } from '@xterm/xterm';
|
||||||
import 'xterm/css/xterm.css';
|
import '@xterm/xterm/css/xterm.css';
|
||||||
import { RESULT_CODE_ERROR } from '@/constants/result-constants';
|
import { RESULT_CODE_ERROR } from '@/constants/result-constants';
|
||||||
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
||||||
const ws = new WS();
|
const ws = new WS();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { message } from 'ant-design-vue/lib';
|
import { message } from 'ant-design-vue/lib';
|
||||||
import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
||||||
import { FitAddon } from 'xterm-addon-fit';
|
import { FitAddon } from '@xterm/addon-fit';
|
||||||
import { Terminal } from 'xterm';
|
import { Terminal } from '@xterm/xterm';
|
||||||
import 'xterm/css/xterm.css';
|
import '@xterm/xterm/css/xterm.css';
|
||||||
import { RESULT_CODE_ERROR } from '@/constants/result-constants';
|
import { RESULT_CODE_ERROR } from '@/constants/result-constants';
|
||||||
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
||||||
const ws = new WS();
|
const ws = new WS();
|
||||||
@@ -19,6 +19,16 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
/**窗口单行字符数 */
|
||||||
|
cols: {
|
||||||
|
type: Number,
|
||||||
|
default: 100,
|
||||||
|
},
|
||||||
|
/**窗口行数 */
|
||||||
|
rows: {
|
||||||
|
type: Number,
|
||||||
|
default: 128,
|
||||||
|
},
|
||||||
/**禁止输入 */
|
/**禁止输入 */
|
||||||
disable: {
|
disable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -238,6 +248,8 @@ onMounted(() => {
|
|||||||
url: '/ws/telnet',
|
url: '/ws/telnet',
|
||||||
params: {
|
params: {
|
||||||
hostId: props.hostId,
|
hostId: props.hostId,
|
||||||
|
cols: props.cols,
|
||||||
|
rows: props.rows,
|
||||||
},
|
},
|
||||||
onmessage: wsMessage,
|
onmessage: wsMessage,
|
||||||
onerror: wsError,
|
onerror: wsError,
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
||||||
|
import { FitAddon } from '@xterm/addon-fit';
|
||||||
|
import { Terminal } from '@xterm/xterm';
|
||||||
|
import '@xterm/xterm/css/xterm.css';
|
||||||
|
const emit = defineEmits(['update:value']);
|
||||||
|
const props = defineProps({
|
||||||
|
/**终端ID,必传 */
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
/**窗口单行字符数 */
|
||||||
|
cols: {
|
||||||
|
type: Number,
|
||||||
|
default: 80,
|
||||||
|
},
|
||||||
|
/**窗口行数 */
|
||||||
|
rows: {
|
||||||
|
type: Number,
|
||||||
|
default: 40,
|
||||||
|
},
|
||||||
|
/**信息 */
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**终端输入DOM节点实例对象 */
|
||||||
|
const terminalDom = ref<HTMLElement | undefined>(undefined);
|
||||||
|
|
||||||
|
/**终端输入实例对象 */
|
||||||
|
const terminal = ref<any>(null);
|
||||||
|
|
||||||
|
/**终端输入渲染 */
|
||||||
|
function handleRanderXterm(container: HTMLElement | undefined) {
|
||||||
|
if (!container) return;
|
||||||
|
const xterm = new Terminal({
|
||||||
|
cols: props.cols,
|
||||||
|
rows: props.rows,
|
||||||
|
lineHeight: 1.2,
|
||||||
|
fontSize: 12,
|
||||||
|
fontFamily: "Monaco, Menlo, Consolas, 'Courier New', monospace",
|
||||||
|
theme: {
|
||||||
|
background: '#000000',
|
||||||
|
},
|
||||||
|
cursorBlink: false, // 光标闪烁
|
||||||
|
cursorStyle: 'block',
|
||||||
|
scrollback: 1000,
|
||||||
|
scrollSensitivity: 15,
|
||||||
|
tabStopWidth: 4,
|
||||||
|
disableStdin: true, // 禁止输入
|
||||||
|
});
|
||||||
|
// 挂载
|
||||||
|
xterm.open(container);
|
||||||
|
// 自适应尺寸
|
||||||
|
const fitAddon = new FitAddon();
|
||||||
|
xterm.loadAddon(fitAddon);
|
||||||
|
|
||||||
|
// 创建 ResizeObserver 实例
|
||||||
|
var observer = new ResizeObserver(entries => {
|
||||||
|
fitAddon.fit();
|
||||||
|
});
|
||||||
|
// 监听元素大小变化
|
||||||
|
observer.observe(container);
|
||||||
|
|
||||||
|
terminal.value = xterm;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
handleRanderXterm(terminalDom.value);
|
||||||
|
// 初始发送命令
|
||||||
|
if (typeof props.value === 'string') {
|
||||||
|
terminal.value.write(props.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (terminal.value != null) {
|
||||||
|
terminal.value.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div ref="terminalDom" :id="id" class="terminal"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.terminal {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,18 +1,26 @@
|
|||||||
/**网元列表,默认顺序 */
|
/**网元列表,默认顺序 */
|
||||||
export const NE_TYPE_LIST = [
|
export const NE_TYPE_LIST = [
|
||||||
'OMC',
|
'OMC',
|
||||||
'MME',
|
'IMS',
|
||||||
'AMF',
|
'AMF',
|
||||||
'AUSF',
|
'AUSF',
|
||||||
'UDM',
|
'UDM',
|
||||||
'SMF',
|
'SMF',
|
||||||
'PCF',
|
'PCF',
|
||||||
'UPF',
|
|
||||||
'NRF',
|
|
||||||
'NSSF',
|
'NSSF',
|
||||||
'IMS',
|
'NRF',
|
||||||
'N3IWF',
|
'UPF',
|
||||||
'NEF',
|
|
||||||
'LMF',
|
'LMF',
|
||||||
|
'NEF',
|
||||||
|
'MME',
|
||||||
|
'N3IWF',
|
||||||
'MOCNGW',
|
'MOCNGW',
|
||||||
|
'SMSC',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元拓展包列表,默认顺序
|
||||||
|
* IMS-adb/rtproxy/mf
|
||||||
|
* UDM-adb
|
||||||
|
*/
|
||||||
|
export const NE_EXPAND_LIST = ['ADB', 'RTPROXY', 'MF'];
|
||||||
+327
-65
@@ -2,6 +2,7 @@ export default {
|
|||||||
// 语言
|
// 语言
|
||||||
i18n: 'English',
|
i18n: 'English',
|
||||||
hello: 'Hello',
|
hello: 'Hello',
|
||||||
|
welcome: 'Welcome, Core Network Management Platform',
|
||||||
|
|
||||||
// 通用
|
// 通用
|
||||||
common: {
|
common: {
|
||||||
@@ -34,7 +35,6 @@ export default {
|
|||||||
unableNull:' Cannot be empty',
|
unableNull:' Cannot be empty',
|
||||||
moreText: 'More',
|
moreText: 'More',
|
||||||
searchBarText: 'Search bar',
|
searchBarText: 'Search bar',
|
||||||
tableStripedText: 'Form Zebra',
|
|
||||||
reloadText: 'Refresh',
|
reloadText: 'Refresh',
|
||||||
columnSetText: 'Column Setting',
|
columnSetText: 'Column Setting',
|
||||||
columnSetTitle: 'Column Display / Sorting',
|
columnSetTitle: 'Column Display / Sorting',
|
||||||
@@ -53,9 +53,15 @@ export default {
|
|||||||
fold: 'Fold',
|
fold: 'Fold',
|
||||||
},
|
},
|
||||||
rowId: 'ID',
|
rowId: 'ID',
|
||||||
|
createTime: 'Create Time',
|
||||||
|
updateTime: 'Update Time',
|
||||||
|
remark: 'Remark',
|
||||||
|
description: 'Description',
|
||||||
operate: 'Operation',
|
operate: 'Operation',
|
||||||
operateOk: 'Operation Successful!',
|
operateOk: 'Operation Successful!',
|
||||||
operateErr: 'Operation Failed!',
|
operateErr: 'Operation Failed!',
|
||||||
|
copyText: "Copy",
|
||||||
|
copyOk: 'Copy Successful!',
|
||||||
units: {
|
units: {
|
||||||
second: 'Second',
|
second: 'Second',
|
||||||
minute: 'Minute',
|
minute: 'Minute',
|
||||||
@@ -129,7 +135,9 @@ export default {
|
|||||||
validError:'Validation Failure',
|
validError:'Validation Failure',
|
||||||
backLogin:'Logout to Relogin',
|
backLogin:'Logout to Relogin',
|
||||||
backReload:'Restarting now, please wait...',
|
backReload:'Restarting now, please wait...',
|
||||||
backReload2:'When ready, your browser will automatically refresh.',
|
backReload2:'When ready, Your browser will automatically refresh.',
|
||||||
|
systemReset:'Resetting now, please wait...',
|
||||||
|
systemReset2:'Data information is being reset.',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -164,6 +172,9 @@ export default {
|
|||||||
codeHit: 'Verification code',
|
codeHit: 'Verification code',
|
||||||
codeText: 'Obtain verification code',
|
codeText: 'Obtain verification code',
|
||||||
codeSmsSend: 'Successfully sent, please pay attention to checking the SMS',
|
codeSmsSend: 'Successfully sent, please pay attention to checking the SMS',
|
||||||
|
ipPlease: 'Please enter a valid IP address',
|
||||||
|
ipv4Reg: 'Not a valid IPv4 address',
|
||||||
|
ipv6Reg: 'Not a valid IPv6 address',
|
||||||
},
|
},
|
||||||
|
|
||||||
// 布局
|
// 布局
|
||||||
@@ -356,7 +367,7 @@ export default {
|
|||||||
pvflag:'PV Flag',
|
pvflag:'PV Flag',
|
||||||
pnf:'Physical Network Element',
|
pnf:'Physical Network Element',
|
||||||
vnf:'Virtual Network Element',
|
vnf:'Virtual Network Element',
|
||||||
province:'Province',
|
province:'Region',
|
||||||
vendorName:'Vendor Name',
|
vendorName:'Vendor Name',
|
||||||
dn:'Network Identification',
|
dn:'Network Identification',
|
||||||
reload: 'Reload',
|
reload: 'Reload',
|
||||||
@@ -424,15 +435,14 @@ export default {
|
|||||||
letUpTime:'Activation time',
|
letUpTime:'Activation time',
|
||||||
createTime:'Creation time',
|
createTime:'Creation time',
|
||||||
onlyAble:'Only upload file format {fileText} is supported',
|
onlyAble:'Only upload file format {fileText} is supported',
|
||||||
nullData:'No network element list data yet',
|
|
||||||
nullVersion:'There is no rollback version for the current network element.',
|
nullVersion:'There is no rollback version for the current network element.',
|
||||||
},
|
},
|
||||||
license: {
|
license: {
|
||||||
neTypePlease: 'Select network element type',
|
neTypePlease: 'Select network element type',
|
||||||
neType: 'NE Type',
|
neType: 'NE Type',
|
||||||
fileName: 'File Name',
|
serialNum: 'Serial Num',
|
||||||
createTime: 'Uploaded Time',
|
createTime: 'Time',
|
||||||
comment: 'File Description',
|
comment: 'Description',
|
||||||
updateComment: 'License Description',
|
updateComment: 'License Description',
|
||||||
updateCommentPlease: 'Please enter a license description',
|
updateCommentPlease: 'Please enter a license description',
|
||||||
updateFile: 'License File',
|
updateFile: 'License File',
|
||||||
@@ -471,21 +481,21 @@ export default {
|
|||||||
neType: 'NE Type',
|
neType: 'NE Type',
|
||||||
neTypePleace: "Please select the network element type",
|
neTypePleace: "Please select the network element type",
|
||||||
noConfigData: "No data on configuration items",
|
noConfigData: "No data on configuration items",
|
||||||
updateValue: "The value of the {num} attribute was modified successfully.",
|
updateValue: "[ {num} ] parameter value modified successfully.",
|
||||||
updateValueErr: "Attribute value modification failure",
|
updateValueErr: "Attribute value modification failure",
|
||||||
updateItem: "Modify Index to {num}.",
|
updateItem: "Modify Index to {num}.",
|
||||||
updateItemErr: "Record modification failure",
|
updateItemErr: "Record modification failure",
|
||||||
delItemOk: "Deleting Index as {num} succeeded",
|
delItemOk: "Deleting Index as {num} succeeded",
|
||||||
addItemOk: "Add Index as {num} Record Succeeded",
|
addItemOk: "Add Index as {num} Record Succeeded",
|
||||||
addItemErr: "Record addition failure",
|
addItemErr: "Record addition failure",
|
||||||
requireUn: "{display} input value is of unknown type",
|
requireUn: "[ {display} ] input value is of unknown type",
|
||||||
requireString: "The {display} parameter value is invalid.",
|
requireString: "[ {display} ] parameter value is invalid.",
|
||||||
requireInt: "{display} Parameter value not in reasonable range {filter}",
|
requireInt: "[ {display} ] parameter value not in reasonable range {filter}",
|
||||||
requireIpv4: "{display} not a legitimate IPV4 address",
|
requireIpv4: "[ {display} ] not a legitimate IPV4 address",
|
||||||
requireIpv6: "{display} Not a legitimate IPV6 address.",
|
requireIpv6: "[ {display} ] not a legitimate IPV6 address.",
|
||||||
requireEnum: "{display} is not a reasonable enumeration value.",
|
requireEnum: "[ {display} ] is not a reasonable enumeration value.",
|
||||||
requireBool: "{display} is not a reasonable boolean value.",
|
requireBool: "[ {display} ] is not a reasonable boolean value.",
|
||||||
editOkTip: "Confirm updating the value of this {num} attribute?",
|
editOkTip: "Confirm updating the value of this [ {num} ] attribute?",
|
||||||
updateItemTip: "Confirm updating the data item with Index [{num}]?",
|
updateItemTip: "Confirm updating the data item with Index [{num}]?",
|
||||||
delItemTip: "Confirm deleting the data item with Index [{num}]?",
|
delItemTip: "Confirm deleting the data item with Index [{num}]?",
|
||||||
arrayMore: "Expand",
|
arrayMore: "Expand",
|
||||||
@@ -575,14 +585,42 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
ne: {
|
ne: {
|
||||||
neInfo: {
|
common: {
|
||||||
version: "Version",
|
neType: 'NE Type',
|
||||||
|
neTypePlease: "Please select network element type",
|
||||||
|
neTypeTip: 'Fill in the type of network element to be created, e.g. SMF.',
|
||||||
|
neId: 'NE ID',
|
||||||
|
neIdPlease: 'Please enter the network element identification',
|
||||||
|
neIdTip: 'Fill in the unique identifier of the network element binding',
|
||||||
|
rmUid: 'Resource Unique ID',
|
||||||
|
rmUidPlease: 'Please enter a resource unique ID',
|
||||||
|
rmUidTip: "Tagging for data reporting of network element logs, alarms, metrics, etc.",
|
||||||
|
neName: 'NE Name',
|
||||||
|
neNamePlease: 'Please enter the name of the network element',
|
||||||
|
ipAddr: 'IP Addr',
|
||||||
|
ipAddrPlease: 'Please enter the IP address of the network element',
|
||||||
|
ipAddrTip: "Support IPV4/IPV6, synchronized change of configuration address",
|
||||||
|
port: 'Port',
|
||||||
|
portTip: "Network element port default:33030",
|
||||||
serialNum: 'Serial Number',
|
serialNum: 'Serial Number',
|
||||||
expiryDate: 'Expiry Date',
|
expiryDate: 'Expiry Date',
|
||||||
|
normalcy: 'Normal',
|
||||||
|
exceptions: 'Abnormal',
|
||||||
|
restart: 'Restart',
|
||||||
|
restartTip: 'Are you sure you want to restart the network element service?',
|
||||||
|
start: 'Start',
|
||||||
|
startTip: 'Are you sure you want to start the network element service?',
|
||||||
|
stop: 'Stop',
|
||||||
|
stopTip: 'Are you sure you want to stop the network element service?',
|
||||||
|
reload: 'Reload',
|
||||||
|
reloadTip: 'Confirm that you want to reload the network element configuration information?',
|
||||||
|
oam: 'OAM',
|
||||||
|
log: 'Logs',
|
||||||
|
},
|
||||||
|
neInfo: {
|
||||||
|
version: "Version",
|
||||||
state: "State",
|
state: "State",
|
||||||
serviceState: "Service Status",
|
serviceState: "Service Status",
|
||||||
normalcy: "Normal",
|
|
||||||
exceptions: "Abnormal",
|
|
||||||
info: 'Status Message',
|
info: 'Status Message',
|
||||||
resourceInfo: 'Resource Situation',
|
resourceInfo: 'Resource Situation',
|
||||||
sysMem: "SYS Mem",
|
sysMem: "SYS Mem",
|
||||||
@@ -590,8 +628,41 @@ export default {
|
|||||||
sysDisk: "SYS Store",
|
sysDisk: "SYS Store",
|
||||||
neCpu: "NE CPU",
|
neCpu: "NE CPU",
|
||||||
hostConfig: "Connection Configuration",
|
hostConfig: "Connection Configuration",
|
||||||
rmUID: "Data resource location identifiers are used for data tagging such as logging, alarm reporting, etc.",
|
pvflag: 'NE Virtualization',
|
||||||
ipAddr: "Support IPV4/IPV6, synchronize the change of the configuration address of the following configuration",
|
pnf: 'physical network element',
|
||||||
|
vnf: 'virtual network element',
|
||||||
|
neAddress: 'MAC',
|
||||||
|
neAddressTip: 'Record the physical address (MAC) of the network card of the network element',
|
||||||
|
dn: 'network identifier',
|
||||||
|
vendorName: 'provider',
|
||||||
|
province: 'Service Area',
|
||||||
|
addTitle: 'New network element information',
|
||||||
|
editTitle: 'Edit network element information',
|
||||||
|
delTip: 'Confirm deletion of network element information data items?',
|
||||||
|
oam: {
|
||||||
|
title: 'OAM Configuration',
|
||||||
|
sync: 'Sync to NE',
|
||||||
|
oamEnable: 'Service',
|
||||||
|
oamPort: 'Port',
|
||||||
|
snmpEnable: 'Service',
|
||||||
|
snmpPort: 'Port',
|
||||||
|
kpiEnable: 'Report',
|
||||||
|
kpiTimer: 'Reporting Cycle',
|
||||||
|
kpiTimerPlease: 'Please enter the reporting period (in seconds)',
|
||||||
|
},
|
||||||
|
backConf: {
|
||||||
|
export: 'Config Export',
|
||||||
|
import: 'Config Import',
|
||||||
|
title: 'Configuration File Import',
|
||||||
|
importType: 'Source of File',
|
||||||
|
server:'Server File',
|
||||||
|
local:'Local File',
|
||||||
|
localUpload:'Local Upload',
|
||||||
|
exportTip:'Confirm that you want to export the network element configuration file?',
|
||||||
|
exportMsg:'Exported successfully, please download from [Backup Management].',
|
||||||
|
filePlease: "Please upload a file",
|
||||||
|
fileNamePlease: 'Please select the server file',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
neHost: {
|
neHost: {
|
||||||
hostType: "Type",
|
hostType: "Type",
|
||||||
@@ -610,13 +681,13 @@ export default {
|
|||||||
privateKey: "Private Key",
|
privateKey: "Private Key",
|
||||||
privateKeyPlease: "Please fill in the private key characters correctly ~/.ssh/id_rsa",
|
privateKeyPlease: "Please fill in the private key characters correctly ~/.ssh/id_rsa",
|
||||||
passPhrase: "Private Key Cipher",
|
passPhrase: "Private Key Cipher",
|
||||||
remark: "Remark",
|
|
||||||
createTime: "Time",
|
|
||||||
delTip: "Confirm that you want to delete the host number [{num}]?",
|
delTip: "Confirm that you want to delete the host number [{num}]?",
|
||||||
addTitle: "Add Host Connection",
|
addTitle: "Add Host Connection",
|
||||||
editTitle: "Edit Host Connection",
|
editTitle: "Edit Host Connection",
|
||||||
test: "Test Connection To Host",
|
test: "Test Connection",
|
||||||
testOk: "Test Connection Successful",
|
testOk: "Test Connection Successful",
|
||||||
|
authRSA: 'Secret Authorization',
|
||||||
|
authRSATip: "Do I have to configure secret-free authorization?",
|
||||||
},
|
},
|
||||||
neHostCmd: {
|
neHostCmd: {
|
||||||
cmdType: "Type",
|
cmdType: "Type",
|
||||||
@@ -625,12 +696,125 @@ export default {
|
|||||||
titlePlease: "Please fill in the command name correctly",
|
titlePlease: "Please fill in the command name correctly",
|
||||||
command: "Command",
|
command: "Command",
|
||||||
commandPlease: "Please enter a valid command string correctly",
|
commandPlease: "Please enter a valid command string correctly",
|
||||||
remark: "Remark",
|
|
||||||
createTime: "Time",
|
|
||||||
delTip: "Are you sure you want to delete the message with command number [{num}]?",
|
delTip: "Are you sure you want to delete the message with command number [{num}]?",
|
||||||
addTitle: "New Host Commands",
|
addTitle: "New Host Commands",
|
||||||
editTitle: "Edit Host Commands",
|
editTitle: "Edit Host Commands",
|
||||||
},
|
},
|
||||||
|
neSoftware: {
|
||||||
|
uploadTitle: "Update Software",
|
||||||
|
upload: "Upload",
|
||||||
|
uploadNotFile: "No software files uploaded",
|
||||||
|
uploadBatch: "Update Softwares",
|
||||||
|
uploadBatchMax: "Multiple packages can be uploaded, with up to {txt} selected at the same time.",
|
||||||
|
uploadFileName: "Parses file names in the format of: amf-r2.240x.xx-xxx",
|
||||||
|
name: "File Name",
|
||||||
|
path: "Software File",
|
||||||
|
pathPlease: "Please upload the software package file",
|
||||||
|
version: "Software Version",
|
||||||
|
versionPlease: "Please enter the software version number",
|
||||||
|
delTip: "Confirmed to remove the package?",
|
||||||
|
downTip: "Confirmation to download package [{txt}]?",
|
||||||
|
fileCheckType: 'The corresponding network element type is not resolved',
|
||||||
|
fileCheckVer: 'The corresponding version number is not resolved',
|
||||||
|
fileTypeNotEq: 'Not a specified network element type {txt}',
|
||||||
|
fileTypeExists: 'Same type of file already exists',
|
||||||
|
fileNameExists: 'File with same name already exists',
|
||||||
|
fileCheckTypeDep: 'The specified dependency package type is not resolved',
|
||||||
|
dependFile: 'Software Dependencies',
|
||||||
|
dependFileTip: 'File name resolution is the same as above, and installation is based on the order of uploading.',
|
||||||
|
},
|
||||||
|
neVersion: {
|
||||||
|
upgrade: "Upgrade To New Version",
|
||||||
|
upgradeTip: "Confirmed to upgrade to the new version?",
|
||||||
|
upgradeTipEmpty: "There are currently no new versions available",
|
||||||
|
upgradeTipEqual: "Current version is the same as the new version",
|
||||||
|
rollback: 'Switch to previous version',
|
||||||
|
rollbackTip: "Confirm switching to the previous version?",
|
||||||
|
rollbackTipEmpty: "There is currently no previous version available",
|
||||||
|
rollbackTipEqual: 'The current version is the same as the previous version',
|
||||||
|
version: "Current Version",
|
||||||
|
preVersion: "Previous Version",
|
||||||
|
newVersion: "New Version",
|
||||||
|
status: "Revision Status",
|
||||||
|
upgradeBatch: "Batch Upgrade",
|
||||||
|
upgradeBatchTip: "Do you perform new version upgrades on checked records?",
|
||||||
|
upgradeNotNewVer: 'No new version found',
|
||||||
|
upgradeDone: 'Update complete, service being reloaded',
|
||||||
|
upgradeFail: 'The update failed, check if the service terminal environment is available!',
|
||||||
|
upgradeModal: 'Network Element Version Updates',
|
||||||
|
},
|
||||||
|
neLicense: {
|
||||||
|
status: "License Status",
|
||||||
|
change: "Change License",
|
||||||
|
reload: "Refresh Info",
|
||||||
|
reloadTip: "Confirmed to refresh license information?",
|
||||||
|
reloadBatch: "Batch Refresh",
|
||||||
|
reloadBatchTip: "Do you do an information refresh on checked records?",
|
||||||
|
updateTtile: "Update License",
|
||||||
|
downCodeTop: "Confirmed to save the license activation code to a file?",
|
||||||
|
activationRequestCode: "License Activation Code",
|
||||||
|
licensePath: "License File",
|
||||||
|
licensePathTip: "Please upload license file",
|
||||||
|
upload: 'Upload',
|
||||||
|
uploadBatch: "Upload License",
|
||||||
|
uploadChangeFail: "Some network elements failed to update the license, please check whether the service terminal environment is available!",
|
||||||
|
},
|
||||||
|
neConfPara5G: {
|
||||||
|
save: 'Save',
|
||||||
|
reload: 'Reload',
|
||||||
|
title: 'Save Info',
|
||||||
|
sync: 'Sync to NE',
|
||||||
|
syncNe: 'Select NE',
|
||||||
|
syncNeDone: 'Synchronization to network element terminals complete',
|
||||||
|
saveOk: 'Save Success!',
|
||||||
|
},
|
||||||
|
neQuickSetup: {
|
||||||
|
stepPrev: 'Previous',
|
||||||
|
stepPrevTip: 'Confirm that you want to abandon the current change and return to the previous step?',
|
||||||
|
stepNext: 'Next',
|
||||||
|
stepSave: 'Save',
|
||||||
|
startTitle: 'Service Terminal Environment',
|
||||||
|
startDesc: 'Test connectivity to network element services',
|
||||||
|
startStepNext: 'Confirm that you want to proceed to the next step to configure the network element information?',
|
||||||
|
addr: 'Terminal IP',
|
||||||
|
kernelName: 'System',
|
||||||
|
kernelRelease: 'Kernel',
|
||||||
|
machine: 'Framework',
|
||||||
|
prettyName: 'Platform',
|
||||||
|
prettyNameTip: 'Support Ubuntu',
|
||||||
|
nodename: 'Node Name',
|
||||||
|
auth: 'Competence Grant',
|
||||||
|
sudo: 'sudo',
|
||||||
|
sudoErr: 'To ensure that you have permission to install packages, configure to grant the current user permission to allow passwordless sudo privileges.',
|
||||||
|
sshLink: 'confidentiality',
|
||||||
|
configTitle: "Configuring Network Elements",
|
||||||
|
configDesc: "Fill in the basic information of the network element",
|
||||||
|
configAddTitle: 'New Tips',
|
||||||
|
configAddTip: 'Is it added as new network element information and continue?',
|
||||||
|
configUpdateTitle: 'Update Tips',
|
||||||
|
configUpdateTip: 'Does it update to the already existing network element information and continue?',
|
||||||
|
configStepNext: 'Confirm that you want to proceed to the next step for the Network Element software installation?',
|
||||||
|
installTitle: "Network Element Installation",
|
||||||
|
installDesc: "Installation to Service Terminal",
|
||||||
|
installConfirmTip: 'Are you sure you want to install package [{name}]?',
|
||||||
|
installStepNext: 'Confirm that you want to proceed to the next step for network element authorization?',
|
||||||
|
installSource: 'Software Source',
|
||||||
|
installSourceOption: 'Uploaded',
|
||||||
|
installSourceUpload: 'New Upload',
|
||||||
|
installSelect: 'Select Record',
|
||||||
|
installUpload: 'Upload File',
|
||||||
|
installText: 'Installed',
|
||||||
|
licenseTitle: "Licenses",
|
||||||
|
licenseDesc: "Network element service authorization certification",
|
||||||
|
licenseResultTitle: "Whether to authorize activation immediately",
|
||||||
|
licenseResultTitleOk: 'Successful Activation',
|
||||||
|
licenseUpload: 'License',
|
||||||
|
licenseEnd: 'Finish',
|
||||||
|
licenseEndTip: "Confirmed to end the installation?",
|
||||||
|
licenseCheack: 'Waiting for network element validation',
|
||||||
|
licenseTip1: '1. Click [License] to get the license activation code, and then contact the network element vendor for activation.',
|
||||||
|
licenseTip2: '2. Clicking [Finish] will end the installation process.',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
neUser: {
|
neUser: {
|
||||||
auth: {
|
auth: {
|
||||||
@@ -644,7 +828,7 @@ export default {
|
|||||||
import: 'Import',
|
import: 'Import',
|
||||||
loadDataConfirm: 'Are you sure you want to reload the data?',
|
loadDataConfirm: 'Are you sure you want to reload the data?',
|
||||||
loadData: 'Load Data',
|
loadData: 'Load Data',
|
||||||
loadDataTip: 'Successfully fetched load data: {num} entries, the system is internally updating the data. You can click reset to refresh the data list after the loading is finished, please don it repeat click to get update!!!!',
|
loadDataTip: 'Successfully fetched load data: {num} entries, the system is internally updating the data. Please wait a moment!!!!',
|
||||||
startIMSI: 'Start IMSI',
|
startIMSI: 'Start IMSI',
|
||||||
batchAddText: 'Batch Add',
|
batchAddText: 'Batch Add',
|
||||||
batchDelText: 'Batch Delete',
|
batchDelText: 'Batch Delete',
|
||||||
@@ -671,7 +855,7 @@ export default {
|
|||||||
import: 'Import',
|
import: 'Import',
|
||||||
loadDataConfirm: 'Are you sure you want to reload the data?',
|
loadDataConfirm: 'Are you sure you want to reload the data?',
|
||||||
loadData: 'Load Data',
|
loadData: 'Load Data',
|
||||||
loadDataTip: 'Successfully fetched load data: {num} entries, the system is internally updating the data. You can click reset to refresh the data list after the loading is finished, please don it repeat click to get update!!!!',
|
loadDataTip: 'Successfully fetched load data: {num} entries, the system is internally updating the data. Please wait a moment!!!!',
|
||||||
numAdd: 'Number of releases',
|
numAdd: 'Number of releases',
|
||||||
numDel: 'Number of deleted',
|
numDel: 'Number of deleted',
|
||||||
checkDel: 'Check Delete',
|
checkDel: 'Check Delete',
|
||||||
@@ -709,6 +893,7 @@ export default {
|
|||||||
addTitle: 'Adding Policy Control Information',
|
addTitle: 'Adding Policy Control Information',
|
||||||
updateTitle: '{imsi} Policy control information',
|
updateTitle: '{imsi} Policy control information',
|
||||||
startIMSI: 'Start IMSI',
|
startIMSI: 'Start IMSI',
|
||||||
|
batchOper: 'Batch Operations',
|
||||||
batchAddText: 'Batch Add',
|
batchAddText: 'Batch Add',
|
||||||
batchDelText: 'Batch Delete',
|
batchDelText: 'Batch Delete',
|
||||||
batchUpdateText: 'Batch Modify',
|
batchUpdateText: 'Batch Modify',
|
||||||
@@ -717,9 +902,19 @@ export default {
|
|||||||
imsiTip1: 'MCC=Mobile Country Code, consisting of three digits.',
|
imsiTip1: 'MCC=Mobile Country Code, consisting of three digits.',
|
||||||
imsiTip2: 'MNC = Mobile Network Number, consisting of two digits',
|
imsiTip2: 'MNC = Mobile Network Number, consisting of two digits',
|
||||||
imsiTip3: 'MSIN = Mobile Subscriber Identification Number, consisting of 10 equal digits.',
|
imsiTip3: 'MSIN = Mobile Subscriber Identification Number, consisting of 10 equal digits.',
|
||||||
|
checkDel: 'Check Delete',
|
||||||
delSure:'Are you sure you want to delete the user with IMSI number: {imsi}?',
|
delSure:'Are you sure you want to delete the user with IMSI number: {imsi}?',
|
||||||
uploadFileOk: 'File Upload Successful',
|
uploadFileOk: 'File Upload Successful',
|
||||||
uploadFileErr: 'File Upload Failed',
|
uploadFileErr: 'File Upload Failed',
|
||||||
|
pccRuleTip:'PCC policy rule template (corresponding to parameter configuration -PCC Rules)',
|
||||||
|
sessRuleTip:' Session policy rule template (corresponding to parameter configuration-session Rules)',
|
||||||
|
qosAudioTip:' Voice call QoS(corresponding parameter configuration -QoS Template QoS ID)',
|
||||||
|
qosVideoTip:' Video call QoS(corresponding parameter configuration -QoS Template QoS ID)',
|
||||||
|
hdrTip:'HTTP Header enhancement (corresponding parameter configuration -Header Enrich Template)',
|
||||||
|
ueTip:'UE policy template (example: uep_001)',
|
||||||
|
sarTip1:' Service area Restriction ',
|
||||||
|
sarTip2:'(corresponding parameter setting -Service Area Restriction)',
|
||||||
|
rfsfTip:'RAT Frequency Selection Priority',
|
||||||
},
|
},
|
||||||
base5G: {
|
base5G: {
|
||||||
neType: 'NE Object',
|
neType: 'NE Object',
|
||||||
@@ -755,7 +950,7 @@ export default {
|
|||||||
viewTask:'View Task',
|
viewTask:'View Task',
|
||||||
editTask:'Edit Task',
|
editTask:'Edit Task',
|
||||||
addTask:'Add Task',
|
addTask:'Add Task',
|
||||||
stopTask:'Pending',
|
stopTask:'Stop',
|
||||||
errorTaskInfo: 'Failed to obtain task information',
|
errorTaskInfo: 'Failed to obtain task information',
|
||||||
granulOptionPlease:'Please select the measurement granularity',
|
granulOptionPlease:'Please select the measurement granularity',
|
||||||
letupSure:'Confirm activation of task with number [{id}]?',
|
letupSure:'Confirm activation of task with number [{id}]?',
|
||||||
@@ -815,7 +1010,7 @@ export default {
|
|||||||
exportSure:'Confirm whether to export all statistical data',
|
exportSure:'Confirm whether to export all statistical data',
|
||||||
exportEmpty: "Export data is empty",
|
exportEmpty: "Export data is empty",
|
||||||
showChartSelected: "Show All",
|
showChartSelected: "Show All",
|
||||||
realTimeData: "Real Time 5s Data",
|
realTimeData: "Real Time Data",
|
||||||
},
|
},
|
||||||
customTarget:{
|
customTarget:{
|
||||||
kpiId:' Custom Indicator',
|
kpiId:' Custom Indicator',
|
||||||
@@ -944,7 +1139,7 @@ export default {
|
|||||||
alarmSeq:'Sequence Number',
|
alarmSeq:'Sequence Number',
|
||||||
objectName:'Object Name',
|
objectName:'Object Name',
|
||||||
locationInfo:'Location Info',
|
locationInfo:'Location Info',
|
||||||
province:'Province',
|
province:'Region',
|
||||||
addInfo:'Additional Info',
|
addInfo:'Additional Info',
|
||||||
specificProblemId:'Cause ID',
|
specificProblemId:'Cause ID',
|
||||||
specificProblem:'Cause',
|
specificProblem:'Cause',
|
||||||
@@ -965,6 +1160,7 @@ export default {
|
|||||||
showSet:'Show filter settings',
|
showSet:'Show filter settings',
|
||||||
exportSure:'Confirm whether to export all active alarm information',
|
exportSure:'Confirm whether to export all active alarm information',
|
||||||
viewIdInfo:'View {alarmId} record information',
|
viewIdInfo:'View {alarmId} record information',
|
||||||
|
closeModal:'Close',
|
||||||
},
|
},
|
||||||
historyAlarm:{
|
historyAlarm:{
|
||||||
exportSure:'Confirm whether to export all historical alarm information',
|
exportSure:'Confirm whether to export all historical alarm information',
|
||||||
@@ -977,13 +1173,16 @@ export default {
|
|||||||
noChange:'There is no change in the alarm forwarding settings.',
|
noChange:'There is no change in the alarm forwarding settings.',
|
||||||
forwardSet:'Alarm Forwarding Setting',
|
forwardSet:'Alarm Forwarding Setting',
|
||||||
},
|
},
|
||||||
|
eventAlarm:{
|
||||||
|
exportSure:'Confirm whether to export all event alarm information',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
logManage:{
|
logManage:{
|
||||||
alarm:{
|
alarm:{
|
||||||
type:'NE Type',
|
type:'NE Type',
|
||||||
neId:'NE UID',
|
neId:'NE UID',
|
||||||
alarmId:'Alarm ID',
|
alarmId:'Alarm ID',
|
||||||
alarmSeq:'Sequece Number',
|
alarmSeq:'Sequence Number',
|
||||||
alarmCode:'Alarm Code',
|
alarmCode:'Alarm Code',
|
||||||
alarmStatus:'Status',
|
alarmStatus:'Status',
|
||||||
eventTime:'Event Time',
|
eventTime:'Event Time',
|
||||||
@@ -1002,12 +1201,13 @@ export default {
|
|||||||
type:'NE Type',
|
type:'NE Type',
|
||||||
neId:'NE UID',
|
neId:'NE UID',
|
||||||
alarmId:'Alarm ID',
|
alarmId:'Alarm ID',
|
||||||
alarmSeq:'Sequece Number',
|
alarmSeq:'Sequence Number',
|
||||||
alarmObj:'Object',
|
alarmObj:'Forward Users',
|
||||||
|
alarmInter:'Forward Interface',
|
||||||
alarmTitle:'Alarm Title',
|
alarmTitle:'Alarm Title',
|
||||||
alarmInfo:'Alarm Content',
|
alarmInfo:'Operation Results',
|
||||||
eventTime:'Generation Time',
|
eventTime:'Event Time',
|
||||||
logTime:'Record Time'
|
logTime:'Log Time'
|
||||||
},
|
},
|
||||||
neFile: {
|
neFile: {
|
||||||
neType:'NE Type',
|
neType:'NE Type',
|
||||||
@@ -1152,12 +1352,12 @@ export default {
|
|||||||
jobLog: {
|
jobLog: {
|
||||||
jobName: "Job Name",
|
jobName: "Job Name",
|
||||||
jobGroup: "Job Group",
|
jobGroup: "Job Group",
|
||||||
invokeTarget: "Invoke Target",
|
invokeTarget: "Job Invoke",
|
||||||
status: "Status",
|
status: "Status",
|
||||||
status0: "Failures",
|
status0: "Failures",
|
||||||
status1: "Active",
|
status1: "Active",
|
||||||
createTime: "Create Time",
|
createTime: "Time",
|
||||||
costTime: "Cost Time",
|
costTime: "Time Consumption",
|
||||||
viewLog: "Scheduling log Info",
|
viewLog: "Scheduling log Info",
|
||||||
delTip: "Are you sure you want to delete the scheduling log entry with the number [{num}]?",
|
delTip: "Are you sure you want to delete the scheduling log entry with the number [{num}]?",
|
||||||
delOk: "Deleted Successfully",
|
delOk: "Deleted Successfully",
|
||||||
@@ -1191,7 +1391,7 @@ export default {
|
|||||||
cacheInfo: {
|
cacheInfo: {
|
||||||
baseInfo: "Basic Info",
|
baseInfo: "Basic Info",
|
||||||
version: "Service Versions",
|
version: "Service Versions",
|
||||||
mode: "Perating Mode",
|
mode: "Operating Mode",
|
||||||
modeStandalone: "stand-alone",
|
modeStandalone: "stand-alone",
|
||||||
modeClusters: "clusters",
|
modeClusters: "clusters",
|
||||||
port: "Port",
|
port: "Port",
|
||||||
@@ -1392,7 +1592,7 @@ export default {
|
|||||||
userInfo:' User Info',
|
userInfo:' User Info',
|
||||||
userNum: 'User Number',
|
userNum: 'User Number',
|
||||||
account: 'Account',
|
account: 'Account',
|
||||||
userName: 'User Name',
|
userName: 'Nick Name',
|
||||||
permission: 'Role',
|
permission: 'Role',
|
||||||
className: 'Department',
|
className: 'Department',
|
||||||
loginIp: 'Login Address',
|
loginIp: 'Login Address',
|
||||||
@@ -1400,7 +1600,7 @@ export default {
|
|||||||
status: 'Status',
|
status: 'Status',
|
||||||
userNameTip:'The account cannot start with a number and can contain uppercase and lowercase letters, numbers, and no less than 5 digits',
|
userNameTip:'The account cannot start with a number and can contain uppercase and lowercase letters, numbers, and no less than 5 digits',
|
||||||
passwdTip:'The password should contain at least uppercase and lowercase letters, numbers, special symbols, and no less than 6 digits',
|
passwdTip:'The password should contain at least uppercase and lowercase letters, numbers, special symbols, and no less than 6 digits',
|
||||||
nickNameTip:'Nicknames can only contain letters, numbers, Chinese characters, and underscores, with no less than 2 digits',
|
nickNameTip:'Nicknames no less than 2 digits',
|
||||||
emailTip:'Please enter the correct email address',
|
emailTip:'Please enter the correct email address',
|
||||||
phoneTip:'Please enter the correct phone number',
|
phoneTip:'Please enter the correct phone number',
|
||||||
resetPwd:'Reset Password',
|
resetPwd:'Reset Password',
|
||||||
@@ -1423,7 +1623,7 @@ export default {
|
|||||||
userWork:'User position',
|
userWork:'User position',
|
||||||
userWorkPlease: 'Please select user post',
|
userWorkPlease: 'Please select user post',
|
||||||
userTip:'User Description',
|
userTip:'User Description',
|
||||||
loginPwd:'Login password',
|
loginPwd:'Password',
|
||||||
updateSure:'Do you want to update existing data',
|
updateSure:'Do you want to update existing data',
|
||||||
downloadObj:'Download Tpl',
|
downloadObj:'Download Tpl',
|
||||||
importTitle:'User Import',
|
importTitle:'User Import',
|
||||||
@@ -1509,6 +1709,9 @@ export default {
|
|||||||
i18nOpen: "Display Switch",
|
i18nOpen: "Display Switch",
|
||||||
i18nDefault: "Default Languages",
|
i18nDefault: "Default Languages",
|
||||||
i18nInstruction: 'Whether to display the internationalization switch and set the system default language',
|
i18nInstruction: 'Whether to display the internationalization switch and set the system default language',
|
||||||
|
reset: "System Reset",
|
||||||
|
resetInstruction: "A system reset will erase all data in the current system, please proceed with caution!!!!",
|
||||||
|
resetTipContent: 'Are you sure you want to clear all data from the current system and insist on continuing?',
|
||||||
},
|
},
|
||||||
role:{
|
role:{
|
||||||
allScopeOptions:'All data permissions',
|
allScopeOptions:'All data permissions',
|
||||||
@@ -1516,11 +1719,11 @@ export default {
|
|||||||
onlyClassScopeOptions:'Data permissions of this department',
|
onlyClassScopeOptions:'Data permissions of this department',
|
||||||
classAllScopeOptions:'Data permissions for this department and the following',
|
classAllScopeOptions:'Data permissions for this department and the following',
|
||||||
myselfScopeOptions:'Only personal data permissions',
|
myselfScopeOptions:'Only personal data permissions',
|
||||||
roleId:'Role ID',
|
roleId:'Role Number',
|
||||||
roleName:'Role Name',
|
roleName:'Role Name',
|
||||||
roleKey:'Role Key',
|
roleKey:'Role Key',
|
||||||
roleSort:'Role Order',
|
roleSort:'Role Sort',
|
||||||
roleStatus:'Status',
|
roleStatus:'Role Status',
|
||||||
createTime:'Creation Time',
|
createTime:'Creation Time',
|
||||||
trueValue:'Please enter {msg} correctly',
|
trueValue:'Please enter {msg} correctly',
|
||||||
roleInfo:'Role information',
|
roleInfo:'Role information',
|
||||||
@@ -1533,10 +1736,10 @@ export default {
|
|||||||
distributeUser:'Assign Users',
|
distributeUser:'Assign Users',
|
||||||
roleMark:'Role Description',
|
roleMark:'Role Description',
|
||||||
menu:'Menu Permissions',
|
menu:'Menu Permissions',
|
||||||
roleKeyTip:"Example of permission identification: Use permission identification in dba controller, such as: @PreAuthorize({ hasRoles: ['dba'] })",
|
roleKeyTip:"Privilege identifiers are used to control page controls or routing interfaces",
|
||||||
openSwitch:'Expand/Collapse',
|
openSwitch:'Expand/Collapse',
|
||||||
selAllSwitch:'Select all/Deselect all',
|
selAllSwitch:'Select All/Deselect All',
|
||||||
relationSwitch:'Father and son linkage',
|
relationSwitch:'Node Linkage',
|
||||||
normal:'Active',
|
normal:'Active',
|
||||||
stop:'Pending',
|
stop:'Pending',
|
||||||
preScope:'Scope of authority',
|
preScope:'Scope of authority',
|
||||||
@@ -1578,7 +1781,7 @@ export default {
|
|||||||
positionId:'Position Number',
|
positionId:'Position Number',
|
||||||
positionCode:'Position Code',
|
positionCode:'Position Code',
|
||||||
positionName:'Position Name',
|
positionName:'Position Name',
|
||||||
positionSort:'Position Sorting',
|
positionSort:'Position Sort',
|
||||||
positionStatus:'Position Status',
|
positionStatus:'Position Status',
|
||||||
positionMark:'Position Description',
|
positionMark:'Position Description',
|
||||||
createTime:'Creation Time',
|
createTime:'Creation Time',
|
||||||
@@ -1588,15 +1791,15 @@ export default {
|
|||||||
},
|
},
|
||||||
log:{
|
log:{
|
||||||
operate:{
|
operate:{
|
||||||
operId:'ID',
|
operId:'Log ID',
|
||||||
moduleName:'Module Name',
|
moduleName:'Module Name',
|
||||||
workType:'Business Type',
|
workType:'Business Type',
|
||||||
operUser:'Operator',
|
operUser:'Operator',
|
||||||
requestMe:'Request Method',
|
requestMe:'Request Method',
|
||||||
host:'Request Host',
|
host:'Request Host',
|
||||||
operStatus:'Operation Status',
|
operStatus:'Status',
|
||||||
operDate:'Operation Date',
|
operDate:'Time',
|
||||||
useTime:'Consumption Time',
|
useTime:'Time Consumption',
|
||||||
logInfo:'Operation Log Information',
|
logInfo:'Operation Log Information',
|
||||||
delSure:'Are you sure to delete the data item with access number [{ids}]?',
|
delSure:'Are you sure to delete the data item with access number [{ids}]?',
|
||||||
delAllSure:'Confirm to clear all login log data items?',
|
delAllSure:'Confirm to clear all login log data items?',
|
||||||
@@ -1703,6 +1906,65 @@ export default {
|
|||||||
exportOk: "Completed export",
|
exportOk: "Completed export",
|
||||||
typeDataErr: "Failed to get dictionary type information",
|
typeDataErr: "Failed to get dictionary type information",
|
||||||
},
|
},
|
||||||
|
quickStart: {
|
||||||
|
start: 'Start Setup',
|
||||||
|
skip: 'Skip',
|
||||||
|
finish: 'Complete Setup',
|
||||||
|
stepPrev: 'Previous',
|
||||||
|
stepNext: 'Next',
|
||||||
|
exit: 'Exit',
|
||||||
|
save: 'Save Info',
|
||||||
|
sysTitle: 'System Configuration',
|
||||||
|
sysAdmin: 'Administrator',
|
||||||
|
sysInfo: 'System Info',
|
||||||
|
sysLogo: 'System Logo',
|
||||||
|
sysLogoTip: 'Show the image to the system logo area to see the effect, please use a transparent background, the size of the proportion to adapt to the size of the area',
|
||||||
|
sysName: 'System Name',
|
||||||
|
sysNameTip: 'Limit system name to 20 characters in length',
|
||||||
|
sysUploadLogo: 'Confirmation of uploading the system logo file?',
|
||||||
|
sysUploadOk: 'File uploaded successfully, please save the information',
|
||||||
|
sysSave: 'Save',
|
||||||
|
sysSaveOk: 'Info saved successfully!',
|
||||||
|
sysPrevTip: 'Confirmed to go back to the previous step?',
|
||||||
|
sysNextNe: 'Confirming that you want to do a network element installation?',
|
||||||
|
sysNextDone: 'Confirmed to skip the network element installation?',
|
||||||
|
stepNeInfoTitle: "Service Configuration",
|
||||||
|
stepNeInfoDesc: "Setting the service terminal corresponding to a network element",
|
||||||
|
stepNeInfoStepPrev: 'Confirming that you want to exit the network element installation step?',
|
||||||
|
stepNeInfoStepNext: 'Confirm that you want to proceed to the next step to configure the parameters of the network element?',
|
||||||
|
stepPara5GTitle: "Configuration Parameter",
|
||||||
|
stepPara5GDesc: "Setting network element global parameter information",
|
||||||
|
stepPara5GStepPrev: 'Confirm that you want to abandon the current change and return to the previous step?',
|
||||||
|
stepPara5GStepNext: 'Confirm that you want to proceed to the next step for the network element service installation?',
|
||||||
|
stepInstallTitle: "Service Install",
|
||||||
|
stepInstallDesc: "Installation of network element services to service terminals",
|
||||||
|
stepInstallStepPrev: 'Confirm that you want to abandon the current change and return to the previous step?',
|
||||||
|
stepInstallStepNext: 'Confirm that you want to proceed to the next step for network element license authorization?',
|
||||||
|
stepInstallText: 'Select Install',
|
||||||
|
stepInstallTip: 'Confirm the installation of the new version of the chosen Net Meta?',
|
||||||
|
stepInstallModal: 'Network Element For Install',
|
||||||
|
stepInstallNotNewVer: 'No new version found',
|
||||||
|
stepInstallDone: 'Installation complete, service initialized',
|
||||||
|
stepInstallFail: 'Installation fails, check if the service terminal environment is available!',
|
||||||
|
stepLicenseTitle: "Service License",
|
||||||
|
stepLicenseDesc: "Obtaining a license activation code for authorization authentication",
|
||||||
|
stepLicenseReload: 'Select Refresh',
|
||||||
|
stepLicenseReloadTip: 'Confirm refreshing selected license information?',
|
||||||
|
stepLicenseDownCode: 'Select Download Activation Code',
|
||||||
|
stepLicenseDownCodeTip: 'Confirmed to download the selected network element license activation code to a text file?',
|
||||||
|
stepLicenseStepPrev: 'Confirm that you want to abandon the current change and return to the previous step?',
|
||||||
|
stepLicenseStepNext: 'Confirmed to end the network element installation step?',
|
||||||
|
stepLicenseStepNext2: 'Please download the Net Element License Authorization Code file to save it and contact the Net Element vendor to get the authorization license',
|
||||||
|
stepLicenseEnd: 'End',
|
||||||
|
doneTitle: "Completing the Configuration",
|
||||||
|
doneTip: 'Please enter the system and configure it as appropriate.',
|
||||||
|
doneNETitle: 'Configuration of the network element installation has been performed',
|
||||||
|
doneNEDesc: 'In case of abnormal network elements, the license can be reinstalled in the system',
|
||||||
|
doneSkipTitle: 'No network element installation configuration',
|
||||||
|
doneSkipDesc: 'The system will initialize the network element information by default, which can be modified or installed within the system.',
|
||||||
|
donePrevTip: 'Confirmed to go back to the previous step?',
|
||||||
|
doneOkTip: 'Confirm that you have completed the setup and started using it?',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mmlManage: {
|
mmlManage: {
|
||||||
cmdTitle: "Command Navigator",
|
cmdTitle: "Command Navigator",
|
||||||
@@ -1710,14 +1972,14 @@ export default {
|
|||||||
cmdOpTip: "Select the item to be operated in the left command navigation!",
|
cmdOpTip: "Select the item to be operated in the left command navigation!",
|
||||||
cmdNoTip: "{num} no optional command operation",
|
cmdNoTip: "{num} no optional command operation",
|
||||||
require: "Mandatory parameter: {num}",
|
require: "Mandatory parameter: {num}",
|
||||||
requireUn: "{display} input value is of unknown type",
|
requireUn: "[ {display} ] input value is of unknown type",
|
||||||
requireString: "The {display} parameter value is invalid.",
|
requireString: "[ {display} ] parameter value is invalid.",
|
||||||
requireInt: "{display} Parameter value not in reasonable range {filter}",
|
requireInt: "[ {display} ] parameter value not in reasonable range {filter}",
|
||||||
requireIpv4: "{display} not a legitimate IPV4 address",
|
requireIpv4: "[ {display} ] not a legitimate IPV4 address",
|
||||||
requireIpv6: "{display} Not a legitimate IPV6 address.",
|
requireIpv6: "[ {display} ] not a legitimate IPV6 address.",
|
||||||
requireEnum: "{display} is not a reasonable enumeration value.",
|
requireEnum: "[ {display} ] is not a reasonable enumeration value.",
|
||||||
requireBool: "{display} is not a reasonable boolean value.",
|
requireBool: "[ {display} ] is not a reasonable boolean value.",
|
||||||
requireFile: "{display} is not a value that matches the parameter file type.",
|
requireFile: "[ {display} ] is not a value that matches the parameter file type.",
|
||||||
cmdQuickEntry: "Command Quick Entry",
|
cmdQuickEntry: "Command Quick Entry",
|
||||||
cmdQuickEntryHelp: "Line feed (Shift + Enter), Execute (Enter)",
|
cmdQuickEntryHelp: "Line feed (Shift + Enter), Execute (Enter)",
|
||||||
cmdParamPanel: "Parameter Panel",
|
cmdParamPanel: "Parameter Panel",
|
||||||
|
|||||||
+307
-45
@@ -2,6 +2,7 @@ export default {
|
|||||||
// 语言
|
// 语言
|
||||||
i18n: '中文',
|
i18n: '中文',
|
||||||
hello: '你好',
|
hello: '你好',
|
||||||
|
welcome: '欢迎使用,核心网管理平台',
|
||||||
|
|
||||||
// 通用
|
// 通用
|
||||||
common: {
|
common: {
|
||||||
@@ -34,7 +35,6 @@ export default {
|
|||||||
unableNull:'不能为空',
|
unableNull:'不能为空',
|
||||||
moreText: '更多',
|
moreText: '更多',
|
||||||
searchBarText: '搜索栏',
|
searchBarText: '搜索栏',
|
||||||
tableStripedText: '表格斑马纹',
|
|
||||||
reloadText: '刷新',
|
reloadText: '刷新',
|
||||||
columnSetText: '列设置',
|
columnSetText: '列设置',
|
||||||
columnSetTitle: '列展示/排序',
|
columnSetTitle: '列展示/排序',
|
||||||
@@ -53,9 +53,15 @@ export default {
|
|||||||
fold: '折叠',
|
fold: '折叠',
|
||||||
},
|
},
|
||||||
rowId: '编号',
|
rowId: '编号',
|
||||||
|
createTime: '创建时间',
|
||||||
|
updateTime: '更新时间',
|
||||||
|
remark: '备注',
|
||||||
|
description: '说明',
|
||||||
operate: '操作',
|
operate: '操作',
|
||||||
operateOk: '操作成功!',
|
operateOk: '操作成功!',
|
||||||
operateErr: '操作失败!',
|
operateErr: '操作失败!',
|
||||||
|
copyText: "复制",
|
||||||
|
copyOk: '复制成功!',
|
||||||
units: {
|
units: {
|
||||||
second: '秒',
|
second: '秒',
|
||||||
minute: '分钟',
|
minute: '分钟',
|
||||||
@@ -130,6 +136,8 @@ export default {
|
|||||||
backLogin:'退出并重新登录',
|
backLogin:'退出并重新登录',
|
||||||
backReload:'正在重启,请稍等...',
|
backReload:'正在重启,请稍等...',
|
||||||
backReload2:'当准备就绪的时候,你的浏览器会自动刷新。',
|
backReload2:'当准备就绪的时候,你的浏览器会自动刷新。',
|
||||||
|
systemReset:'正在重置,请稍等...',
|
||||||
|
systemReset2:'数据信息正在重置',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -164,6 +172,9 @@ export default {
|
|||||||
codeHit: '验证码',
|
codeHit: '验证码',
|
||||||
codeText: '获取验证码',
|
codeText: '获取验证码',
|
||||||
codeSmsSend: '发送成功,请注意查看短信',
|
codeSmsSend: '发送成功,请注意查看短信',
|
||||||
|
ipPlease: '请输入有效的IP地址',
|
||||||
|
ipv4Reg: '不是有效IPv4地址',
|
||||||
|
ipv6Reg: '不是有效IPv6地址',
|
||||||
},
|
},
|
||||||
|
|
||||||
// 布局
|
// 布局
|
||||||
@@ -262,10 +273,10 @@ export default {
|
|||||||
email: "电子邮箱",
|
email: "电子邮箱",
|
||||||
emailPleace: "请输入正确的电子邮箱",
|
emailPleace: "请输入正确的电子邮箱",
|
||||||
phonenumber: "手机号码",
|
phonenumber: "手机号码",
|
||||||
phonenumberPleace: "请输入正确的电子邮箱",
|
phonenumberPleace: "请输入正确的手机号码",
|
||||||
nick: "用户昵称",
|
nick: "用户昵称",
|
||||||
nickPleace: "请输入用户昵称",
|
nickPleace: "请输入用户昵称",
|
||||||
nickTip: "昵称只能包含字母、数字、中文和下划线,且不少于2位",
|
nickTip: "昵称少于2位",
|
||||||
profileTip: "确认要提交修改用户基本信息吗?",
|
profileTip: "确认要提交修改用户基本信息吗?",
|
||||||
profileOk: "用户基本信息修改成功!",
|
profileOk: "用户基本信息修改成功!",
|
||||||
know: "我知道了",
|
know: "我知道了",
|
||||||
@@ -424,15 +435,14 @@ export default {
|
|||||||
letUpTime:'激活时间',
|
letUpTime:'激活时间',
|
||||||
createTime:'创建时间',
|
createTime:'创建时间',
|
||||||
onlyAble:'只支持上传文件格式 {fileText}',
|
onlyAble:'只支持上传文件格式 {fileText}',
|
||||||
nullData:'暂无网元列表数据',
|
|
||||||
nullVersion:'当前网元无可回退版本',
|
nullVersion:'当前网元无可回退版本',
|
||||||
},
|
},
|
||||||
license: {
|
license: {
|
||||||
neTypePlease: '选择网元类型',
|
neTypePlease: '选择网元类型',
|
||||||
neType: '网元类型',
|
neType: '网元类型',
|
||||||
fileName: '文件名',
|
serialNum: '序列号',
|
||||||
createTime: '上传时间',
|
createTime: '时间',
|
||||||
comment: '文件说明',
|
comment: '说明',
|
||||||
updateComment: 'License说明',
|
updateComment: 'License说明',
|
||||||
updateCommentPlease: '请输入License说明',
|
updateCommentPlease: '请输入License说明',
|
||||||
updateFile: 'License文件',
|
updateFile: 'License文件',
|
||||||
@@ -471,21 +481,21 @@ export default {
|
|||||||
neType: "网元类型",
|
neType: "网元类型",
|
||||||
neTypePleace: "请选择网元类型",
|
neTypePleace: "请选择网元类型",
|
||||||
noConfigData: "暂无配置项数据",
|
noConfigData: "暂无配置项数据",
|
||||||
updateValue: "{num} 属性值修改成功",
|
updateValue: "【 {num} 】 属性值修改成功",
|
||||||
updateValueErr: "属性值修改失败",
|
updateValueErr: "属性值修改失败",
|
||||||
updateItem: "修改 Index 为 {num} 记录成功",
|
updateItem: "修改 Index 为 {num} 记录成功",
|
||||||
updateItemErr: "记录修改失败",
|
updateItemErr: "记录修改失败",
|
||||||
delItemOk: "删除 Index 为 {num} 记录成功",
|
delItemOk: "删除 Index 为 {num} 记录成功",
|
||||||
addItemOk: "新增 Index 为 {num} 记录成功",
|
addItemOk: "新增 Index 为 {num} 记录成功",
|
||||||
addItemErr: "记录新增失败",
|
addItemErr: "记录新增失败",
|
||||||
requireUn: "{display} 输入值是未知类型",
|
requireUn: "【 {display} 】输入值是未知类型",
|
||||||
requireString: "{display} 参数值不合理",
|
requireString: "【 {display} 】参数值不合理",
|
||||||
requireInt: "{display} 参数值不在合理范围 {filter}",
|
requireInt: "【 {display} 】参数值不在合理范围 {filter}",
|
||||||
requireIpv4: "{display} 不是合法的IPV4地址",
|
requireIpv4: "【 {display} 】不是合法的IPV4地址",
|
||||||
requireIpv6: "{display} 不是合法的IPV6地址",
|
requireIpv6: "【 {display} 】不是合法的IPV6地址",
|
||||||
requireEnum: "{display} 不是合理的枚举值",
|
requireEnum: "【 {display} 】不是合理的枚举值",
|
||||||
requireBool: "{display} 不是合理的布尔类型的值",
|
requireBool: "【 {display} 】不是合理的布尔类型的值",
|
||||||
editOkTip: "确认更新该{num}属性值吗?",
|
editOkTip: "确认更新该【 {num} 】属性值吗?",
|
||||||
updateItemTip: "确认更新Index为 【{num}】 的数据项?",
|
updateItemTip: "确认更新Index为 【{num}】 的数据项?",
|
||||||
delItemTip: "确认删除Index为 【{num}】 的数据项?",
|
delItemTip: "确认删除Index为 【{num}】 的数据项?",
|
||||||
arrayMore: "展开",
|
arrayMore: "展开",
|
||||||
@@ -575,14 +585,42 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
ne: {
|
ne: {
|
||||||
neInfo: {
|
common: {
|
||||||
version: "网元版本",
|
neType: '网元类型',
|
||||||
|
neTypePlease: "请选择网元类型",
|
||||||
|
neTypeTip: '填写创建的网元类型,如:SMF',
|
||||||
|
neId: '网元标识',
|
||||||
|
neIdPlease: '请输入网元标识',
|
||||||
|
neIdTip: '填写网元绑定的唯一标识',
|
||||||
|
rmUid: '资源唯一标识',
|
||||||
|
rmUidPlease: '请输入资源唯一标识',
|
||||||
|
rmUidTip: "用于网元日志、告警、指标等数据上报的标记",
|
||||||
|
neName: '网元名称',
|
||||||
|
neNamePlease: '请输入网元名称',
|
||||||
|
ipAddr: '服务IP',
|
||||||
|
ipAddrPlease: '请输入网元服务IP地址',
|
||||||
|
ipAddrTip: "支持IPV4/IPV6,同步变更配置地址",
|
||||||
|
port: '服务端口',
|
||||||
|
portTip: "网元服务端口,默认:33030",
|
||||||
serialNum: '序列号',
|
serialNum: '序列号',
|
||||||
expiryDate: '许可证到期日期',
|
expiryDate: '许可证到期日期',
|
||||||
|
normalcy: '正常',
|
||||||
|
exceptions: '异常',
|
||||||
|
restart: '重启',
|
||||||
|
restartTip: '确认要重新启动网元服务吗?',
|
||||||
|
start: '启动',
|
||||||
|
startTip: '确认要启动网元服务吗?',
|
||||||
|
stop: '停止',
|
||||||
|
stopTip: '确认要停止网元服务吗?',
|
||||||
|
reload: '重载',
|
||||||
|
reloadTip: '确认要重载网元配置信息吗?',
|
||||||
|
oam: 'OAM',
|
||||||
|
log: '日志',
|
||||||
|
},
|
||||||
|
neInfo: {
|
||||||
|
version: "网元版本",
|
||||||
state: "网元状态",
|
state: "网元状态",
|
||||||
serviceState: "服务状态",
|
serviceState: "服务状态",
|
||||||
normalcy: "正常",
|
|
||||||
exceptions: "异常",
|
|
||||||
info: '状态信息',
|
info: '状态信息',
|
||||||
resourceInfo: '资源情况',
|
resourceInfo: '资源情况',
|
||||||
sysMem: "系统内存",
|
sysMem: "系统内存",
|
||||||
@@ -590,8 +628,41 @@ export default {
|
|||||||
sysDisk: "系统存储",
|
sysDisk: "系统存储",
|
||||||
neCpu: "网元CPU",
|
neCpu: "网元CPU",
|
||||||
hostConfig: "终端连接配置",
|
hostConfig: "终端连接配置",
|
||||||
rmUID: "数据资源定位标识符用于日志、告警上报等数据标记",
|
pvflag: '网元虚拟化标识',
|
||||||
ipAddr: "支持IPV4/IPV6,同步变更下方配置的配置地址",
|
pnf: '物理网元',
|
||||||
|
vnf: '虚拟网元',
|
||||||
|
neAddress: '物理地址(MAC)',
|
||||||
|
neAddressTip: '记录网元的网卡物理地址(MAC)',
|
||||||
|
dn: '网络标识',
|
||||||
|
vendorName: '提供厂商',
|
||||||
|
province: '服务地域',
|
||||||
|
addTitle: '新增网元信息',
|
||||||
|
editTitle: '编辑网元信息',
|
||||||
|
delTip: '确认删除网元信息数据项吗?',
|
||||||
|
oam: {
|
||||||
|
title: 'OAM配置',
|
||||||
|
sync: '同步到网元',
|
||||||
|
oamEnable: '服务',
|
||||||
|
oamPort: '端口',
|
||||||
|
snmpEnable: '服务',
|
||||||
|
snmpPort: '端口',
|
||||||
|
kpiEnable: '上报',
|
||||||
|
kpiTimer: '上报周期',
|
||||||
|
kpiTimerPlease: '请输入上报周期(单位秒)',
|
||||||
|
},
|
||||||
|
backConf: {
|
||||||
|
export: '配置导出',
|
||||||
|
import: '配置导入',
|
||||||
|
title: '配置文件导入',
|
||||||
|
importType: '文件来源',
|
||||||
|
server:'服务器文件',
|
||||||
|
local:'本地文件',
|
||||||
|
localUpload:'本地上传',
|
||||||
|
exportTip:'确认要导出网元配置信息到文件?',
|
||||||
|
exportMsg:'导出成功,请到【备份管理】进行下载',
|
||||||
|
filePlease: "请上传文件",
|
||||||
|
fileNamePlease: '请选择服务器文件',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
neHost: {
|
neHost: {
|
||||||
hostType: "主机类型",
|
hostType: "主机类型",
|
||||||
@@ -610,13 +681,13 @@ export default {
|
|||||||
privateKey: "私钥",
|
privateKey: "私钥",
|
||||||
privateKeyPlease: "请正确填写私钥字符内容 ~/.ssh/id_rsa",
|
privateKeyPlease: "请正确填写私钥字符内容 ~/.ssh/id_rsa",
|
||||||
passPhrase: "私钥密码",
|
passPhrase: "私钥密码",
|
||||||
remark: "备注信息",
|
|
||||||
createTime: "创建时间",
|
|
||||||
delTip: "确认要删除主机编号为【{num}】的信息吗?",
|
delTip: "确认要删除主机编号为【{num}】的信息吗?",
|
||||||
addTitle: "新增主机连接",
|
addTitle: "新增主机连接",
|
||||||
editTitle: "编辑主机连接",
|
editTitle: "编辑主机连接",
|
||||||
test: "测试连接",
|
test: "测试连接",
|
||||||
testOk: "测试连接成功",
|
testOk: "测试连接成功",
|
||||||
|
authRSA: "免密授权",
|
||||||
|
authRSATip: "是否要配置免密授权?",
|
||||||
},
|
},
|
||||||
neHostCmd: {
|
neHostCmd: {
|
||||||
cmdType: "命令类型",
|
cmdType: "命令类型",
|
||||||
@@ -625,12 +696,125 @@ export default {
|
|||||||
titlePlease: "请正确填写命令名称",
|
titlePlease: "请正确填写命令名称",
|
||||||
command: "命令",
|
command: "命令",
|
||||||
commandPlease: "请正确输入有效命令字符串",
|
commandPlease: "请正确输入有效命令字符串",
|
||||||
remark: "备注",
|
|
||||||
createTime: "创建时间",
|
|
||||||
delTip: "确认要删除命令编号为【{num}】的信息吗?",
|
delTip: "确认要删除命令编号为【{num}】的信息吗?",
|
||||||
addTitle: "新增主机命令",
|
addTitle: "新增主机命令",
|
||||||
editTitle: "编辑主机命令",
|
editTitle: "编辑主机命令",
|
||||||
},
|
},
|
||||||
|
neSoftware: {
|
||||||
|
uploadTitle: "上传软件",
|
||||||
|
upload: "上传",
|
||||||
|
uploadNotFile: "未上传软件文件",
|
||||||
|
uploadBatch: "上传软件包",
|
||||||
|
uploadBatchMax: "可上传多个软件包,最多同时选择{txt}个。",
|
||||||
|
uploadFileName: "解析文件名称格式如: amf-r2.240x.xx-xxx",
|
||||||
|
name: "文件名",
|
||||||
|
path: "软件文件",
|
||||||
|
pathPlease: "请上传软件包文件",
|
||||||
|
version: "软件版本",
|
||||||
|
versionPlease: "请输入软件版本号",
|
||||||
|
delTip: "确认要删除软件包吗?",
|
||||||
|
downTip: "确认要下载软件包【{txt}】吗?",
|
||||||
|
fileCheckType: '未解析出对应的网元类型',
|
||||||
|
fileCheckVer: '未解析出对应的版本号',
|
||||||
|
fileTypeNotEq: '不是指定网元类型 {txt}',
|
||||||
|
fileTypeExists: '已存在相同类型文件',
|
||||||
|
fileNameExists: '已存在相同名称文件',
|
||||||
|
fileCheckTypeDep: '未解析出对应指定的依赖包类型',
|
||||||
|
dependFile: '软件包依赖',
|
||||||
|
dependFileTip: '文件名解析同上,依据上传顺序安装',
|
||||||
|
},
|
||||||
|
neVersion: {
|
||||||
|
upgrade: "升级到新版本",
|
||||||
|
upgradeTip: "确认要升级到新版本吗?",
|
||||||
|
upgradeTipEmpty: "当前没有可用的新版本",
|
||||||
|
upgradeTipEqual: "当前版本与新版本相同",
|
||||||
|
rollback: '切换到上一个版本',
|
||||||
|
rollbackTip: "确认切换到上一个版本吗?",
|
||||||
|
rollbackTipEmpty: "目前没有可用的上一个版本",
|
||||||
|
rollbackTipEqual: '当前版本与之前版本相同',
|
||||||
|
version: "当前版本",
|
||||||
|
preVersion: "上一个版本",
|
||||||
|
newVersion: "新版本",
|
||||||
|
status: "版本状态",
|
||||||
|
upgradeBatch: "批量更新",
|
||||||
|
upgradeBatchTip: "对勾选的记录进行新版本升级吗?",
|
||||||
|
upgradeNotNewVer: '没有发现新版本',
|
||||||
|
upgradeDone: '更新完成,服务正在重载',
|
||||||
|
upgradeFail: '更新失败,请检查服务终端环境是否可用!',
|
||||||
|
upgradeModal: '网元版本更新',
|
||||||
|
},
|
||||||
|
neLicense: {
|
||||||
|
status: "许可证状态",
|
||||||
|
change: "变更许可证",
|
||||||
|
reload: "刷新信息",
|
||||||
|
reloadTip: "确认要刷新许可证信息吗?",
|
||||||
|
reloadBatch: "批量刷新",
|
||||||
|
reloadBatchTip: "对勾选的记录进行信息刷新吗?",
|
||||||
|
updateTtile: "更新许可证",
|
||||||
|
downCodeTop: "确认要将许可激活码保存到文件吗?",
|
||||||
|
activationRequestCode: "许可激活码",
|
||||||
|
licensePath: "许可证文件",
|
||||||
|
licensePathTip: "请上传许可证文件",
|
||||||
|
upload: '上传',
|
||||||
|
uploadBatch: "上传许可证",
|
||||||
|
uploadChangeFail: "部分网元更新许可证失败,请检查服务终端环境是否可用!",
|
||||||
|
},
|
||||||
|
neConfPara5G: {
|
||||||
|
save: '保存',
|
||||||
|
reload: '刷新',
|
||||||
|
title: '保存信息',
|
||||||
|
sync: '同步到网元',
|
||||||
|
syncNe: '选择网元',
|
||||||
|
syncNeDone: '同步到网元终端完成',
|
||||||
|
saveOk: '保存成功!',
|
||||||
|
},
|
||||||
|
neQuickSetup: {
|
||||||
|
stepPrev: '上一步',
|
||||||
|
stepPrevTip: '确认要放弃当前变更返回上一步吗?',
|
||||||
|
stepNext: '下一步',
|
||||||
|
stepSave: '保存信息',
|
||||||
|
startTitle: '服务终端环境',
|
||||||
|
startDesc: '测试连接网元服务',
|
||||||
|
startStepNext: '确认要下一步进行配置网元信息?',
|
||||||
|
addr: '终端IP',
|
||||||
|
kernelName: '系统',
|
||||||
|
kernelRelease: '内核',
|
||||||
|
machine: '架构',
|
||||||
|
prettyName: '平台',
|
||||||
|
prettyNameTip: '支持 Ubuntu',
|
||||||
|
nodename: '主机名',
|
||||||
|
auth: '权限授予',
|
||||||
|
sudo: '提权',
|
||||||
|
sudoErr: '确保有权限进行软件包安装,请配置授予当前用户允许无密码 sudo 权限。',
|
||||||
|
sshLink: '免密直连',
|
||||||
|
configTitle: "配置网元",
|
||||||
|
configDesc: "填写网元基础信息",
|
||||||
|
configAddTitle: '新增提示',
|
||||||
|
configAddTip: '是否新增为新的网元信息并继续?',
|
||||||
|
configUpdateTitle: '更新提示',
|
||||||
|
configUpdateTip: '是否更新到已存在网元信息并继续?',
|
||||||
|
configStepNext: '确认要下一步进行网元软件安装?',
|
||||||
|
installTitle: "网元安装",
|
||||||
|
installDesc: "安装到服务终端",
|
||||||
|
installConfirmTip: '确认要安装软件包【{name}】吗?',
|
||||||
|
installStepNext: '确认要下一步进行网元授权吗?',
|
||||||
|
installSource: '软件来源',
|
||||||
|
installSourceOption: '已上传',
|
||||||
|
installSourceUpload: '新上传',
|
||||||
|
installSelect: '选择记录',
|
||||||
|
installUpload: '上传文件',
|
||||||
|
installText: '安装',
|
||||||
|
licenseTitle: "授权许可",
|
||||||
|
licenseDesc: "网元服务授权认证",
|
||||||
|
licenseResultTitle: "是否立即授权激活",
|
||||||
|
licenseResultTitleOk: '成功激活',
|
||||||
|
licenseUpload: '许可证',
|
||||||
|
licenseEnd: '结束',
|
||||||
|
licenseEndTip: "确认要结束安装吗?",
|
||||||
|
licenseCheack: '等待网元验证',
|
||||||
|
licenseTip1: '1. 点击【许可证】可获取许可激活码,随后联系网元厂商进行激活',
|
||||||
|
licenseTip2: '2. 点击【结束】将结束安装过程',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
neUser: {
|
neUser: {
|
||||||
auth: {
|
auth: {
|
||||||
@@ -644,7 +828,7 @@ export default {
|
|||||||
import: '导入',
|
import: '导入',
|
||||||
loadDataConfirm: '确认要重新加载数据吗?',
|
loadDataConfirm: '确认要重新加载数据吗?',
|
||||||
loadData: '加载数据',
|
loadData: '加载数据',
|
||||||
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新。加载结束后可点击重置刷新数据列表,请勿重复点击获取更新!!!',
|
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,请稍候!!!',
|
||||||
startIMSI: '起始IMSI',
|
startIMSI: '起始IMSI',
|
||||||
batchAddText: '批量新增',
|
batchAddText: '批量新增',
|
||||||
batchDelText: '批量删除',
|
batchDelText: '批量删除',
|
||||||
@@ -671,7 +855,7 @@ export default {
|
|||||||
import: '导入',
|
import: '导入',
|
||||||
loadDataConfirm: '确认要重新加载数据吗?',
|
loadDataConfirm: '确认要重新加载数据吗?',
|
||||||
loadData: '加载数据',
|
loadData: '加载数据',
|
||||||
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新。加载结束后可点击重置刷新数据列表,请勿重复点击获取更新!!!',
|
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,请稍候!!!',
|
||||||
numAdd: '放号个数',
|
numAdd: '放号个数',
|
||||||
numDel: '删除个数',
|
numDel: '删除个数',
|
||||||
checkDel:'勾选删除',
|
checkDel:'勾选删除',
|
||||||
@@ -709,6 +893,7 @@ export default {
|
|||||||
addTitle: '新增策略控制信息',
|
addTitle: '新增策略控制信息',
|
||||||
updateTitle: '{imsi} 策略控制信息',
|
updateTitle: '{imsi} 策略控制信息',
|
||||||
startIMSI: '起始IMSI',
|
startIMSI: '起始IMSI',
|
||||||
|
batchOper: '批量操作',
|
||||||
batchAddText: '批量新增',
|
batchAddText: '批量新增',
|
||||||
batchDelText: '批量删除',
|
batchDelText: '批量删除',
|
||||||
batchUpdateText: '批量更新',
|
batchUpdateText: '批量更新',
|
||||||
@@ -717,9 +902,19 @@ export default {
|
|||||||
imsiTip1: 'MCC=移动国家号码, 由三位数字组成',
|
imsiTip1: 'MCC=移动国家号码, 由三位数字组成',
|
||||||
imsiTip2: 'MNC=移动网络号,由两位数字组成',
|
imsiTip2: 'MNC=移动网络号,由两位数字组成',
|
||||||
imsiTip3: 'MSIN=移动客户识别码,采用等长10位数字构成',
|
imsiTip3: 'MSIN=移动客户识别码,采用等长10位数字构成',
|
||||||
delSure:'确认删除IMSI编号为: {imsi} 的用户吗?',
|
checkDel:'勾选删除',
|
||||||
|
delSure:'确认删除IMSI编号为: {imsi} 的数据项吗?',
|
||||||
uploadFileOk: '文件上传成功',
|
uploadFileOk: '文件上传成功',
|
||||||
uploadFileErr: '文件上传失败',
|
uploadFileErr: '文件上传失败',
|
||||||
|
pccRuleTip:'PCC策略规则模板(对应参数配置-PCC Rules)',
|
||||||
|
sessRuleTip:'会话策略规则模板(对应参数配置-Session Rules)',
|
||||||
|
qosAudioTip:'语音呼叫QoS(对应参数配置-QoS Template的QoS ID)',
|
||||||
|
qosVideoTip:'视频呼叫QoS(对应参数配置-QoS Template的QoS ID)',
|
||||||
|
hdrTip:'HTTP头增强(对应参数配置-Header Enrich Template)',
|
||||||
|
ueTip:'UE策略模板(样例: uep_001)',
|
||||||
|
sarTip1:'服务区限制',
|
||||||
|
sarTip2:'(对应参数配置-Service Area Restriction)',
|
||||||
|
rfsfTip:'无线频率选择优先级',
|
||||||
},
|
},
|
||||||
base5G: {
|
base5G: {
|
||||||
neType: '网元对象',
|
neType: '网元对象',
|
||||||
@@ -755,7 +950,7 @@ export default {
|
|||||||
viewTask:'查看任务',
|
viewTask:'查看任务',
|
||||||
editTask:'修改任务',
|
editTask:'修改任务',
|
||||||
addTask:'新增任务',
|
addTask:'新增任务',
|
||||||
stopTask:'挂起',
|
stopTask:'停止',
|
||||||
errorTaskInfo: '获取任务信息失败',
|
errorTaskInfo: '获取任务信息失败',
|
||||||
granulOptionPlease:'请选择测量粒度',
|
granulOptionPlease:'请选择测量粒度',
|
||||||
letupSure:'确认激活编号为 【{id}】 的任务?',
|
letupSure:'确认激活编号为 【{id}】 的任务?',
|
||||||
@@ -815,7 +1010,7 @@ export default {
|
|||||||
exportSure:'确认是否导出全部统计数据',
|
exportSure:'确认是否导出全部统计数据',
|
||||||
exportEmpty: "导出数据为空",
|
exportEmpty: "导出数据为空",
|
||||||
showChartSelected: "显示全部",
|
showChartSelected: "显示全部",
|
||||||
realTimeData: "实时5s数据",
|
realTimeData: "实时数据",
|
||||||
},
|
},
|
||||||
customTarget:{
|
customTarget:{
|
||||||
kpiId:'自定义指标项',
|
kpiId:'自定义指标项',
|
||||||
@@ -965,6 +1160,7 @@ export default {
|
|||||||
showSet:'显示过滤设置',
|
showSet:'显示过滤设置',
|
||||||
exportSure:'确认是否导出全部活动告警信息',
|
exportSure:'确认是否导出全部活动告警信息',
|
||||||
viewIdInfo:'查看{alarmId} 记录信息',
|
viewIdInfo:'查看{alarmId} 记录信息',
|
||||||
|
closeModal:'关闭',
|
||||||
},
|
},
|
||||||
historyAlarm:{
|
historyAlarm:{
|
||||||
exportSure:'确认是否导出全部历史告警信息?',
|
exportSure:'确认是否导出全部历史告警信息?',
|
||||||
@@ -976,6 +1172,9 @@ export default {
|
|||||||
save:'保存设置',
|
save:'保存设置',
|
||||||
noChange:'告警前转接口设置无变更',
|
noChange:'告警前转接口设置无变更',
|
||||||
forwardSet:'告警前转接口设置',
|
forwardSet:'告警前转接口设置',
|
||||||
|
},
|
||||||
|
eventAlarm:{
|
||||||
|
exportSure:'确认是否导出全部事件告警信息?',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
logManage:{
|
logManage:{
|
||||||
@@ -1004,8 +1203,9 @@ export default {
|
|||||||
alarmId:'告警唯一标识',
|
alarmId:'告警唯一标识',
|
||||||
alarmSeq:'告警流水号',
|
alarmSeq:'告警流水号',
|
||||||
alarmObj:'告警前转对象',
|
alarmObj:'告警前转对象',
|
||||||
|
alarmInter:'告警前转接口',
|
||||||
alarmTitle:'告警标题',
|
alarmTitle:'告警标题',
|
||||||
alarmInfo:'告警内容',
|
alarmInfo:'操作结果',
|
||||||
eventTime:'告警产生时间',
|
eventTime:'告警产生时间',
|
||||||
logTime:'记录时间'
|
logTime:'记录时间'
|
||||||
},
|
},
|
||||||
@@ -1400,7 +1600,7 @@ export default {
|
|||||||
status: '用户状态',
|
status: '用户状态',
|
||||||
userNameTip:'账号不能以数字开头,可包含大写小写字母,数字,且不少于5位',
|
userNameTip:'账号不能以数字开头,可包含大写小写字母,数字,且不少于5位',
|
||||||
passwdTip:'密码至少包含大小写字母、数字、特殊符号,且不少于6位',
|
passwdTip:'密码至少包含大小写字母、数字、特殊符号,且不少于6位',
|
||||||
nickNameTip:'昵称只能包含字母、数字、中文和下划线,且不少于2位',
|
nickNameTip:'昵称不少于2位',
|
||||||
emailTip:'请输入正确的邮箱地址',
|
emailTip:'请输入正确的邮箱地址',
|
||||||
phoneTip:'请输入正确的手机号码',
|
phoneTip:'请输入正确的手机号码',
|
||||||
resetPwd:'重置密码',
|
resetPwd:'重置密码',
|
||||||
@@ -1423,7 +1623,7 @@ export default {
|
|||||||
userWork:'用户岗位',
|
userWork:'用户岗位',
|
||||||
userWorkPlease: '请选择用户岗位',
|
userWorkPlease: '请选择用户岗位',
|
||||||
userTip:'用户说明',
|
userTip:'用户说明',
|
||||||
loginPwd:'登入密码',
|
loginPwd:'登录密码',
|
||||||
updateSure:'是否更新已经存在的数据',
|
updateSure:'是否更新已经存在的数据',
|
||||||
downloadObj:'下载模板',
|
downloadObj:'下载模板',
|
||||||
importTitle:'用户导入',
|
importTitle:'用户导入',
|
||||||
@@ -1509,6 +1709,9 @@ export default {
|
|||||||
i18nOpen: "显示切换",
|
i18nOpen: "显示切换",
|
||||||
i18nDefault: "默认语言",
|
i18nDefault: "默认语言",
|
||||||
i18nInstruction: '是否显示国际化切换,设置系统默认语言',
|
i18nInstruction: '是否显示国际化切换,设置系统默认语言',
|
||||||
|
reset: "系统重置",
|
||||||
|
resetInstruction: "系统重置将会清除当前系统内所有数据,请谨慎操作!!!",
|
||||||
|
resetTipContent: '确认要清除当前系统内所有数据并坚持继续吗?',
|
||||||
},
|
},
|
||||||
role:{
|
role:{
|
||||||
allScopeOptions:'全部数据权限',
|
allScopeOptions:'全部数据权限',
|
||||||
@@ -1533,10 +1736,10 @@ export default {
|
|||||||
distributeUser:'分配用户',
|
distributeUser:'分配用户',
|
||||||
roleMark:'角色说明',
|
roleMark:'角色说明',
|
||||||
menu:'菜单权限',
|
menu:'菜单权限',
|
||||||
roleKeyTip:"权限标识示例:dba 控制器中使用权限标识,如: @PreAuthorize({ hasRoles: ['dba'] })",
|
roleKeyTip:"权限标识用于控制页面控件或路由接口",
|
||||||
openSwitch:'展开/折叠',
|
openSwitch:'展开/折叠',
|
||||||
selAllSwitch:'全选/全不选',
|
selAllSwitch:'全选/全不选',
|
||||||
relationSwitch:'父子联动',
|
relationSwitch:'节点联动',
|
||||||
normal:'正常',
|
normal:'正常',
|
||||||
stop:'暂停',
|
stop:'暂停',
|
||||||
preScope:'权限范围',
|
preScope:'权限范围',
|
||||||
@@ -1703,6 +1906,65 @@ export default {
|
|||||||
exportOk: "已完成导出",
|
exportOk: "已完成导出",
|
||||||
typeDataErr: "获取字典类型信息失败",
|
typeDataErr: "获取字典类型信息失败",
|
||||||
},
|
},
|
||||||
|
quickStart: {
|
||||||
|
start: '开始设置',
|
||||||
|
skip: '跳过',
|
||||||
|
finish: '完成设置',
|
||||||
|
stepPrev: '上一步',
|
||||||
|
stepNext: '下一步',
|
||||||
|
exit: '退出',
|
||||||
|
save: '保存信息',
|
||||||
|
sysTitle: '系统配置',
|
||||||
|
sysAdmin: '管理员',
|
||||||
|
sysInfo: '系统信息',
|
||||||
|
sysLogo: '系统LOGO',
|
||||||
|
sysLogoTip: '将图片展示到系统LOGO区域查看效果,请使用透明背景,尺寸比例适应区域大小',
|
||||||
|
sysName: '系统名称',
|
||||||
|
sysNameTip: '系统名称限制20个字符长度',
|
||||||
|
sysUploadLogo: '确认要上传系统LOGO文件吗?',
|
||||||
|
sysUploadOk: '文件上传成功,请进行保存信息',
|
||||||
|
sysSave: '保存',
|
||||||
|
sysSaveOk: '信息保存成功!',
|
||||||
|
sysPrevTip: '确认要返回上一个步骤吗?',
|
||||||
|
sysNextNe: '确认要进行网元安装吗?',
|
||||||
|
sysNextDone: '确认要跳过网元安装吗?',
|
||||||
|
stepNeInfoTitle: "网元服务配置",
|
||||||
|
stepNeInfoDesc: "设置网元对应的服务终端",
|
||||||
|
stepNeInfoStepPrev: '确认要退出网元安装步骤吗?',
|
||||||
|
stepNeInfoStepNext: '确认要下一步进行网元配置参数?',
|
||||||
|
stepPara5GTitle: "网元配置参数",
|
||||||
|
stepPara5GDesc: "设置网元全局参数信息",
|
||||||
|
stepPara5GStepPrev: '确认要放弃当前变更返回上一步吗?',
|
||||||
|
stepPara5GStepNext: '确认要下一步进行网元服务安装吗?',
|
||||||
|
stepInstallTitle: "网元服务安装",
|
||||||
|
stepInstallDesc: "将网元服务安装到服务终端",
|
||||||
|
stepInstallStepPrev: '确认要放弃当前变更返回上一步吗?',
|
||||||
|
stepInstallStepNext: '确认要下一步进行网元许可授权吗?',
|
||||||
|
stepInstallText: '选择安装',
|
||||||
|
stepInstallTip: '确认安装选择的网元新版本吗?',
|
||||||
|
stepInstallModal: '网元进行安装',
|
||||||
|
stepInstallNotNewVer: '没有发现新版本',
|
||||||
|
stepInstallDone: '安装完成,服务进入初始化',
|
||||||
|
stepInstallFail: '安装失败,请检查服务终端环境是否可用!',
|
||||||
|
stepLicenseTitle: "网元许可授权",
|
||||||
|
stepLicenseDesc: "获取网元许可激活码进行授权认证",
|
||||||
|
stepLicenseReload: '选择刷新许可证',
|
||||||
|
stepLicenseReloadTip: '确认刷新选择的许可证信息吗?',
|
||||||
|
stepLicenseDownCode: '选择下载网元许可激活码',
|
||||||
|
stepLicenseDownCodeTip: '确认下载选择的网元许可激活码到文本文件吗?',
|
||||||
|
stepLicenseStepPrev: '确认要放弃当前变更返回上一步吗?',
|
||||||
|
stepLicenseStepNext: '确认要结束网元安装步骤吗?',
|
||||||
|
stepLicenseStepNext2: '请下载网元许可授权码文件保存,并联系网元厂商获取授权许可证',
|
||||||
|
stepLicenseEnd: '结束',
|
||||||
|
doneTitle: "完成配置",
|
||||||
|
doneTip: '请进入系统后,根据情况进行更多相关配置',
|
||||||
|
doneNETitle: '已经进行网元安装配置',
|
||||||
|
doneNEDesc: '如有异常网元,可在系统内重新安装授权许可',
|
||||||
|
doneSkipTitle: '未进行网元安装配置',
|
||||||
|
doneSkipDesc: '系统将会默认初始网元信息,可在系统内自行修改或进行安装',
|
||||||
|
donePrevTip: '确认要返回上一个步骤吗?',
|
||||||
|
doneOkTip: '确认完成设置并开始使用吗?',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mmlManage: {
|
mmlManage: {
|
||||||
cmdTitle: "命令导航",
|
cmdTitle: "命令导航",
|
||||||
@@ -1710,14 +1972,14 @@ export default {
|
|||||||
cmdOpTip: "左侧命令导航中选择要操作项!",
|
cmdOpTip: "左侧命令导航中选择要操作项!",
|
||||||
cmdNoTip: "{num} 无可选命令操作",
|
cmdNoTip: "{num} 无可选命令操作",
|
||||||
require: "必填参数:{num}",
|
require: "必填参数:{num}",
|
||||||
requireUn: "{display} 输入值是未知类型",
|
requireUn: "【 {display} 】输入值是未知类型",
|
||||||
requireString: "{display} 参数值不合理",
|
requireString: "【 {display} 】参数值不合理",
|
||||||
requireInt: "{display} 参数值不在合理范围 {filter}",
|
requireInt: "【 {display} 】参数值不在合理范围 {filter}",
|
||||||
requireIpv4: "{display} 不是合法的IPV4地址",
|
requireIpv4: "【 {display} 】不是合法的IPV4地址",
|
||||||
requireIpv6: "{display} 不是合法的IPV6地址",
|
requireIpv6: "【 {display} 】不是合法的IPV6地址",
|
||||||
requireEnum: "{display} 不是合理的枚举值",
|
requireEnum: "【 {display} 】不是合理的枚举值",
|
||||||
requireBool: "{display} 不是合理的布尔类型的值",
|
requireBool: "【 {display} 】不是合理的布尔类型的值",
|
||||||
requireFile: "{display} 不是符合参数文件类型的值",
|
requireFile: "【 {display} 】不是符合参数文件类型的值",
|
||||||
cmdQuickEntry: "命令快速输入",
|
cmdQuickEntry: "命令快速输入",
|
||||||
cmdQuickEntryHelp: "换行(Shift + Enter) 执行发送(Enter)",
|
cmdQuickEntryHelp: "换行(Shift + Enter) 执行发送(Enter)",
|
||||||
cmdParamPanel: "参数面板",
|
cmdParamPanel: "参数面板",
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ function fnChangeLocale(e: any) {
|
|||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<a-tooltip placement="bottom">
|
<a-tooltip placement="bottom" v-if="false">
|
||||||
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
|
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
|
||||||
<a-button type="text" @click="fnClickLock">
|
<a-button type="text" @click="fnClickLock">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@@ -107,7 +107,7 @@ function fnChangeLocale(e: any) {
|
|||||||
|
|
||||||
<a-dropdown
|
<a-dropdown
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
:trigger="['click', 'hover']"
|
trigger="click"
|
||||||
v-if="appStore.i18nOpen && hasPermissions(['system:setting:i18n'])"
|
v-if="appStore.i18nOpen && hasPermissions(['system:setting:i18n'])"
|
||||||
>
|
>
|
||||||
<a-button size="small" type="default">
|
<a-button size="small" type="default">
|
||||||
@@ -123,7 +123,7 @@ function fnChangeLocale(e: any) {
|
|||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
|
|
||||||
<a-dropdown placement="bottomRight" :trigger="['click', 'hover']">
|
<a-dropdown placement="bottomRight" trigger="click">
|
||||||
<div class="user">
|
<div class="user">
|
||||||
<a-avatar
|
<a-avatar
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ function fnTabClose(path: string) {
|
|||||||
/**
|
/**
|
||||||
* 国际化翻译转换
|
* 国际化翻译转换
|
||||||
*/
|
*/
|
||||||
function fnLocale(title: string) {
|
function fnLocale(title: string) {
|
||||||
if (title.indexOf('router.') !== -1) {
|
if (title.indexOf('router.') !== -1) {
|
||||||
title = t(title);
|
title = t(title);
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ watch(router.currentRoute, v => tabsStore.tabOpen(v), { immediate: true });
|
|||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip placement="topRight">
|
<a-tooltip placement="topRight">
|
||||||
<template #title>{{ t('loayouts.tabs.more') }}</template>
|
<template #title>{{ t('loayouts.tabs.more') }}</template>
|
||||||
<a-dropdown :trigger="['click', 'hover']" placement="bottomRight">
|
<a-dropdown trigger="click" placement="bottomRight">
|
||||||
<a-button type="ghost" shape="circle" size="small">
|
<a-button type="ghost" shape="circle" size="small">
|
||||||
<template #icon><DownOutlined /></template>
|
<template #icon><DownOutlined /></template>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|||||||
+42
-27
@@ -87,6 +87,12 @@ const constantRoutes: RouteRecordRaw[] = [
|
|||||||
meta: { title: 'router.helpDoc' },
|
meta: { title: 'router.helpDoc' },
|
||||||
component: () => import('@/views/tool/help/index.vue'),
|
component: () => import('@/views/tool/help/index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/quick-start',
|
||||||
|
name: 'QuickStart',
|
||||||
|
meta: { title: 'router.quickStart' },
|
||||||
|
component: () => import('@/views/system/quick-start/index.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/redirect',
|
path: '/redirect',
|
||||||
name: 'Redirect',
|
name: 'Redirect',
|
||||||
@@ -136,17 +142,30 @@ router.afterEach((to, from, failure) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**无Token可访问页面地址白名单 */
|
/**无Token可访问页面地址白名单 */
|
||||||
const WHITE_LIST: string[] = ['/login', '/auth-redirect', '/help', '/register'];
|
const WHITE_LIST: string[] = [
|
||||||
|
'/login',
|
||||||
|
'/auth-redirect',
|
||||||
|
'/help',
|
||||||
|
'/register',
|
||||||
|
'/quick-start',
|
||||||
|
];
|
||||||
|
|
||||||
/**全局路由-前置守卫 */
|
/**全局路由-前置守卫 */
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
NProgress.start();
|
NProgress.start();
|
||||||
const token = getToken();
|
|
||||||
// 获取系统配置信息
|
// 获取系统配置信息
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
if (!appStore.loginBackground) {
|
if (!appStore.loginBackground) {
|
||||||
appStore.fnSysConf();
|
await appStore.fnSysConf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 需要系统引导跳转
|
||||||
|
if (appStore.bootloader && to.path !== '/quick-start') {
|
||||||
|
next({ name: 'QuickStart' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = getToken();
|
||||||
|
|
||||||
// 没有token
|
// 没有token
|
||||||
if (!token) {
|
if (!token) {
|
||||||
@@ -168,31 +187,27 @@ router.beforeEach((to, from, next) => {
|
|||||||
// 判断当前用户是否有角色信息
|
// 判断当前用户是否有角色信息
|
||||||
const user = useUserStore();
|
const user = useUserStore();
|
||||||
if (user.roles && user.roles.length === 0) {
|
if (user.roles && user.roles.length === 0) {
|
||||||
// 获取用户信息
|
try {
|
||||||
user
|
// 获取用户信息
|
||||||
.fnGetInfo()
|
await user.fnGetInfo();
|
||||||
.then(() => {
|
// 获取路由信息
|
||||||
return useRouterStore().generateRoutes();
|
const accessRoutes = await useRouterStore().generateRoutes();
|
||||||
})
|
// 根据后台配置生成可访问的路由表
|
||||||
.then(accessRoutes => {
|
if (accessRoutes && accessRoutes.length !== 0) {
|
||||||
// 根据后台配置生成可访问的路由表
|
for (const route of accessRoutes) {
|
||||||
if (accessRoutes && accessRoutes.length !== 0) {
|
// 动态添加可访问路由表,http开头会异常
|
||||||
for (const route of accessRoutes) {
|
if (!validHttp(route.path)) {
|
||||||
// 动态添加可访问路由表,http开头会异常
|
router.addRoute(route);
|
||||||
if (!validHttp(route.path)) {
|
|
||||||
router.addRoute(route);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 刷新替换原先路由,确保addRoutes已完成
|
}
|
||||||
next({ ...to, replace: true });
|
// 刷新替换原先路由,确保addRoutes已完成
|
||||||
})
|
next({ ...to, replace: true });
|
||||||
.catch(e => {
|
} catch (error: any) {
|
||||||
console.error(`[${to.path}]: ${e.message}`);
|
console.error(`[${to.path}]: ${error.message}`);
|
||||||
user.fnLogOut().finally(() => {
|
await user.fnLogOut();
|
||||||
next({ name: 'Login' });
|
next({ name: 'Login' });
|
||||||
});
|
}
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { getSysConf } from '@/api';
|
import { getSysConf } from '@/api';
|
||||||
import { CACHE_LOCAL_I18N } from '@/constants/cache-keys-constants';
|
import { CACHE_LOCAL_I18N } from '@/constants/cache-keys-constants';
|
||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { removeToken } from '@/plugins/auth-token';
|
||||||
import { parseUrlPath } from '@/plugins/file-static-url';
|
import { parseUrlPath } from '@/plugins/file-static-url';
|
||||||
import { localGet, localSet } from '@/utils/cache-local-utils';
|
import { localGet, localSet } from '@/utils/cache-local-utils';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
@@ -17,6 +18,8 @@ type AppStore = {
|
|||||||
/**服务版本 */
|
/**服务版本 */
|
||||||
version: string;
|
version: string;
|
||||||
buildTime: string;
|
buildTime: string;
|
||||||
|
/**系统引导使用 */
|
||||||
|
bootloader: boolean;
|
||||||
// 序列号
|
// 序列号
|
||||||
serialNum: string;
|
serialNum: string;
|
||||||
/**应用版权声明 */
|
/**应用版权声明 */
|
||||||
@@ -48,6 +51,7 @@ const useAppStore = defineStore('app', {
|
|||||||
|
|
||||||
version: `-`,
|
version: `-`,
|
||||||
buildTime: `-`,
|
buildTime: `-`,
|
||||||
|
bootloader: false,
|
||||||
serialNum: `-`,
|
serialNum: `-`,
|
||||||
copyright: `Copyright ©2023 For ${import.meta.env.VITE_APP_NAME}`,
|
copyright: `Copyright ©2023 For ${import.meta.env.VITE_APP_NAME}`,
|
||||||
logoType: 'icon',
|
logoType: 'icon',
|
||||||
@@ -57,7 +61,7 @@ const useAppStore = defineStore('app', {
|
|||||||
loginBackground: '',
|
loginBackground: '',
|
||||||
helpDoc: '',
|
helpDoc: '',
|
||||||
officialUrl: '',
|
officialUrl: '',
|
||||||
i18nOpen: true,
|
i18nOpen: false,
|
||||||
i18nDefault: 'en_US',
|
i18nDefault: 'en_US',
|
||||||
}),
|
}),
|
||||||
getters: {},
|
getters: {},
|
||||||
@@ -70,16 +74,17 @@ const useAppStore = defineStore('app', {
|
|||||||
document.title = this.appName;
|
document.title = this.appName;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**设置版权声明 */
|
|
||||||
setCopyright(text: string) {
|
|
||||||
this.copyright = text;
|
|
||||||
},
|
|
||||||
// 获取系统配置信息
|
// 获取系统配置信息
|
||||||
async fnSysConf() {
|
async fnSysConf() {
|
||||||
const res = await getSysConf();
|
const res = await getSysConf();
|
||||||
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
||||||
this.version = res.data.version;
|
this.version = res.data.version;
|
||||||
this.buildTime = res.data.buildTime;
|
this.buildTime = res.data.buildTime;
|
||||||
|
this.bootloader = res.data.bootloader === 'true';
|
||||||
|
// 引导时
|
||||||
|
if (this.bootloader) {
|
||||||
|
removeToken();
|
||||||
|
}
|
||||||
this.serialNum = res.data.serialNum;
|
this.serialNum = res.data.serialNum;
|
||||||
this.appName = res.data.title;
|
this.appName = res.data.title;
|
||||||
this.copyright = res.data.copyright;
|
this.copyright = res.data.copyright;
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ import { defineStore } from 'pinia';
|
|||||||
/**锁屏信息类型 */
|
/**锁屏信息类型 */
|
||||||
type Locked = {
|
type Locked = {
|
||||||
/**锁屏类型 */
|
/**锁屏类型 */
|
||||||
type: 'none' | 'lock' | 'reload' | string;
|
type: 'none' | 'lock' | 'reload' | 'reset';
|
||||||
/**lock 超时锁屏时间,秒*/
|
/**lock 超时锁屏时间,秒*/
|
||||||
lockTimeout: number;
|
lockTimeout: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useLockedStore = defineStore('locked', {
|
const useLockedStore = defineStore('locked', {
|
||||||
state: (): Locked => ({
|
state: (): Locked => ({
|
||||||
type: localGet(CACHE_LOCAL_LOCK) || 'none',
|
type: (localGet(CACHE_LOCAL_LOCK) || 'none') as Locked['type'],
|
||||||
lockTimeout: 0,
|
lockTimeout: 0,
|
||||||
}),
|
}),
|
||||||
getters: {},
|
getters: {},
|
||||||
@@ -24,8 +24,16 @@ const useLockedStore = defineStore('locked', {
|
|||||||
try {
|
try {
|
||||||
const res = await getSysConf();
|
const res = await getSysConf();
|
||||||
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
||||||
this.fnLock('none');
|
// 延迟5秒
|
||||||
window.location.reload();
|
setTimeout(() => {
|
||||||
|
this.fnLock('none');
|
||||||
|
window.location.reload();
|
||||||
|
}, 2_000);
|
||||||
|
} else {
|
||||||
|
// 延迟5秒
|
||||||
|
setTimeout(() => {
|
||||||
|
this.relaodWait();
|
||||||
|
}, 5_000);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 延迟5秒
|
// 延迟5秒
|
||||||
@@ -35,7 +43,7 @@ const useLockedStore = defineStore('locked', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 设置锁定
|
// 设置锁定
|
||||||
async fnLock(type: 'none' | 'lock' | 'reload' | string) {
|
async fnLock(type: Locked['type']) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
localSet(CACHE_LOCAL_LOCK, type);
|
localSet(CACHE_LOCAL_LOCK, type);
|
||||||
if (type === 'reload') {
|
if (type === 'reload') {
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import { parseUrlPath } from '@/plugins/file-static-url';
|
|||||||
|
|
||||||
/**用户信息类型 */
|
/**用户信息类型 */
|
||||||
type UserInfo = {
|
type UserInfo = {
|
||||||
/**授权凭证 */
|
|
||||||
token: string;
|
|
||||||
/**登录账号 */
|
/**登录账号 */
|
||||||
userName: string;
|
userName: string;
|
||||||
/**用户角色 字符串数组 */
|
/**用户角色 字符串数组 */
|
||||||
@@ -27,13 +25,12 @@ type UserInfo = {
|
|||||||
email: string;
|
email: string;
|
||||||
/**用户性别 */
|
/**用户性别 */
|
||||||
sex: string | undefined;
|
sex: string | undefined;
|
||||||
/**个人化设置 */
|
/**其他信息 */
|
||||||
profile: Record<string, any>;
|
profile: Record<string, any>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useUserStore = defineStore('user', {
|
const useUserStore = defineStore('user', {
|
||||||
state: (): UserInfo => ({
|
state: (): UserInfo => ({
|
||||||
token: getToken(),
|
|
||||||
userName: '',
|
userName: '',
|
||||||
roles: [],
|
roles: [],
|
||||||
permissions: [],
|
permissions: [],
|
||||||
@@ -104,7 +101,6 @@ const useUserStore = defineStore('user', {
|
|||||||
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
||||||
const token = res.data[TOKEN_RESPONSE_FIELD];
|
const token = res.data[TOKEN_RESPONSE_FIELD];
|
||||||
setToken(token);
|
setToken(token);
|
||||||
this.token = token;
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
@@ -154,7 +150,6 @@ const useUserStore = defineStore('user', {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
this.token = '';
|
|
||||||
this.roles = [];
|
this.roles = [];
|
||||||
this.permissions = [];
|
this.permissions = [];
|
||||||
removeToken();
|
removeToken();
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export const regExpPasswd =
|
|||||||
/**
|
/**
|
||||||
* 有效手机号格式
|
* 有效手机号格式
|
||||||
*/
|
*/
|
||||||
export const regExpMobile = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/;
|
export const regExpMobile = /^.{3,}$/; // /^1[3|4|5|6|7|8|9][0-9]\d{8}$/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 有效邮箱格式
|
* 有效邮箱格式
|
||||||
@@ -47,7 +47,7 @@ export const regExpEmail =
|
|||||||
*
|
*
|
||||||
* 用户昵称只能包含字母、数字、中文和下划线,且不少于2位
|
* 用户昵称只能包含字母、数字、中文和下划线,且不少于2位
|
||||||
*/
|
*/
|
||||||
export const regExpNick = /^[\w\u4e00-\u9fa5-]{2,}$/;
|
export const regExpNick = /^.{2,}$/; // /^[\w\u4e00-\u9fa5-]{2,}$/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否为http(s)://开头
|
* 是否为http(s)://开头
|
||||||
@@ -84,13 +84,14 @@ export function validURL(str: string) {
|
|||||||
// http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString
|
// http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString
|
||||||
strTemp = 'http://' + str;
|
strTemp = 'http://' + str;
|
||||||
}
|
}
|
||||||
debugger;
|
|
||||||
|
let u = { host: '', pathname: '' };
|
||||||
try {
|
try {
|
||||||
new URL(strTemp);
|
new URL(strTemp);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const u = new URL(strTemp);
|
|
||||||
if (u.host.startsWith('.')) {
|
if (u.host.startsWith('.')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,12 +166,12 @@ onMounted(() => {
|
|||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<a-input
|
<IntlTelInput
|
||||||
v-model:value="stateForm.form.phonenumber"
|
v-model:value="stateForm.form.phonenumber"
|
||||||
allow-clear
|
allow-clear
|
||||||
:maxlength="11"
|
:maxlength="16"
|
||||||
:placeholder="t('views.account.settings.phonenumberPleace')"
|
:placeholder="t('views.account.settings.phonenumberPleace')"
|
||||||
></a-input>
|
></IntlTelInput>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item
|
<a-form-item
|
||||||
|
|||||||
@@ -227,7 +227,11 @@ function fnGetList(pageNum?: number) {
|
|||||||
}
|
}
|
||||||
tablePagination.total = res.total;
|
tablePagination.total = res.total;
|
||||||
tableState.data = res.rows;
|
tableState.data = res.rows;
|
||||||
if (tablePagination.total <=(queryParams.pageNum - 1) * tablePagination.pageSize &&queryParams.pageNum !== 1) {
|
if (
|
||||||
|
tablePagination.total <=
|
||||||
|
(queryParams.pageNum - 1) * tablePagination.pageSize &&
|
||||||
|
queryParams.pageNum !== 1
|
||||||
|
) {
|
||||||
tableState.loading = false;
|
tableState.loading = false;
|
||||||
fnGetList(queryParams.pageNum - 1);
|
fnGetList(queryParams.pageNum - 1);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,157 @@
|
|||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { regExpIPv4, regExpIPv6, validURL } from '@/utils/regular-utils';
|
||||||
|
|
||||||
|
export default function useOptions() {
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
/**规则校验 */
|
||||||
|
function ruleVerification(row: Record<string, any>): (string | boolean)[] {
|
||||||
|
let result = [true, ''];
|
||||||
|
const type = row.type;
|
||||||
|
const value = row.value;
|
||||||
|
const filter = row.filter;
|
||||||
|
const display = row.display;
|
||||||
|
|
||||||
|
// 子嵌套的不检查
|
||||||
|
if (row.array) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可选的同时没有值不检查
|
||||||
|
if (row.optional === 'true' && !value) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
switch (type) {
|
||||||
|
case 'int':
|
||||||
|
if (filter && filter.indexOf('~') !== -1) {
|
||||||
|
const filterArr = filter.split('~');
|
||||||
|
const minInt = parseInt(filterArr[0]);
|
||||||
|
const maxInt = parseInt(filterArr[1]);
|
||||||
|
const valueInt = parseInt(value);
|
||||||
|
if (valueInt < minInt || valueInt > maxInt) {
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
t('views.configManage.configParamForm.requireInt', {
|
||||||
|
display,
|
||||||
|
filter,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ipv4':
|
||||||
|
if (!regExpIPv4.test(value)) {
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
t('views.configManage.configParamForm.requireIpv4', { display }),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ipv6':
|
||||||
|
if (!regExpIPv6.test(value)) {
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
t('views.configManage.configParamForm.requireIpv6', { display }),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'enum':
|
||||||
|
if (filter && filter.indexOf('{') === 1) {
|
||||||
|
let filterJson: Record<string, any> = {};
|
||||||
|
try {
|
||||||
|
filterJson = JSON.parse(filter); //string---json
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Object.keys(filterJson).includes(`${value}`)) {
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
t('views.configManage.configParamForm.requireEnum', { display }),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'bool':
|
||||||
|
if (filter && filter.indexOf('{') === 1) {
|
||||||
|
let filterJson: Record<string, any> = {};
|
||||||
|
try {
|
||||||
|
filterJson = JSON.parse(filter); //string---json
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Object.values(filterJson).includes(`${value}`)) {
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
t('views.configManage.configParamForm.requireBool', { display }),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'string':
|
||||||
|
// 字符串长度判断
|
||||||
|
if (filter && filter.indexOf('~') !== -1) {
|
||||||
|
try {
|
||||||
|
const filterArr = filter.split('~');
|
||||||
|
let rule = new RegExp(
|
||||||
|
'^\\S{' + filterArr[0] + ',' + filterArr[1] + '}$'
|
||||||
|
);
|
||||||
|
if (!rule.test(value)) {
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
t('views.configManage.configParamForm.requireString', {
|
||||||
|
display,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 字符串http判断
|
||||||
|
if (value.startsWith('http')) {
|
||||||
|
try {
|
||||||
|
if (!validURL(value)) {
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
t('views.configManage.configParamForm.requireString', {
|
||||||
|
display,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'regex':
|
||||||
|
if (filter) {
|
||||||
|
try {
|
||||||
|
let regex = new RegExp(filter);
|
||||||
|
if (!regex.test(value)) {
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
t('views.configManage.configParamForm.requireString', {
|
||||||
|
display,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
t('views.configManage.configParamForm.requireUn', { display }),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ruleVerification };
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { getParamConfigInfo } from '@/api/configManage/configParam';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
export default function useSMFOptions() {
|
||||||
|
/**upfId可选择 */
|
||||||
|
const optionsUPFIds = ref<{ value: string; label: string }[]>([]);
|
||||||
|
|
||||||
|
/**初始加载upfId */
|
||||||
|
function initUPFIds() {
|
||||||
|
getParamConfigInfo('smf', 'upfConfig', '001').then(res => {
|
||||||
|
optionsUPFIds.value = [];
|
||||||
|
for (const s of res.data) {
|
||||||
|
optionsUPFIds.value.push({
|
||||||
|
value: s.id,
|
||||||
|
label: s.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { initUPFIds, optionsUPFIds };
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref, onMounted, watch, toRaw, nextTick } from 'vue';
|
import { reactive, ref, onMounted, toRaw, nextTick, watch } from 'vue';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import { Modal, message } from 'ant-design-vue/lib';
|
import { Modal, message } from 'ant-design-vue/lib';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
@@ -13,11 +13,14 @@ import {
|
|||||||
addParamConfigInfo,
|
addParamConfigInfo,
|
||||||
} from '@/api/configManage/configParam';
|
} from '@/api/configManage/configParam';
|
||||||
import useNeInfoStore from '@/store/modules/neinfo';
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
import { regExpIPv4, regExpIPv6, validURL } from '@/utils/regular-utils';
|
import useOptions from './hooks/useOptions';
|
||||||
|
import useSMFOptions from './hooks/useSMFOptions';
|
||||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||||
import { DataNode } from 'ant-design-vue/lib/tree';
|
import { DataNode } from 'ant-design-vue/lib/tree';
|
||||||
const neInfoStore = useNeInfoStore();
|
const neInfoStore = useNeInfoStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { ruleVerification } = useOptions();
|
||||||
|
const { initUPFIds, optionsUPFIds } = useSMFOptions();
|
||||||
|
|
||||||
/**网元参数 */
|
/**网元参数 */
|
||||||
let neCascaderOptions = ref<Record<string, any>[]>([]);
|
let neCascaderOptions = ref<Record<string, any>[]>([]);
|
||||||
@@ -25,6 +28,14 @@ let neCascaderOptions = ref<Record<string, any>[]>([]);
|
|||||||
/**网元类型选择 type,id */
|
/**网元类型选择 type,id */
|
||||||
let neTypeSelect = ref<string[]>(['', '']);
|
let neTypeSelect = ref<string[]>(['', '']);
|
||||||
|
|
||||||
|
/**左侧导航是否可收起 */
|
||||||
|
let collapsible = ref<boolean>(true);
|
||||||
|
|
||||||
|
/**改变收起状态 */
|
||||||
|
function changeCollapsible() {
|
||||||
|
collapsible.value = !collapsible.value;
|
||||||
|
}
|
||||||
|
|
||||||
/**对象信息状态类型 */
|
/**对象信息状态类型 */
|
||||||
type TreeStateType = {
|
type TreeStateType = {
|
||||||
/**网元 loading */
|
/**网元 loading */
|
||||||
@@ -43,7 +54,7 @@ let treeState: TreeStateType = reactive({
|
|||||||
selectNode: {
|
selectNode: {
|
||||||
topDisplay: '' as string,
|
topDisplay: '' as string,
|
||||||
topTag: '' as string,
|
topTag: '' as string,
|
||||||
method: '' as string,
|
method: [] as string[],
|
||||||
//
|
//
|
||||||
title: '' as string,
|
title: '' as string,
|
||||||
key: '' as string,
|
key: '' as string,
|
||||||
@@ -57,7 +68,11 @@ function fnSelectConfigNode(_: any, info: any) {
|
|||||||
const { title, key, method } = info.node;
|
const { title, key, method } = info.node;
|
||||||
treeState.selectNode.topDisplay = title;
|
treeState.selectNode.topDisplay = title;
|
||||||
treeState.selectNode.topTag = key;
|
treeState.selectNode.topTag = key;
|
||||||
treeState.selectNode.method = method;
|
if (method) {
|
||||||
|
treeState.selectNode.method = method.split(',');
|
||||||
|
} else {
|
||||||
|
treeState.selectNode.method = ['post', 'put', 'delete'];
|
||||||
|
}
|
||||||
treeState.selectNode.title = title;
|
treeState.selectNode.title = title;
|
||||||
treeState.selectNode.key = key;
|
treeState.selectNode.key = key;
|
||||||
fnActiveConfigNode(key);
|
fnActiveConfigNode(key);
|
||||||
@@ -329,14 +344,6 @@ let arrayState: ArrayStateType = reactive({
|
|||||||
dataRule: {},
|
dataRule: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**监听表格字段列排序变化关闭展开 */
|
|
||||||
watch(
|
|
||||||
() => arrayState.columnsDnd,
|
|
||||||
() => {
|
|
||||||
arrayEditClose();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**多列表编辑 */
|
/**多列表编辑 */
|
||||||
function arrayEdit(rowIndex: Record<string, any>) {
|
function arrayEdit(rowIndex: Record<string, any>) {
|
||||||
const item = arrayState.data.find((s: any) => s.key === rowIndex.value);
|
const item = arrayState.data.find((s: any) => s.key === rowIndex.value);
|
||||||
@@ -941,155 +948,6 @@ function arrayAddInit(data: any[], dataRule: any) {
|
|||||||
return ruleFrom;
|
return ruleFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**规则校验 */
|
|
||||||
function ruleVerification(row: Record<string, any>): (string | boolean)[] {
|
|
||||||
let result = [true, ''];
|
|
||||||
const type = row.type;
|
|
||||||
const value = row.value;
|
|
||||||
const filter = row.filter;
|
|
||||||
const display = row.display;
|
|
||||||
|
|
||||||
// 子嵌套的不检查
|
|
||||||
if (row.array) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 可选的同时没有值不检查
|
|
||||||
if (row.optional === 'true' && !value) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
switch (type) {
|
|
||||||
case 'int':
|
|
||||||
if (filter && filter.indexOf('~') !== -1) {
|
|
||||||
const filterArr = filter.split('~');
|
|
||||||
const minInt = parseInt(filterArr[0]);
|
|
||||||
const maxInt = parseInt(filterArr[1]);
|
|
||||||
const valueInt = parseInt(value);
|
|
||||||
if (valueInt < minInt || valueInt > maxInt) {
|
|
||||||
return [
|
|
||||||
false,
|
|
||||||
t('views.configManage.configParamForm.requireInt', {
|
|
||||||
display,
|
|
||||||
filter,
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'ipv4':
|
|
||||||
if (!regExpIPv4.test(value)) {
|
|
||||||
return [
|
|
||||||
false,
|
|
||||||
t('views.configManage.configParamForm.requireIpv4', { display }),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'ipv6':
|
|
||||||
if (!regExpIPv6.test(value)) {
|
|
||||||
return [
|
|
||||||
false,
|
|
||||||
t('views.configManage.configParamForm.requireIpv6', { display }),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'enum':
|
|
||||||
if (filter && filter.indexOf('{') === 1) {
|
|
||||||
let filterJson: Record<string, any> = {};
|
|
||||||
try {
|
|
||||||
filterJson = JSON.parse(filter); //string---json
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Object.keys(filterJson).includes(`${value}`)) {
|
|
||||||
return [
|
|
||||||
false,
|
|
||||||
t('views.configManage.configParamForm.requireEnum', { display }),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'bool':
|
|
||||||
if (filter && filter.indexOf('{') === 1) {
|
|
||||||
let filterJson: Record<string, any> = {};
|
|
||||||
try {
|
|
||||||
filterJson = JSON.parse(filter); //string---json
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Object.values(filterJson).includes(`${value}`)) {
|
|
||||||
return [
|
|
||||||
false,
|
|
||||||
t('views.configManage.configParamForm.requireBool', { display }),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'string':
|
|
||||||
// 字符串长度判断
|
|
||||||
if (filter && filter.indexOf('~') !== -1) {
|
|
||||||
try {
|
|
||||||
const filterArr = filter.split('~');
|
|
||||||
let rule = new RegExp(
|
|
||||||
'^\\S{' + filterArr[0] + ',' + filterArr[1] + '}$'
|
|
||||||
);
|
|
||||||
if (!rule.test(value)) {
|
|
||||||
return [
|
|
||||||
false,
|
|
||||||
t('views.configManage.configParamForm.requireString', {
|
|
||||||
display,
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 字符串http判断
|
|
||||||
if (value.startsWith('http')) {
|
|
||||||
try {
|
|
||||||
if (!validURL(value)) {
|
|
||||||
return [
|
|
||||||
false,
|
|
||||||
t('views.configManage.configParamForm.requireString', {
|
|
||||||
display,
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'regex':
|
|
||||||
if (filter) {
|
|
||||||
try {
|
|
||||||
let regex = new RegExp(filter);
|
|
||||||
if (!regex.test(value)) {
|
|
||||||
return [
|
|
||||||
false,
|
|
||||||
t('views.configManage.configParamForm.requireString', {
|
|
||||||
display,
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return [
|
|
||||||
false,
|
|
||||||
t('views.configManage.configParamForm.requireUn', { display }),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**对话框对象信息状态类型 */
|
/**对话框对象信息状态类型 */
|
||||||
type ModalStateType = {
|
type ModalStateType = {
|
||||||
/**添加框是否显示 */
|
/**添加框是否显示 */
|
||||||
@@ -1151,6 +1009,25 @@ function fnModalCancel() {
|
|||||||
modalState.data = [];
|
modalState.data = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听表格字段列排序变化关闭展开
|
||||||
|
watch(
|
||||||
|
() => arrayState.columnsDnd,
|
||||||
|
() => {
|
||||||
|
arrayEditClose();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听新增编辑弹窗
|
||||||
|
watch(
|
||||||
|
() => modalState.visible,
|
||||||
|
val => {
|
||||||
|
// SMF需要选择配置的UPF id
|
||||||
|
if (val && neTypeSelect.value[0] === 'SMF') {
|
||||||
|
initUPFIds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 获取网元网元列表
|
// 获取网元网元列表
|
||||||
neInfoStore.fnNelist().then(res => {
|
neInfoStore.fnNelist().then(res => {
|
||||||
@@ -1193,7 +1070,13 @@ onMounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="6" :md="6" :xs="24" style="margin-bottom: 24px">
|
<a-col
|
||||||
|
:lg="6"
|
||||||
|
:md="6"
|
||||||
|
:xs="24"
|
||||||
|
style="margin-bottom: 24px"
|
||||||
|
v-show="collapsible"
|
||||||
|
>
|
||||||
<!-- 网元类型 -->
|
<!-- 网元类型 -->
|
||||||
<a-card
|
<a-card
|
||||||
size="small"
|
size="small"
|
||||||
@@ -1221,7 +1104,7 @@ onMounted(() => {
|
|||||||
</a-form>
|
</a-form>
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="18" :md="18" :xs="24">
|
<a-col :lg="collapsible ? 18 : 24" :md="collapsible ? 18 : 24" :xs="24">
|
||||||
<a-card
|
<a-card
|
||||||
size="small"
|
size="small"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
@@ -1229,6 +1112,13 @@ onMounted(() => {
|
|||||||
:loading="treeState.selectLoading"
|
:loading="treeState.selectLoading"
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
|
<a-button type="text" @click.prevent="changeCollapsible()">
|
||||||
|
<template #icon>
|
||||||
|
<MenuFoldOutlined v-show="collapsible" />
|
||||||
|
<MenuUnfoldOutlined v-show="!collapsible" />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
|
||||||
<a-typography-text strong v-if="treeState.selectNode.topDisplay">
|
<a-typography-text strong v-if="treeState.selectNode.topDisplay">
|
||||||
{{ treeState.selectNode.topDisplay }}
|
{{ treeState.selectNode.topDisplay }}
|
||||||
</a-typography-text>
|
</a-typography-text>
|
||||||
@@ -1349,7 +1239,9 @@ onMounted(() => {
|
|||||||
<EditOutlined
|
<EditOutlined
|
||||||
class="editable-cell__icon"
|
class="editable-cell__icon"
|
||||||
@click="listEdit(record)"
|
@click="listEdit(record)"
|
||||||
v-if="!['read-only', 'ro'].includes(record.access)"
|
v-if="
|
||||||
|
!['read-only', 'read', 'ro'].includes(record.access)
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1363,7 +1255,7 @@ onMounted(() => {
|
|||||||
<a-table
|
<a-table
|
||||||
class="table"
|
class="table"
|
||||||
row-key="index"
|
row-key="index"
|
||||||
:columns="treeState.selectNode.method === 'get' ? arrayState.columnsDnd.filter((s:any)=>s.key !== 'index') : arrayState.columnsDnd"
|
:columns="treeState.selectNode.method.includes('get') ? arrayState.columnsDnd.filter((s:any)=>s.key !== 'index') : arrayState.columnsDnd"
|
||||||
:data-source="arrayState.columnsData"
|
:data-source="arrayState.columnsData"
|
||||||
:size="arrayState.size"
|
:size="arrayState.size"
|
||||||
:pagination="tablePagination"
|
:pagination="tablePagination"
|
||||||
@@ -1380,7 +1272,7 @@ onMounted(() => {
|
|||||||
type="primary"
|
type="primary"
|
||||||
@click.prevent="arrayAdd()"
|
@click.prevent="arrayAdd()"
|
||||||
size="small"
|
size="small"
|
||||||
v-if="treeState.selectNode.method !== 'get'"
|
v-if="treeState.selectNode.method.includes('post')"
|
||||||
>
|
>
|
||||||
<template #icon> <PlusOutlined /> </template>
|
<template #icon> <PlusOutlined /> </template>
|
||||||
{{ t('common.addText') }}
|
{{ t('common.addText') }}
|
||||||
@@ -1388,7 +1280,7 @@ onMounted(() => {
|
|||||||
<TableColumnsDnd
|
<TableColumnsDnd
|
||||||
type="ghost"
|
type="ghost"
|
||||||
:cache-id="treeState.selectNode.key"
|
:cache-id="treeState.selectNode.key"
|
||||||
:columns="treeState.selectNode.method === 'get' ? [...arrayState.columns.filter((s:any)=>s.key !== 'index')] : arrayState.columns"
|
:columns="treeState.selectNode.method.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>
|
||||||
</a-space>
|
</a-space>
|
||||||
@@ -1398,13 +1290,17 @@ onMounted(() => {
|
|||||||
<template #bodyCell="{ column, text, record }">
|
<template #bodyCell="{ column, text, record }">
|
||||||
<template v-if="column?.key === 'index'">
|
<template v-if="column?.key === 'index'">
|
||||||
<a-space :size="16" align="center">
|
<a-space :size="16" align="center">
|
||||||
<a-tooltip>
|
<a-tooltip
|
||||||
|
v-if="treeState.selectNode.method.includes('put')"
|
||||||
|
>
|
||||||
<template #title>{{ t('common.editText') }}</template>
|
<template #title>{{ t('common.editText') }}</template>
|
||||||
<a-button type="link" @click.prevent="arrayEdit(text)">
|
<a-button type="link" @click.prevent="arrayEdit(text)">
|
||||||
<template #icon><FormOutlined /></template>
|
<template #icon><FormOutlined /></template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
<a-tooltip
|
||||||
|
v-if="treeState.selectNode.method.includes('delete')"
|
||||||
|
>
|
||||||
<template #title>{{ t('common.deleteText') }}</template>
|
<template #title>{{ t('common.deleteText') }}</template>
|
||||||
<a-button type="link" @click.prevent="arrayDelete(text)">
|
<a-button type="link" @click.prevent="arrayDelete(text)">
|
||||||
<template #icon><DeleteOutlined /></template>
|
<template #icon><DeleteOutlined /></template>
|
||||||
@@ -1509,9 +1405,9 @@ onMounted(() => {
|
|||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{
|
<template #title>
|
||||||
t('common.deleteText')
|
{{ t('common.deleteText') }}
|
||||||
}}</template>
|
</template>
|
||||||
<a-button
|
<a-button
|
||||||
type="link"
|
type="link"
|
||||||
@click.prevent="arrayChildDelete(text)"
|
@click.prevent="arrayChildDelete(text)"
|
||||||
@@ -1598,10 +1494,24 @@ onMounted(() => {
|
|||||||
modalState.from[item.name] !== undefined
|
modalState.from[item.name] !== undefined
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<a-input-number
|
<!-- 特殊SMF-upfid选择 -->
|
||||||
v-if="item['type'] === 'int'"
|
<a-select
|
||||||
|
v-if="
|
||||||
|
neTypeSelect[0] === 'SMF' &&
|
||||||
|
modalState.from[item.name]['name'] === 'upfId'
|
||||||
|
"
|
||||||
v-model:value="modalState.from[item.name]['value']"
|
v-model:value="modalState.from[item.name]['value']"
|
||||||
:disabled="['read-only', 'ro'].includes(item.access)"
|
:options="optionsUPFIds"
|
||||||
|
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||||
|
:allow-clear="true"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
<!-- 常规 -->
|
||||||
|
<a-input-number
|
||||||
|
v-else-if="item['type'] === 'int'"
|
||||||
|
v-model:value="modalState.from[item.name]['value']"
|
||||||
|
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
></a-input-number>
|
></a-input-number>
|
||||||
<a-switch
|
<a-switch
|
||||||
@@ -1609,12 +1519,12 @@ onMounted(() => {
|
|||||||
v-model:checked="modalState.from[item.name]['value']"
|
v-model:checked="modalState.from[item.name]['value']"
|
||||||
:checked-children="t('common.switch.open')"
|
:checked-children="t('common.switch.open')"
|
||||||
:un-checked-children="t('common.switch.shut')"
|
:un-checked-children="t('common.switch.shut')"
|
||||||
:disabled="['read-only', 'ro'].includes(item.access)"
|
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||||
></a-switch>
|
></a-switch>
|
||||||
<a-select
|
<a-select
|
||||||
v-else-if="item['type'] === 'enum'"
|
v-else-if="item['type'] === 'enum'"
|
||||||
v-model:value="modalState.from[item.name]['value']"
|
v-model:value="modalState.from[item.name]['value']"
|
||||||
:disabled="['read-only', 'ro'].includes(item.access)"
|
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||||
:allow-clear="true"
|
:allow-clear="true"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
@@ -1629,7 +1539,7 @@ onMounted(() => {
|
|||||||
<a-input
|
<a-input
|
||||||
v-else
|
v-else
|
||||||
v-model:value="modalState.from[item.name]['value']"
|
v-model:value="modalState.from[item.name]['value']"
|
||||||
:disabled="['read-only', 'ro'].includes(item.access)"
|
:disabled="['read-only', 'read', 'ro'].includes(item.access)"
|
||||||
></a-input>
|
></a-input>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import useI18n from '@/hooks/useI18n';
|
|||||||
import useNeInfoStore from '@/store/modules/neinfo';
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||||
|
import { parseDateToStr } from '@/utils/date-utils';
|
||||||
const neInfoStore = useNeInfoStore();
|
const neInfoStore = useNeInfoStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -74,21 +75,25 @@ let tableColumns: ColumnsType = [
|
|||||||
width: 2,
|
width: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.license.fileName'),
|
title: t('views.configManage.license.serialNum'),
|
||||||
dataIndex: 'fileName',
|
dataIndex: 'serialNum',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 3,
|
width: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.license.comment'),
|
title: t('views.configManage.license.comment'),
|
||||||
dataIndex: 'comment',
|
dataIndex: 'remark',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 5,
|
width: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.license.createTime'),
|
title: t('views.configManage.license.createTime'),
|
||||||
dataIndex: 'createdAt',
|
dataIndex: 'createTime',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
customRender(opt) {
|
||||||
|
if (!opt.value) return '';
|
||||||
|
return parseDateToStr(opt.value);
|
||||||
|
},
|
||||||
width: 2,
|
width: 2,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -141,7 +146,11 @@ function fnGetList(pageNum?: number) {
|
|||||||
}
|
}
|
||||||
tablePagination.total = res.total;
|
tablePagination.total = res.total;
|
||||||
tableState.data = res.rows;
|
tableState.data = res.rows;
|
||||||
if (tablePagination.total <=(queryParams.pageNum - 1) * tablePagination.pageSize &&queryParams.pageNum !== 1) {
|
if (
|
||||||
|
tablePagination.total <=
|
||||||
|
(queryParams.pageNum - 1) * tablePagination.pageSize &&
|
||||||
|
queryParams.pageNum !== 1
|
||||||
|
) {
|
||||||
tableState.loading = false;
|
tableState.loading = false;
|
||||||
fnGetList(queryParams.pageNum - 1);
|
fnGetList(queryParams.pageNum - 1);
|
||||||
}
|
}
|
||||||
@@ -301,7 +310,7 @@ onMounted(() => {
|
|||||||
fnGetList();
|
fnGetList();
|
||||||
} else {
|
} else {
|
||||||
message.warning({
|
message.warning({
|
||||||
content: t('views.configManage.softwareManage.nullData'),
|
content: t('common.noData'),
|
||||||
duration: 2,
|
duration: 2,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted, toRaw } from 'vue';
|
import { reactive, onMounted, toRaw, ref } from 'vue';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import { message, Modal, Form } from 'ant-design-vue/lib';
|
import { message, Modal, Form } from 'ant-design-vue/lib';
|
||||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||||
@@ -22,8 +22,12 @@ import { updateNeConfigReload } from '@/api/configManage/configParam';
|
|||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||||
|
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
|
||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||||
import useNeInfoStore from '@/store/modules/neinfo';
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
|
import useLockedStore from '@/store/modules/locked';
|
||||||
|
const lockedStore = useLockedStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
/**表格所需option */
|
/**表格所需option */
|
||||||
@@ -86,71 +90,74 @@ let tableColumns: ColumnsType = [
|
|||||||
title: t('views.configManage.neManage.neType'),
|
title: t('views.configManage.neManage.neType'),
|
||||||
dataIndex: 'neType',
|
dataIndex: 'neType',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 3,
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.neId'),
|
title: t('views.configManage.neManage.neId'),
|
||||||
dataIndex: 'neId',
|
dataIndex: 'neId',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 3,
|
width: 100,
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('views.configManage.neManage.uid'),
|
|
||||||
dataIndex: 'rmUid',
|
|
||||||
align: 'center',
|
|
||||||
width: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('views.configManage.neManage.neName'),
|
|
||||||
dataIndex: 'neName',
|
|
||||||
align: 'center',
|
|
||||||
width: 5,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.ip'),
|
title: t('views.configManage.neManage.ip'),
|
||||||
dataIndex: 'ip',
|
dataIndex: 'ip',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 5,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.port'),
|
title: t('views.configManage.neManage.port'),
|
||||||
dataIndex: 'port',
|
dataIndex: 'port',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 3,
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.configManage.neManage.neName'),
|
||||||
|
dataIndex: 'neName',
|
||||||
|
align: 'center',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.configManage.neManage.uid'),
|
||||||
|
dataIndex: 'rmUid',
|
||||||
|
align: 'center',
|
||||||
|
width: 200,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.pvflag'),
|
title: t('views.configManage.neManage.pvflag'),
|
||||||
dataIndex: 'pvFlag',
|
dataIndex: 'pvFlag',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 5,
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.province'),
|
title: t('views.configManage.neManage.province'),
|
||||||
dataIndex: 'province',
|
dataIndex: 'province',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 5,
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.vendorName'),
|
title: t('views.configManage.neManage.vendorName'),
|
||||||
dataIndex: 'vendorName',
|
dataIndex: 'vendorName',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 5,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.dn'),
|
title: t('views.configManage.neManage.dn'),
|
||||||
dataIndex: 'dn',
|
dataIndex: 'dn',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 5,
|
width: 200,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('common.operate'),
|
title: t('common.operate'),
|
||||||
key: 'id',
|
key: 'id',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
width: 5,
|
width: 150,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**表格字段列排序 */
|
||||||
|
let tableColumnsDnd = ref<ColumnsType>([]);
|
||||||
|
|
||||||
/**表格分页器参数 */
|
/**表格分页器参数 */
|
||||||
let tablePagination = reactive({
|
let tablePagination = reactive({
|
||||||
/**当前页数 */
|
/**当前页数 */
|
||||||
@@ -215,11 +222,11 @@ let modalState: ModalStateType = reactive({
|
|||||||
neAddress: '',
|
neAddress: '',
|
||||||
neId: '',
|
neId: '',
|
||||||
neName: '',
|
neName: '',
|
||||||
neType: 'OMC',
|
neType: 'AMF',
|
||||||
port: '3030',
|
port: '33030',
|
||||||
province: '',
|
province: '',
|
||||||
pvFlag: 'PNF',
|
pvFlag: 'PNF',
|
||||||
rmUid: '4400HX1OMC001',
|
rmUid: '4400HX1AMF001',
|
||||||
vendorName: '',
|
vendorName: '',
|
||||||
sync: true,
|
sync: true,
|
||||||
},
|
},
|
||||||
@@ -541,6 +548,11 @@ function fnRecordRestart(row: Record<string, any>) {
|
|||||||
restartNf(row)
|
restartNf(row)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// OMC自升级
|
||||||
|
if (row.neType.toLowerCase() === 'omc') {
|
||||||
|
lockedStore.fnLock('reload');
|
||||||
|
return;
|
||||||
|
}
|
||||||
message.success({
|
message.success({
|
||||||
content: t('common.msgSuccess', {
|
content: t('common.msgSuccess', {
|
||||||
msg: t('views.configManage.neManage.restart'),
|
msg: t('views.configManage.neManage.restart'),
|
||||||
@@ -785,11 +797,12 @@ onMounted(() => {
|
|||||||
:label="t('views.configManage.neManage.neType')"
|
:label="t('views.configManage.neManage.neType')"
|
||||||
name="neType "
|
name="neType "
|
||||||
>
|
>
|
||||||
<a-input
|
<a-auto-complete
|
||||||
v-model:value="queryParams.neType"
|
v-model:value="queryParams.neType"
|
||||||
|
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
|
||||||
allow-clear
|
allow-clear
|
||||||
:placeholder="t('views.configManage.neManage.neTypePlease')"
|
:placeholder="t('common.inputPlease')"
|
||||||
></a-input>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
@@ -839,6 +852,11 @@ onMounted(() => {
|
|||||||
<template #icon><ReloadOutlined /></template>
|
<template #icon><ReloadOutlined /></template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
<TableColumnsDnd
|
||||||
|
cache-id="neManageData"
|
||||||
|
:columns="tableColumns"
|
||||||
|
v-model:columns-dnd="tableColumnsDnd"
|
||||||
|
></TableColumnsDnd>
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.sizeText') }}</template>
|
<template #title>{{ t('common.sizeText') }}</template>
|
||||||
<a-dropdown trigger="click" placement="bottomRight">
|
<a-dropdown trigger="click" placement="bottomRight">
|
||||||
@@ -870,15 +888,15 @@ onMounted(() => {
|
|||||||
<a-table
|
<a-table
|
||||||
class="table"
|
class="table"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:columns="tableColumns"
|
:columns="tableColumnsDnd"
|
||||||
:loading="tableState.loading"
|
:loading="tableState.loading"
|
||||||
:data-source="tableState.data"
|
:data-source="tableState.data"
|
||||||
:size="tableState.size"
|
:size="tableState.size"
|
||||||
:pagination="tablePagination"
|
:pagination="tablePagination"
|
||||||
:scroll="{ x: 2000, y: 480 }"
|
:scroll="{ y: 'calc(100vh - 480px)' }"
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.key === 'id'">
|
<template v-if="column?.key === 'id'">
|
||||||
<a-space :size="8" align="center">
|
<a-space :size="8" align="center">
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.editText') }}</template>
|
<template #title>{{ t('common.editText') }}</template>
|
||||||
@@ -902,10 +920,7 @@ onMounted(() => {
|
|||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip placement="left">
|
<a-tooltip placement="left">
|
||||||
<template #title>{{ t('common.moreText') }}</template>
|
<template #title>{{ t('common.moreText') }}</template>
|
||||||
<a-dropdown
|
<a-dropdown placement="bottomRight" trigger="click">
|
||||||
placement="bottomRight"
|
|
||||||
:trigger="['hover', 'click']"
|
|
||||||
>
|
|
||||||
<a-button type="link">
|
<a-button type="link">
|
||||||
<template #icon><EllipsisOutlined /> </template>
|
<template #icon><EllipsisOutlined /> </template>
|
||||||
</a-button>
|
</a-button>
|
||||||
@@ -919,11 +934,17 @@ onMounted(() => {
|
|||||||
<ImportOutlined />
|
<ImportOutlined />
|
||||||
{{ t('views.configManage.neManage.import') }}
|
{{ t('views.configManage.neManage.import') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item key="start">
|
<a-menu-item
|
||||||
|
key="start"
|
||||||
|
v-if="!['OMC'].includes(record.neType)"
|
||||||
|
>
|
||||||
<thunderbolt-outlined />
|
<thunderbolt-outlined />
|
||||||
{{ t('views.configManage.neManage.start') }}
|
{{ t('views.configManage.neManage.start') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item key="stop">
|
<a-menu-item
|
||||||
|
key="stop"
|
||||||
|
v-if="!['OMC'].includes(record.neType)"
|
||||||
|
>
|
||||||
<pause-outlined />
|
<pause-outlined />
|
||||||
{{ t('views.configManage.neManage.stop') }}
|
{{ t('views.configManage.neManage.stop') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
@@ -974,20 +995,21 @@ onMounted(() => {
|
|||||||
name="neType"
|
name="neType"
|
||||||
v-bind="modalStateFrom.validateInfos.neType"
|
v-bind="modalStateFrom.validateInfos.neType"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-auto-complete
|
||||||
v-model:value="modalState.from.neType"
|
v-model:value="modalState.from.neType"
|
||||||
allow-clear
|
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
|
||||||
:placeholder="t('views.configManage.neManage.neTypePlease')"
|
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<a-input allow-clear :placeholder="t('common.inputPlease')">
|
||||||
<a-tooltip placement="topLeft">
|
<template #prefix>
|
||||||
<template #title>{{
|
<a-tooltip placement="topLeft">
|
||||||
t('views.configManage.neManage.neTypeTip')
|
<template #title>{{
|
||||||
}}</template>
|
t('views.configManage.neManage.neTypeTip')
|
||||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
}}</template>
|
||||||
</a-tooltip>
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
</template>
|
</a-tooltip>
|
||||||
</a-input>
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-auto-complete>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
@@ -1135,7 +1157,7 @@ onMounted(() => {
|
|||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.configManage.neManage.sync')"
|
:label="t('views.configManage.neManage.sync')"
|
||||||
name="province"
|
name="sync"
|
||||||
>
|
>
|
||||||
<a-switch
|
<a-switch
|
||||||
v-model:checked="modalState.from.sync"
|
v-model:checked="modalState.from.sync"
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ let tableColumns: ColumnsType = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.softwareManage.fileName'),
|
title: t('views.configManage.softwareManage.fileName'),
|
||||||
dataIndex: 'fileName',
|
dataIndex: 'name',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 2,
|
width: 2,
|
||||||
},
|
},
|
||||||
@@ -94,7 +94,7 @@ let tableColumns: ColumnsType = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.softwareManage.updateTime'),
|
title: t('views.configManage.softwareManage.updateTime'),
|
||||||
dataIndex: 'updateTime',
|
dataIndex: 'createTime',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
customRender(opt) {
|
customRender(opt) {
|
||||||
if (!opt.value) return '';
|
if (!opt.value) return '';
|
||||||
@@ -104,7 +104,7 @@ let tableColumns: ColumnsType = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.softwareManage.description'),
|
title: t('views.configManage.softwareManage.description'),
|
||||||
dataIndex: 'comment',
|
dataIndex: 'name',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 2,
|
width: 2,
|
||||||
},
|
},
|
||||||
@@ -274,6 +274,7 @@ function fnFileModalVisible(type: string | number, row: Record<string, any>) {
|
|||||||
* 进行表达规则校验
|
* 进行表达规则校验
|
||||||
*/
|
*/
|
||||||
function fnFileModalOk() {
|
function fnFileModalOk() {
|
||||||
|
if (fileModalState.confirmLoading) return;
|
||||||
fileModalStateFrom
|
fileModalStateFrom
|
||||||
.validate()
|
.validate()
|
||||||
.then(e => {
|
.then(e => {
|
||||||
@@ -730,13 +731,15 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
message.warning({
|
message.warning({
|
||||||
content: t('views.configManage.softwareManage.nullData'),
|
content: t('common.noData'),
|
||||||
duration: 2,
|
duration: 2,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
// 获取列表数据
|
||||||
|
fnGetList();
|
||||||
});
|
});
|
||||||
// 获取列表数据
|
|
||||||
fnGetList();
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -889,10 +892,7 @@ onMounted(() => {
|
|||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip placement="left">
|
<a-tooltip placement="left">
|
||||||
<template #title>{{ t('common.moreText') }}</template>
|
<template #title>{{ t('common.moreText') }}</template>
|
||||||
<a-dropdown
|
<a-dropdown placement="bottomRight" trigger="click">
|
||||||
placement="bottomRight"
|
|
||||||
:trigger="['hover', 'click']"
|
|
||||||
>
|
|
||||||
<a-button type="link">
|
<a-button type="link">
|
||||||
<template #icon><EllipsisOutlined /> </template>
|
<template #icon><EllipsisOutlined /> </template>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted, toRaw, ref, onUnmounted } from 'vue';
|
import { reactive, onMounted, toRaw, ref, onBeforeUnmount } from 'vue';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import { message, Modal } from 'ant-design-vue/lib';
|
import { message, Modal } from 'ant-design-vue/lib';
|
||||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||||
@@ -39,6 +39,7 @@ let queryParams = reactive({
|
|||||||
neType: 'AMF',
|
neType: 'AMF',
|
||||||
neId: '001',
|
neId: '001',
|
||||||
eventType: 'auth-result',
|
eventType: 'auth-result',
|
||||||
|
imsi: '',
|
||||||
sortField: 'timestamp',
|
sortField: 'timestamp',
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
/**当前页数 */
|
/**当前页数 */
|
||||||
@@ -52,6 +53,7 @@ function fnQueryReset() {
|
|||||||
eventTypes.value = ['auth-result'];
|
eventTypes.value = ['auth-result'];
|
||||||
queryParams = Object.assign(queryParams, {
|
queryParams = Object.assign(queryParams, {
|
||||||
eventType: 'auth-result',
|
eventType: 'auth-result',
|
||||||
|
imsi: '',
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
});
|
});
|
||||||
@@ -76,8 +78,6 @@ type TabeStateType = {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
/**紧凑型 */
|
/**紧凑型 */
|
||||||
size: SizeType;
|
size: SizeType;
|
||||||
/**斑马纹 */
|
|
||||||
striped: boolean;
|
|
||||||
/**搜索栏 */
|
/**搜索栏 */
|
||||||
seached: boolean;
|
seached: boolean;
|
||||||
/**记录数据 */
|
/**记录数据 */
|
||||||
@@ -90,7 +90,6 @@ type TabeStateType = {
|
|||||||
let tableState: TabeStateType = reactive({
|
let tableState: TabeStateType = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
striped: false,
|
|
||||||
seached: true,
|
seached: true,
|
||||||
data: [],
|
data: [],
|
||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
@@ -108,7 +107,7 @@ let tableColumns: ColumnsType = [
|
|||||||
title: 'IMSI',
|
title: 'IMSI',
|
||||||
dataIndex: 'eventJSON',
|
dataIndex: 'eventJSON',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 150,
|
||||||
customRender(opt) {
|
customRender(opt) {
|
||||||
const eventJSON = opt.value;
|
const eventJSON = opt.value;
|
||||||
return eventJSON.imsi;
|
return eventJSON.imsi;
|
||||||
@@ -119,20 +118,20 @@ let tableColumns: ColumnsType = [
|
|||||||
dataIndex: 'eventType',
|
dataIndex: 'eventType',
|
||||||
key: 'eventType',
|
key: 'eventType',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.dashboard.ue.result'),
|
title: t('views.dashboard.ue.result'),
|
||||||
dataIndex: 'eventJSON',
|
dataIndex: 'eventJSON',
|
||||||
key: 'result',
|
key: 'result',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.dashboard.ue.time'),
|
title: t('views.dashboard.ue.time'),
|
||||||
dataIndex: 'eventJSON',
|
dataIndex: 'eventJSON',
|
||||||
key: 'time',
|
key: 'time',
|
||||||
align: 'center',
|
align: 'left',
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -175,11 +174,6 @@ function fnTableSize({ key }: MenuInfo) {
|
|||||||
tableState.size = key as SizeType;
|
tableState.size = key as SizeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**表格斑马纹 */
|
|
||||||
function fnTableStriped(_record: unknown, index: number): any {
|
|
||||||
return tableState.striped && index % 2 === 1 ? 'table-striped' : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**表格多选 */
|
/**表格多选 */
|
||||||
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
||||||
tableState.selectedRowKeys = keys;
|
tableState.selectedRowKeys = keys;
|
||||||
@@ -374,8 +368,10 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onBeforeUnmount(() => {
|
||||||
ws.close();
|
if (ws.state() !== -1) {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -389,20 +385,29 @@ onUnmounted(() => {
|
|||||||
<!-- 表格搜索栏 -->
|
<!-- 表格搜索栏 -->
|
||||||
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.dashboard.ue.eventType')"
|
:label="t('views.dashboard.ue.eventType')"
|
||||||
name="eventType "
|
name="eventType "
|
||||||
>
|
>
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="eventTypes"
|
v-model:value="eventTypes"
|
||||||
mode="tags"
|
mode="multiple"
|
||||||
:options="dict.ueEventType"
|
:options="dict.ueEventType"
|
||||||
:placeholder="t('common.selectPlease')"
|
:placeholder="t('common.selectPlease')"
|
||||||
@change="fnQueryEventTypeChange"
|
@change="fnQueryEventTypeChange"
|
||||||
></a-select>
|
></a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item label="IMSI" name="imsi ">
|
||||||
|
<a-input
|
||||||
|
v-model:value="queryParams.imsi"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<a-space :size="8">
|
<a-space :size="8">
|
||||||
@@ -471,15 +476,6 @@ onUnmounted(() => {
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.tableStripedText') }}</template>
|
|
||||||
<a-switch
|
|
||||||
v-model:checked="tableState.striped"
|
|
||||||
:checked-children="t('common.switch.open')"
|
|
||||||
:un-checked-children="t('common.switch.shut')"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
@@ -522,7 +518,6 @@ onUnmounted(() => {
|
|||||||
:data-source="tableState.data"
|
:data-source="tableState.data"
|
||||||
:size="tableState.size"
|
:size="tableState.size"
|
||||||
:pagination="tablePagination"
|
:pagination="tablePagination"
|
||||||
:row-class-name="fnTableStriped"
|
|
||||||
:scroll="{ x: tableColumns.length * 120, y: 'calc(100vh - 480px)' }"
|
:scroll="{ x: tableColumns.length * 120, y: 'calc(100vh - 480px)' }"
|
||||||
:row-selection="{
|
:row-selection="{
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
@@ -658,10 +653,6 @@ onUnmounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.table :deep(.table-striped) td {
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table :deep(.ant-pagination) {
|
.table :deep(.ant-pagination) {
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted, toRaw, ref, onUnmounted } from 'vue';
|
import { reactive, onMounted, toRaw, ref, onBeforeUnmount } from 'vue';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import { message, Modal } from 'ant-design-vue/lib';
|
import { message, Modal } from 'ant-design-vue/lib';
|
||||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||||
@@ -37,6 +37,8 @@ let queryParams = reactive({
|
|||||||
neType: 'IMS',
|
neType: 'IMS',
|
||||||
neId: '001',
|
neId: '001',
|
||||||
recordType: 'MOC',
|
recordType: 'MOC',
|
||||||
|
callerParty: '',
|
||||||
|
calledParty: '',
|
||||||
sortField: 'timestamp',
|
sortField: 'timestamp',
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
/**当前页数 */
|
/**当前页数 */
|
||||||
@@ -50,6 +52,8 @@ function fnQueryReset() {
|
|||||||
recordTypes.value = ['MOC'];
|
recordTypes.value = ['MOC'];
|
||||||
queryParams = Object.assign(queryParams, {
|
queryParams = Object.assign(queryParams, {
|
||||||
recordType: 'MOC',
|
recordType: 'MOC',
|
||||||
|
callerParty: '',
|
||||||
|
calledParty: '',
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
});
|
});
|
||||||
@@ -74,8 +78,6 @@ type TabeStateType = {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
/**紧凑型 */
|
/**紧凑型 */
|
||||||
size: SizeType;
|
size: SizeType;
|
||||||
/**斑马纹 */
|
|
||||||
striped: boolean;
|
|
||||||
/**搜索栏 */
|
/**搜索栏 */
|
||||||
seached: boolean;
|
seached: boolean;
|
||||||
/**记录数据 */
|
/**记录数据 */
|
||||||
@@ -88,7 +90,6 @@ type TabeStateType = {
|
|||||||
let tableState: TabeStateType = reactive({
|
let tableState: TabeStateType = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
striped: false,
|
|
||||||
seached: true,
|
seached: true,
|
||||||
data: [],
|
data: [],
|
||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
@@ -106,7 +107,7 @@ let tableColumns: ColumnsType = [
|
|||||||
title: t('views.dashboard.cdr.recordType'),
|
title: t('views.dashboard.cdr.recordType'),
|
||||||
dataIndex: 'cdrJSON',
|
dataIndex: 'cdrJSON',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 150,
|
||||||
customRender(opt) {
|
customRender(opt) {
|
||||||
const cdrJSON = opt.value;
|
const cdrJSON = opt.value;
|
||||||
return cdrJSON.recordType;
|
return cdrJSON.recordType;
|
||||||
@@ -124,7 +125,7 @@ let tableColumns: ColumnsType = [
|
|||||||
dataIndex: 'cdrJSON',
|
dataIndex: 'cdrJSON',
|
||||||
key: 'calledParty',
|
key: 'calledParty',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 120,
|
||||||
customRender(opt) {
|
customRender(opt) {
|
||||||
const cdrJSON = opt.value;
|
const cdrJSON = opt.value;
|
||||||
return cdrJSON.calledParty;
|
return cdrJSON.calledParty;
|
||||||
@@ -135,7 +136,7 @@ let tableColumns: ColumnsType = [
|
|||||||
dataIndex: 'cdrJSON',
|
dataIndex: 'cdrJSON',
|
||||||
key: 'callerParty',
|
key: 'callerParty',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 120,
|
||||||
customRender(opt) {
|
customRender(opt) {
|
||||||
const cdrJSON = opt.value;
|
const cdrJSON = opt.value;
|
||||||
return cdrJSON.callerParty;
|
return cdrJSON.callerParty;
|
||||||
@@ -159,7 +160,7 @@ let tableColumns: ColumnsType = [
|
|||||||
dataIndex: 'cdrJSON',
|
dataIndex: 'cdrJSON',
|
||||||
key: 'cause',
|
key: 'cause',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.dashboard.cdr.time'),
|
title: t('views.dashboard.cdr.time'),
|
||||||
@@ -211,11 +212,6 @@ function fnTableSize({ key }: MenuInfo) {
|
|||||||
tableState.size = key as SizeType;
|
tableState.size = key as SizeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**表格斑马纹 */
|
|
||||||
function fnTableStriped(_record: unknown, index: number): any {
|
|
||||||
return tableState.striped && index % 2 === 1 ? 'table-striped' : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**表格多选 */
|
/**表格多选 */
|
||||||
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
||||||
tableState.selectedRowKeys = keys;
|
tableState.selectedRowKeys = keys;
|
||||||
@@ -402,8 +398,10 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onBeforeUnmount(() => {
|
||||||
ws.close();
|
if (ws.state() !== -1) {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -417,14 +415,14 @@ onUnmounted(() => {
|
|||||||
<!-- 表格搜索栏 -->
|
<!-- 表格搜索栏 -->
|
||||||
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="8" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.dashboard.cdr.recordType')"
|
:label="t('views.dashboard.cdr.recordType')"
|
||||||
name="recordType "
|
name="recordType "
|
||||||
>
|
>
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="recordTypes"
|
v-model:value="recordTypes"
|
||||||
mode="tags"
|
mode="multiple"
|
||||||
:options="
|
:options="
|
||||||
['MOC', 'MTC', 'MOSM', 'MTSM'].map(v => ({ value: v }))
|
['MOC', 'MTC', 'MOSM', 'MTSM'].map(v => ({ value: v }))
|
||||||
"
|
"
|
||||||
@@ -433,7 +431,31 @@ onUnmounted(() => {
|
|||||||
></a-select>
|
></a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
<a-col :lg="4" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.dashboard.cdr.called')"
|
||||||
|
name="calledParty "
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="queryParams.calledParty"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="4" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.dashboard.cdr.caller')"
|
||||||
|
name="callerParty "
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="queryParams.callerParty"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="4" :md="12" :xs="24">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<a-space :size="8">
|
<a-space :size="8">
|
||||||
<a-button type="primary" @click.prevent="fnGetList(1)">
|
<a-button type="primary" @click.prevent="fnGetList(1)">
|
||||||
@@ -501,15 +523,6 @@ onUnmounted(() => {
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.tableStripedText') }}</template>
|
|
||||||
<a-switch
|
|
||||||
v-model:checked="tableState.striped"
|
|
||||||
:checked-children="t('common.switch.open')"
|
|
||||||
:un-checked-children="t('common.switch.shut')"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
@@ -552,7 +565,6 @@ onUnmounted(() => {
|
|||||||
:data-source="tableState.data"
|
:data-source="tableState.data"
|
||||||
:size="tableState.size"
|
:size="tableState.size"
|
||||||
:pagination="tablePagination"
|
:pagination="tablePagination"
|
||||||
:row-class-name="fnTableStriped"
|
|
||||||
:scroll="{ x: tableColumns.length * 120, y: 'calc(100vh - 480px)' }"
|
:scroll="{ x: tableColumns.length * 120, y: 'calc(100vh - 480px)' }"
|
||||||
:row-selection="{
|
:row-selection="{
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
@@ -659,10 +671,6 @@ onUnmounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.table :deep(.table-striped) td {
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table :deep(.ant-pagination) {
|
.table :deep(.ant-pagination) {
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,202 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import * as echarts from 'echarts/core';
|
||||||
|
import {
|
||||||
|
TitleComponent,
|
||||||
|
TitleComponentOption,
|
||||||
|
TooltipComponent,
|
||||||
|
TooltipComponentOption,
|
||||||
|
GridComponent,
|
||||||
|
GridComponentOption,
|
||||||
|
LegendComponent,
|
||||||
|
LegendComponentOption,
|
||||||
|
} from 'echarts/components';
|
||||||
|
import {
|
||||||
|
PieChart,
|
||||||
|
PieSeriesOption,
|
||||||
|
BarChart,
|
||||||
|
BarSeriesOption,
|
||||||
|
} from 'echarts/charts';
|
||||||
|
import { LabelLayout } from 'echarts/features';
|
||||||
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
|
|
||||||
|
import { markRaw, onMounted, ref } from 'vue';
|
||||||
|
import { origGet, top3Sel } from '@/api/faultManage/actAlarm';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
echarts.use([
|
||||||
|
TitleComponent,
|
||||||
|
TooltipComponent,
|
||||||
|
GridComponent,
|
||||||
|
LegendComponent,
|
||||||
|
PieChart,
|
||||||
|
BarChart,
|
||||||
|
CanvasRenderer,
|
||||||
|
LabelLayout,
|
||||||
|
]);
|
||||||
|
|
||||||
|
type EChartsOption = echarts.ComposeOption<
|
||||||
|
| TitleComponentOption
|
||||||
|
| TooltipComponentOption
|
||||||
|
| GridComponentOption
|
||||||
|
| LegendComponentOption
|
||||||
|
| PieSeriesOption
|
||||||
|
| BarSeriesOption
|
||||||
|
>;
|
||||||
|
|
||||||
|
/**图DOM节点实例对象 */
|
||||||
|
const alarmTypeBar = ref<HTMLElement | undefined>(undefined);
|
||||||
|
|
||||||
|
/**图实例对象 */
|
||||||
|
const alarmTypeBarChart = ref<any>(null);
|
||||||
|
|
||||||
|
/**告警类型数据 */
|
||||||
|
const alarmTypeType = ref<any>([
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: t('views.index.Critical'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: t('views.index.Major'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: t('views.index.Minor'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: t('views.index.Warning'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
name: t('views.index.Event'),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
//
|
||||||
|
function initPicture() {
|
||||||
|
Promise.allSettled([origGet()])
|
||||||
|
.then(resArr => {
|
||||||
|
if (resArr[0].status === 'fulfilled') {
|
||||||
|
const res0 = resArr[0].value;
|
||||||
|
if (res0.code === RESULT_CODE_SUCCESS && Array.isArray(res0.data)) {
|
||||||
|
for (const item of res0.data) {
|
||||||
|
let index = 0;
|
||||||
|
switch (item.name) {
|
||||||
|
case 'Critical':
|
||||||
|
index = 0;
|
||||||
|
break;
|
||||||
|
case 'Major':
|
||||||
|
index = 1;
|
||||||
|
break;
|
||||||
|
case 'Minor':
|
||||||
|
index = 2;
|
||||||
|
break;
|
||||||
|
case 'Warning':
|
||||||
|
index = 3;
|
||||||
|
break;
|
||||||
|
case 'Event':
|
||||||
|
index = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
alarmTypeType.value[index].value = Number(item.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const optionData: EChartsOption = {
|
||||||
|
title: [
|
||||||
|
{
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: '{b} : {c}',
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
orient: 'vertical',
|
||||||
|
right: '2%',
|
||||||
|
top: '10%',
|
||||||
|
data: alarmTypeType.value.map((item: any) => item.name), //label数组
|
||||||
|
textStyle: {
|
||||||
|
color: '#A7D6F4', // 设置图例文字颜色
|
||||||
|
},
|
||||||
|
},
|
||||||
|
grid: [
|
||||||
|
{
|
||||||
|
top: '60%',
|
||||||
|
left: '15%',
|
||||||
|
right: '25%',
|
||||||
|
bottom: '10%',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
//饼图:
|
||||||
|
{
|
||||||
|
type: 'pie',
|
||||||
|
radius: '60%',
|
||||||
|
color: ['#f5222d', '#fa8c16', '#fadb14', '#1677ff', '#13c2c2'],
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'inner',
|
||||||
|
formatter: (params: any) => {
|
||||||
|
if (!params.value) return '';
|
||||||
|
return `${params.value}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
center: ['30%', '40%'],
|
||||||
|
data: alarmTypeType.value,
|
||||||
|
zlevel: 2, // 设置zlevel为1,使得柱状图在下层显示
|
||||||
|
itemStyle: {
|
||||||
|
shadowBlur: 10,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
fnDesign(alarmTypeBar.value, optionData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fnDesign(container: HTMLElement | undefined, option: any) {
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
alarmTypeBarChart.value = markRaw(echarts.init(container, 'light'));
|
||||||
|
option && alarmTypeBarChart.value.setOption(option);
|
||||||
|
|
||||||
|
// 创建 ResizeObserver 实例
|
||||||
|
var observer = new ResizeObserver(entries => {
|
||||||
|
if (alarmTypeBarChart.value) {
|
||||||
|
alarmTypeBarChart.value.resize();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 监听元素大小变化
|
||||||
|
observer.observe(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
initPicture();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div ref="alarmTypeBar" class="chart-container"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.chart-container {
|
||||||
|
/* 设置图表容器大小和位置 */
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, toRaw, watch } from 'vue';
|
||||||
|
import { dbGetJSON, dbSetJSON } from '@/utils/cache-db-utils';
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
|
||||||
|
const props = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '标题',
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**数据参数 */
|
||||||
|
let dataState = reactive({
|
||||||
|
/**基站数 */
|
||||||
|
baseNum: 0,
|
||||||
|
/**核心网数 */
|
||||||
|
coreNetNum: 0,
|
||||||
|
/**在线用户数 */
|
||||||
|
onlineUserNum: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**弹框取消按钮事件 */
|
||||||
|
function fnModalOk() {
|
||||||
|
dbSetJSON('tbl_mocn', `tmp`, toRaw(dataState));
|
||||||
|
emit('ok');
|
||||||
|
emit('update:visible', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**弹框取消按钮事件 */
|
||||||
|
function fnModalCancel() {
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:visible', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**显示弹框时初始数据 */
|
||||||
|
function init() {
|
||||||
|
// 读取数据
|
||||||
|
dbGetJSON('tbl_mocn', `tmp`).then(data => {
|
||||||
|
if (data) {
|
||||||
|
Object.assign(dataState, data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
val => {
|
||||||
|
if (val) init();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
width="800px"
|
||||||
|
:title="props.title"
|
||||||
|
:visible="props.visible"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="dataState"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-form-item label="baseNum" name="baseNum">
|
||||||
|
<a-input-number v-model:value="dataState.baseNum"> </a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="coreNetNum" name="coreNetNum">
|
||||||
|
<a-input-number v-model:value="dataState.coreNetNum"> </a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="onlineUserNum" name="onlineUserNum">
|
||||||
|
<a-input-number v-model:value="dataState.onlineUserNum">
|
||||||
|
</a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
@@ -0,0 +1,567 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onBeforeUnmount, onMounted, reactive, ref } from 'vue';
|
||||||
|
import svgBase from '@/assets/svg/base.svg';
|
||||||
|
import svgUserIMS from '@/assets/svg/userIMS.svg';
|
||||||
|
import svgUserSMF from '@/assets/svg/userSMF.svg';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import Topology from '../overview/components/Topology/index.vue';
|
||||||
|
import NeResources from '../overview/components/NeResources/index.vue';
|
||||||
|
import UserActivity from '../overview/components/UserActivity/index.vue';
|
||||||
|
import AlarnTypeBar from './components/AlarnTypeBar/index.vue';
|
||||||
|
import setting from './components/setting.vue';
|
||||||
|
import UPFFlow from '../overview/components/UPFFlow/index.vue';
|
||||||
|
import { listSub } from '@/api/neUser/sub';
|
||||||
|
import { listUENumBySMF } from '@/api/neUser/smf';
|
||||||
|
import { listUENumByIMS } from '@/api/neUser/ims';
|
||||||
|
import { listBase5G } from '@/api/neUser/base5G';
|
||||||
|
import {
|
||||||
|
graphNodeClickID,
|
||||||
|
graphState,
|
||||||
|
notNeNodes,
|
||||||
|
graphNodeStateNum,
|
||||||
|
neStateRequestMap,
|
||||||
|
} from '../overview/hooks/useTopology';
|
||||||
|
import { upfTotalFlow, upfTFActive } from '../overview/hooks/useUPFTotalFlow';
|
||||||
|
import { useFullscreen } from '@vueuse/core';
|
||||||
|
import useWS from '../overview/hooks/useWS';
|
||||||
|
import useAppStore from '@/store/modules/app';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { dbGetJSON } from '@/utils/cache-db-utils';
|
||||||
|
const router = useRouter();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { wsSend, cdrEventSend, ueEventSend, upfTFSend } = useWS();
|
||||||
|
|
||||||
|
/**概览状态类型 */
|
||||||
|
type SkimStateType = {
|
||||||
|
/**UDM签约用户数量 */
|
||||||
|
udmSubNum: number;
|
||||||
|
/**SMF在线用户数 */
|
||||||
|
smfUeNum: number;
|
||||||
|
/**IMS在线用户数 */
|
||||||
|
imsUeNum: number;
|
||||||
|
/**5G基站数量 */
|
||||||
|
gnbNum: number;
|
||||||
|
/**5G在线用户数量 */
|
||||||
|
gnbUeNum: number;
|
||||||
|
/**4G基站数量 */
|
||||||
|
enbNum: number;
|
||||||
|
/**4G在线用户数量 */
|
||||||
|
enbUeNum: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**概览状态信息 */
|
||||||
|
let skimState: SkimStateType = reactive({
|
||||||
|
udmSubNum: 0,
|
||||||
|
smfUeNum: 0,
|
||||||
|
imsUeNum: 0,
|
||||||
|
gnbNum: 0,
|
||||||
|
gnbUeNum: 0,
|
||||||
|
enbNum: 0,
|
||||||
|
enbUeNum: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**总览节点 */
|
||||||
|
const viewportDom = ref<HTMLElement | null>(null);
|
||||||
|
const { isFullscreen, toggle } = useFullscreen(viewportDom);
|
||||||
|
|
||||||
|
/**10s调度器 */
|
||||||
|
const interval10s = ref<any>(null);
|
||||||
|
|
||||||
|
/**5s调度器 */
|
||||||
|
const interval5s = ref<any>(null);
|
||||||
|
|
||||||
|
/**查询网元状态 */
|
||||||
|
function fnGetNeState() {
|
||||||
|
// 获取节点状态
|
||||||
|
for (const node of graphState.data.nodes) {
|
||||||
|
if (notNeNodes.includes(node.id)) continue;
|
||||||
|
const { neType, neId } = node.neInfo;
|
||||||
|
if (!neType || !neId) continue;
|
||||||
|
// 请求标记检查避免重复发送
|
||||||
|
if (neStateRequestMap.value.get(neType)) continue;
|
||||||
|
neStateRequestMap.value.set(neType, true);
|
||||||
|
|
||||||
|
wsSend({
|
||||||
|
requestId: `neState_${neType}_${neId}`,
|
||||||
|
type: 'ne_state',
|
||||||
|
data: {
|
||||||
|
neType: neType,
|
||||||
|
neId: neId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**获取概览信息 */
|
||||||
|
async function fnGetSkim() {
|
||||||
|
const resArr = await Promise.allSettled([
|
||||||
|
listSub({
|
||||||
|
neid: '001',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 1,
|
||||||
|
}),
|
||||||
|
listUENumBySMF('001'),
|
||||||
|
listUENumByIMS('001'),
|
||||||
|
listBase5G({
|
||||||
|
neType: 'AMF',
|
||||||
|
neId: '001',
|
||||||
|
}),
|
||||||
|
listBase5G({
|
||||||
|
neType: 'MME',
|
||||||
|
neId: '001',
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (resArr[0].status === 'fulfilled') {
|
||||||
|
const res0 = resArr[0].value;
|
||||||
|
if (res0.code === RESULT_CODE_SUCCESS) {
|
||||||
|
skimState.udmSubNum = res0.total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resArr[1].status === 'fulfilled') {
|
||||||
|
const res1 = resArr[1].value;
|
||||||
|
if (res1.code === RESULT_CODE_SUCCESS) {
|
||||||
|
skimState.smfUeNum = res1.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resArr[2].status === 'fulfilled') {
|
||||||
|
const res2 = resArr[2].value;
|
||||||
|
if (res2.code === RESULT_CODE_SUCCESS) {
|
||||||
|
skimState.imsUeNum = res2.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resArr[3].status === 'fulfilled') {
|
||||||
|
const res3 = resArr[3].value;
|
||||||
|
if (res3.code === RESULT_CODE_SUCCESS) {
|
||||||
|
skimState.gnbNum = res3.total;
|
||||||
|
skimState.gnbUeNum = 0;
|
||||||
|
res3.rows.map((item: any) => {
|
||||||
|
skimState.gnbUeNum += item.ueNum;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resArr[4].status === 'fulfilled') {
|
||||||
|
const res4 = resArr[4].value;
|
||||||
|
if (res4.code === RESULT_CODE_SUCCESS) {
|
||||||
|
skimState.enbNum = res4.total;
|
||||||
|
skimState.enbUeNum = 0;
|
||||||
|
res4.rows.map((item: any) => {
|
||||||
|
skimState.enbUeNum += item.ueNum;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**初始数据函数 */
|
||||||
|
function loadData() {
|
||||||
|
fnGetNeState(); // 获取网元状态
|
||||||
|
cdrEventSend();
|
||||||
|
ueEventSend();
|
||||||
|
upfTFSend(0);
|
||||||
|
upfTFSend(7);
|
||||||
|
upfTFSend(30);
|
||||||
|
|
||||||
|
interval10s.value = setInterval(() => {
|
||||||
|
upfTFActive.value = upfTFActive.value >= 2 ? 0 : upfTFActive.value + 1;
|
||||||
|
if (upfTFActive.value === 0) {
|
||||||
|
upfTFSend(7);
|
||||||
|
} else if (upfTFActive.value === 1) {
|
||||||
|
upfTFSend(30);
|
||||||
|
} else if (upfTFActive.value === 2) {
|
||||||
|
upfTFSend(0);
|
||||||
|
}
|
||||||
|
}, 10_000);
|
||||||
|
|
||||||
|
interval5s.value = setInterval(() => {
|
||||||
|
fnGetSkim(); // 获取概览信息
|
||||||
|
fnGetNeState(); // 获取网元状态
|
||||||
|
}, 5_000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**栏目信息跳转 */
|
||||||
|
function fnToRouter(name: string, query?: any) {
|
||||||
|
router.push({ name, query });
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fnGetSkim().then(() => {
|
||||||
|
loadData();
|
||||||
|
});
|
||||||
|
// 读取数据
|
||||||
|
dbGetJSON('tbl_mocn', `tmp`).then(data => {
|
||||||
|
if (data) {
|
||||||
|
Object.assign(mocnState.data, data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
clearInterval(interval10s.value);
|
||||||
|
clearInterval(interval5s.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**MOCN状态 */
|
||||||
|
const mocnState = reactive({
|
||||||
|
title: 'Set MOCN Data',
|
||||||
|
visible: false,
|
||||||
|
data: {
|
||||||
|
/**基站数 */
|
||||||
|
baseNum: 0,
|
||||||
|
/**核心网数 */
|
||||||
|
coreNetNum: 0,
|
||||||
|
/**在线用户数 */
|
||||||
|
onlineUserNum: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
/**MOCN 右击设置 */
|
||||||
|
function fnRightClick() {
|
||||||
|
mocnState.visible = true;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="viewport" ref="viewportDom">
|
||||||
|
<div class="brand">
|
||||||
|
<div
|
||||||
|
class="brand-title"
|
||||||
|
@click="toggle"
|
||||||
|
:title="t('views.dashboard.overview.fullscreen')"
|
||||||
|
>
|
||||||
|
{{ t('views.dashboard.overview.title') }}
|
||||||
|
<FullscreenExitOutlined v-if="isFullscreen" />
|
||||||
|
<FullscreenOutlined v-else />
|
||||||
|
</div>
|
||||||
|
<div class="brand-desc">{{ appStore.appName }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column">
|
||||||
|
<!--概览-->
|
||||||
|
<div class="skim panel">
|
||||||
|
<div class="inner">
|
||||||
|
<h3>
|
||||||
|
<IdcardOutlined style="color: #68d8fe" />
|
||||||
|
{{ t('views.dashboard.overview.skim.userTitle') }}
|
||||||
|
</h3>
|
||||||
|
<div class="data">
|
||||||
|
<div
|
||||||
|
class="item toRouter"
|
||||||
|
@click="fnToRouter('Sub_2010')"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<UserOutlined
|
||||||
|
style="color: #4096ff; margin-right: 8px; font-size: 1.1rem"
|
||||||
|
/>
|
||||||
|
{{ skimState.udmSubNum }}
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
{{ t('views.dashboard.overview.skim.users') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="item toRouter"
|
||||||
|
@click="fnToRouter('Ims_2080')"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
style="margin: 0 12px"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<img :src="svgUserIMS" style="width: 18px; margin-right: 8px" />
|
||||||
|
{{ skimState.imsUeNum }}
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
{{ t('views.dashboard.overview.skim.imsUeNum') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="item toRouter"
|
||||||
|
@click="fnToRouter('Ue_2081')"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<img :src="svgUserSMF" style="width: 18px; margin-right: 8px" />
|
||||||
|
{{ skimState.smfUeNum }}
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
{{ t('views.dashboard.overview.skim.smfUeNum') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="skim panel base">
|
||||||
|
<div class="inner">
|
||||||
|
<h3>
|
||||||
|
<GlobalOutlined style="color: #68d8fe" />
|
||||||
|
{{ t('views.dashboard.overview.skim.baseTitle') }}
|
||||||
|
</h3>
|
||||||
|
<div class="data">
|
||||||
|
<div
|
||||||
|
class="item toRouter"
|
||||||
|
@click="fnToRouter('Base5G_2082', { neType: 'AMF' })"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<div style="align-items: flex-start">
|
||||||
|
<img
|
||||||
|
:src="svgBase"
|
||||||
|
style="width: 18px; margin-right: 8px; height: 2rem"
|
||||||
|
/>
|
||||||
|
{{ skimState.gnbNum }}
|
||||||
|
</div>
|
||||||
|
<span>{{ t('views.dashboard.overview.skim.gnbBase') }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="item toRouter"
|
||||||
|
@click="fnToRouter('Base5G_2082', { neType: 'AMF' })"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<div style="align-items: flex-start">
|
||||||
|
<UserOutlined
|
||||||
|
style="color: #4096ff; margin-right: 8px; font-size: 1.1rem"
|
||||||
|
/>
|
||||||
|
{{ skimState.gnbUeNum }}
|
||||||
|
</div>
|
||||||
|
<span>{{ t('views.dashboard.overview.skim.gnbUeNum') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="data">
|
||||||
|
<div
|
||||||
|
class="item toRouter"
|
||||||
|
@click="fnToRouter('Base5G_2082', { neType: 'MME' })"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<div style="align-items: flex-start">
|
||||||
|
<img
|
||||||
|
:src="svgBase"
|
||||||
|
style="width: 18px; margin-right: 8px; height: 2rem"
|
||||||
|
/>
|
||||||
|
{{ skimState.enbNum }}
|
||||||
|
</div>
|
||||||
|
<span>{{ t('views.dashboard.overview.skim.enbBase') }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="item toRouter"
|
||||||
|
@click="fnToRouter('Base5G_2082', { neType: 'MME' })"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<div style="align-items: flex-start">
|
||||||
|
<UserOutlined
|
||||||
|
style="color: #4096ff; margin-right: 8px; font-size: 1.1rem"
|
||||||
|
/>
|
||||||
|
{{ skimState.enbUeNum }}
|
||||||
|
</div>
|
||||||
|
<span>{{ t('views.dashboard.overview.skim.enbUeNum') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 用户行为 -->
|
||||||
|
<div class="userActivity panel">
|
||||||
|
<div class="inner">
|
||||||
|
<h3>
|
||||||
|
<WhatsAppOutlined style="color: #68d8fe" />
|
||||||
|
{{ t('views.dashboard.overview.userActivity.title') }}
|
||||||
|
</h3>
|
||||||
|
<div class="chart">
|
||||||
|
<UserActivity />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column" style="flex: 4; margin: 1.333rem 0.833rem 0">
|
||||||
|
<!-- 实时流量 -->
|
||||||
|
<div class="upfFlow panel">
|
||||||
|
<div class="inner">
|
||||||
|
<h3
|
||||||
|
class="toRouter"
|
||||||
|
@click="fnToRouter('GoldTarget_2104')"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<AreaChartOutlined style="color: #68d8fe" />
|
||||||
|
{{ t('views.dashboard.overview.upfFlow.title') }}
|
||||||
|
</h3>
|
||||||
|
<div class="chart">
|
||||||
|
<UPFFlow />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 网络拓扑 -->
|
||||||
|
<div class="topology panel">
|
||||||
|
<div class="inner">
|
||||||
|
<h3
|
||||||
|
class="toRouter"
|
||||||
|
@click="fnToRouter('TopologyArchitecture_2128')"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<ApartmentOutlined style="color: #68d8fe" />
|
||||||
|
{{ t('views.dashboard.overview.topology.title') }}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{{ t('views.dashboard.overview.topology.normal') }}:
|
||||||
|
<span class="normal"> {{ graphNodeStateNum[0] }} </span>
|
||||||
|
{{ t('views.dashboard.overview.topology.abnormal') }}:
|
||||||
|
<span class="abnormal"> {{ graphNodeStateNum[1] }} </span>
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
<div class="chart">
|
||||||
|
<Topology />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<!-- 流量统计 -->
|
||||||
|
<div class="upfFlowTotal panel">
|
||||||
|
<div class="inner">
|
||||||
|
<h3>
|
||||||
|
<span>
|
||||||
|
<SwapOutlined style="color: #68d8fe" />
|
||||||
|
{{ t('views.dashboard.overview.upfFlowTotal.title') }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 筛选 -->
|
||||||
|
<div class="filter">
|
||||||
|
<span
|
||||||
|
:data-key="v"
|
||||||
|
:class="{ active: upfTFActive === i }"
|
||||||
|
v-for="(v, i) in ['0', '7', '30']"
|
||||||
|
:key="v"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
upfTFActive = i;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
v === '0'
|
||||||
|
? '24' + t('common.units.hour')
|
||||||
|
: v + t('common.units.day')
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</h3>
|
||||||
|
<div class="chart">
|
||||||
|
<!-- 数据 -->
|
||||||
|
<div class="data">
|
||||||
|
<div class="item">
|
||||||
|
<span>
|
||||||
|
<ArrowUpOutlined style="color: #597ef7" />
|
||||||
|
{{ t('views.dashboard.overview.upfFlowTotal.up') }}
|
||||||
|
</span>
|
||||||
|
<h4>{{ upfTotalFlow[upfTFActive].up }}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span>
|
||||||
|
<ArrowDownOutlined style="color: #52c41a" />
|
||||||
|
{{ t('views.dashboard.overview.upfFlowTotal.down') }}
|
||||||
|
</span>
|
||||||
|
<h4>{{ upfTotalFlow[upfTFActive].down }}</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- MOCN -->
|
||||||
|
<div class="skim panel mocn">
|
||||||
|
<div class="inner">
|
||||||
|
<h3
|
||||||
|
class="toRouter"
|
||||||
|
@contextmenu.prevent="fnRightClick()"
|
||||||
|
@click="fnToRouter('GoldTarget_2104', { neType: 'MOCNGW' })"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<PieChartOutlined style="color: #68d8fe" /> MOCN
|
||||||
|
Information
|
||||||
|
</h3>
|
||||||
|
<div class="chart">
|
||||||
|
<div class="data">
|
||||||
|
<div class="item" title="NodeB">
|
||||||
|
<div>
|
||||||
|
<img :src="svgBase" style="width: 18px; margin-right: 8px" />
|
||||||
|
{{ mocnState.data.baseNum }}
|
||||||
|
</div>
|
||||||
|
<span> NodeB </span>
|
||||||
|
</div>
|
||||||
|
<div class="item" title="CoreNet">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
:src="svgUserSMF"
|
||||||
|
style="width: 18px; margin-right: 8px"
|
||||||
|
/>
|
||||||
|
{{ mocnState.data.coreNetNum }}
|
||||||
|
</div>
|
||||||
|
<span> CoreNet </span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="data">
|
||||||
|
<div class="item" title="OnlineUser">
|
||||||
|
<div>
|
||||||
|
<UserOutlined
|
||||||
|
style="color: #4096ff; margin-right: 8px; font-size: 1.1rem"
|
||||||
|
/>
|
||||||
|
{{ mocnState.data.onlineUserNum }}
|
||||||
|
</div>
|
||||||
|
<span> OnlineUser </span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 告警统计 -->
|
||||||
|
<div class="alarmType panel">
|
||||||
|
<div class="inner">
|
||||||
|
<h3
|
||||||
|
class="toRouter"
|
||||||
|
@click="fnToRouter('HistoryAlarm_2097')"
|
||||||
|
:title="t('views.dashboard.overview.toRouter')"
|
||||||
|
>
|
||||||
|
<PieChartOutlined style="color: #68d8fe" />
|
||||||
|
{{ t('views.dashboard.overview.alarmTypeBar.alarmSum') }}
|
||||||
|
</h3>
|
||||||
|
<div class="chart">
|
||||||
|
<AlarnTypeBar />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 资源情况 -->
|
||||||
|
<div class="resources panel">
|
||||||
|
<div class="inner">
|
||||||
|
<h3>
|
||||||
|
<DashboardOutlined style="color: #68d8fe" />
|
||||||
|
{{ t('views.dashboard.overview.resources.title') }}:
|
||||||
|
{{ graphNodeClickID }}
|
||||||
|
</h3>
|
||||||
|
<div class="chart">
|
||||||
|
<NeResources />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<setting
|
||||||
|
:title="mocnState.title"
|
||||||
|
v-model:visible="mocnState.visible"
|
||||||
|
></setting>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@import url('../overview/css/index.css');
|
||||||
|
|
||||||
|
.mocn {
|
||||||
|
height: 20.6%;
|
||||||
|
}
|
||||||
|
.mocn .inner .chart .data {
|
||||||
|
height: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mocn .inner .chart .data .item {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alarmType {
|
||||||
|
height: 24.4%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -70,10 +70,10 @@ const alarmTypeType = ref<any>([
|
|||||||
value: 0,
|
value: 0,
|
||||||
name: t('views.index.Warning'),
|
name: t('views.index.Warning'),
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
value: 0,
|
// value: 0,
|
||||||
name: t('views.index.Event'),
|
// name: t('views.index.Event'),
|
||||||
},
|
// },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**告警类型Top数据 */
|
/**告警类型Top数据 */
|
||||||
@@ -105,9 +105,9 @@ function initPicture() {
|
|||||||
case 'Warning':
|
case 'Warning':
|
||||||
index = 3;
|
index = 3;
|
||||||
break;
|
break;
|
||||||
case 'Event':
|
// case 'Event':
|
||||||
index = 4;
|
// index = 4;
|
||||||
break;
|
// break;
|
||||||
}
|
}
|
||||||
alarmTypeType.value[index].value = Number(item.value);
|
alarmTypeType.value[index].value = Number(item.value);
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ function initPicture() {
|
|||||||
legend: {
|
legend: {
|
||||||
orient: 'vertical',
|
orient: 'vertical',
|
||||||
right: '2%',
|
right: '2%',
|
||||||
top: '10%',
|
top: '12%',
|
||||||
data: alarmTypeType.value.map((item: any) => item.name), //label数组
|
data: alarmTypeType.value.map((item: any) => item.name), //label数组
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: '#A7D6F4', // 设置图例文字颜色
|
color: '#A7D6F4', // 设置图例文字颜色
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ function fnGraphEvent(graph: Graph) {
|
|||||||
// 节点点击
|
// 节点点击
|
||||||
graph.on('node:click', evt => {
|
graph.on('node:click', evt => {
|
||||||
// 获得鼠标当前目标节点
|
// 获得鼠标当前目标节点
|
||||||
const node = evt.item?.getModel();
|
const node = evt.item?.getModel();
|
||||||
if (node && node.id && !notNeNodes.includes(node.id)) {
|
if (node && node.id && !notNeNodes.includes(node.id)) {
|
||||||
graphNodeClickID.value = node.id;
|
graphNodeClickID.value = node.id;
|
||||||
}
|
}
|
||||||
@@ -129,6 +129,9 @@ function handleRanderGraph(
|
|||||||
var observer = new ResizeObserver(function (entries) {
|
var observer = new ResizeObserver(function (entries) {
|
||||||
// 当元素大小发生变化时触发回调函数
|
// 当元素大小发生变化时触发回调函数
|
||||||
entries.forEach(function (entry) {
|
entries.forEach(function (entry) {
|
||||||
|
if (!graphG6.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
graphG6.value.changeSize(
|
graphG6.value.changeSize(
|
||||||
entry.contentRect.width,
|
entry.contentRect.width,
|
||||||
entry.contentRect.height - 30
|
entry.contentRect.height - 30
|
||||||
|
|||||||
@@ -221,7 +221,7 @@
|
|||||||
.upfFlowTotal .inner .chart {
|
.upfFlowTotal .inner .chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin-top: 1rem;
|
margin-top: 0.1rem;
|
||||||
}
|
}
|
||||||
.upfFlowTotal .inner .chart .data {
|
.upfFlowTotal .inner .chart .data {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -158,3 +158,15 @@ export function neStateParse(neType: string, data: Record<string, any>) {
|
|||||||
// 请求标记复位
|
// 请求标记复位
|
||||||
neStateRequestMap.value.set(neType, false);
|
neStateRequestMap.value.set(neType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**属性复位 */
|
||||||
|
export function topologyReset() {
|
||||||
|
graphState.data = {
|
||||||
|
combos: [],
|
||||||
|
edges: [],
|
||||||
|
nodes: [],
|
||||||
|
};
|
||||||
|
graphG6.value = null;
|
||||||
|
graphNodeClickID.value = 'UPF';
|
||||||
|
neStateRequestMap.value = new Map();
|
||||||
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
import { parseSizeFromBits, parseSizeFromKbs } from '@/utils/parse-utils';
|
import { parseSizeFromBits, parseSizeFromKbs } from '@/utils/parse-utils';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
/**UPF-流量数据 */
|
type FDType = {
|
||||||
export const upfFlowData = ref<{
|
|
||||||
/**时间 */
|
/**时间 */
|
||||||
lineXTime: string[];
|
lineXTime: string[];
|
||||||
/**上行 N3 */
|
/**上行 N3 */
|
||||||
@@ -11,7 +10,10 @@ export const upfFlowData = ref<{
|
|||||||
lineYDown: number[];
|
lineYDown: number[];
|
||||||
/**容量 */
|
/**容量 */
|
||||||
cap: number;
|
cap: number;
|
||||||
}>({
|
};
|
||||||
|
|
||||||
|
/**UPF-流量数据 */
|
||||||
|
export const upfFlowData = ref<FDType>({
|
||||||
lineXTime: [],
|
lineXTime: [],
|
||||||
lineYUp: [],
|
lineYUp: [],
|
||||||
lineYDown: [],
|
lineYDown: [],
|
||||||
@@ -74,3 +76,32 @@ export function upfTFParse(data: Record<string, string>) {
|
|||||||
|
|
||||||
/**UPF-总流量数 选中 */
|
/**UPF-总流量数 选中 */
|
||||||
export const upfTFActive = ref<number>(0);
|
export const upfTFActive = ref<number>(0);
|
||||||
|
|
||||||
|
/**属性复位 */
|
||||||
|
export function upfTotalFlowReset() {
|
||||||
|
upfFlowData.value = {
|
||||||
|
lineXTime: [],
|
||||||
|
lineYUp: [],
|
||||||
|
lineYDown: [],
|
||||||
|
cap: 0,
|
||||||
|
};
|
||||||
|
upfTotalFlow.value = [
|
||||||
|
// 0天 当天24小时
|
||||||
|
{
|
||||||
|
up: '0 B',
|
||||||
|
down: '0 B',
|
||||||
|
requestFlag: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
up: '0 B',
|
||||||
|
down: '0 B',
|
||||||
|
requestFlag: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
up: '0 B',
|
||||||
|
down: '0 B',
|
||||||
|
requestFlag: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
upfTFActive.value = 0;
|
||||||
|
}
|
||||||
@@ -1,14 +1,5 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
/**UE事件数据 */
|
|
||||||
export const ueEventData = ref<Record<string, any>[]>([]);
|
|
||||||
|
|
||||||
/**UE事件总量 */
|
|
||||||
export const ueEventTotal = ref<number>(0);
|
|
||||||
|
|
||||||
/**UE事件推送id */
|
|
||||||
export const ueEventId = ref<string>('');
|
|
||||||
|
|
||||||
/**ueEvent UE会话事件 数据解析 */
|
/**ueEvent UE会话事件 数据解析 */
|
||||||
export function ueEventParse(item: Record<string, any>) {
|
export function ueEventParse(item: Record<string, any>) {
|
||||||
let evData: Record<string, any> = item.eventJSON;
|
let evData: Record<string, any> = item.eventJSON;
|
||||||
@@ -23,21 +14,13 @@ export function ueEventParse(item: Record<string, any>) {
|
|||||||
return {
|
return {
|
||||||
eType: 'ue',
|
eType: 'ue',
|
||||||
eId: `ue_${item.id}_${Date.now()}`,
|
eId: `ue_${item.id}_${Date.now()}`,
|
||||||
|
eTime: +item.timestamp,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
type: item.eventType,
|
type: item.eventType,
|
||||||
data: evData,
|
data: evData,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**CDR事件数据 */
|
|
||||||
export const cdrEventData = ref<Record<string, any>[]>([]);
|
|
||||||
|
|
||||||
/**CDR事件总量 */
|
|
||||||
export const cdrEventTotal = ref<number>(0);
|
|
||||||
|
|
||||||
/**CDR事件推送id */
|
|
||||||
export const cdrEventId = ref<string>('');
|
|
||||||
|
|
||||||
/**cdrEvent CDR会话事件 数据解析 */
|
/**cdrEvent CDR会话事件 数据解析 */
|
||||||
export function cdrEventParse(item: Record<string, any>) {
|
export function cdrEventParse(item: Record<string, any>) {
|
||||||
let evData: Record<string, any> = item.cdrJSON || item.CDR;
|
let evData: Record<string, any> = item.cdrJSON || item.CDR;
|
||||||
@@ -58,6 +41,7 @@ export function cdrEventParse(item: Record<string, any>) {
|
|||||||
return {
|
return {
|
||||||
eType: 'cdr',
|
eType: 'cdr',
|
||||||
eId: `cdr_${item.id}_${Date.now()}`,
|
eId: `cdr_${item.id}_${Date.now()}`,
|
||||||
|
eTime: +item.timestamp,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
data: evData,
|
data: evData,
|
||||||
};
|
};
|
||||||
@@ -69,3 +53,10 @@ export const eventData = ref<Record<string, any>[]>([]);
|
|||||||
export const eventTotal = ref<number>(0);
|
export const eventTotal = ref<number>(0);
|
||||||
/**CDR/UE事件推送id */
|
/**CDR/UE事件推送id */
|
||||||
export const eventId = ref<string>('');
|
export const eventId = ref<string>('');
|
||||||
|
|
||||||
|
/**属性复位 */
|
||||||
|
export function userActivityReset() {
|
||||||
|
eventData.value = [];
|
||||||
|
eventTotal.value = 0;
|
||||||
|
eventId.value = '';
|
||||||
|
}
|
||||||
@@ -7,9 +7,15 @@ import {
|
|||||||
eventData,
|
eventData,
|
||||||
eventTotal,
|
eventTotal,
|
||||||
eventId,
|
eventId,
|
||||||
|
userActivityReset,
|
||||||
} from './useUserActivity';
|
} from './useUserActivity';
|
||||||
import { upfTotalFlow, upfTFParse, upfFlowParse } from './useUPFTotalFlow';
|
import {
|
||||||
import { neStateParse } from './useTopology';
|
upfTotalFlow,
|
||||||
|
upfTFParse,
|
||||||
|
upfFlowParse,
|
||||||
|
upfTotalFlowReset,
|
||||||
|
} from './useUPFTotalFlow';
|
||||||
|
import { topologyReset, neStateParse } from './useTopology';
|
||||||
import PQueue from 'p-queue';
|
import PQueue from 'p-queue';
|
||||||
|
|
||||||
/**websocket连接 */
|
/**websocket连接 */
|
||||||
@@ -56,6 +62,11 @@ export default function useWS() {
|
|||||||
eventData.value.push(v);
|
eventData.value.push(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 有数据进行排序
|
||||||
|
if (eventData.value.length > 10) {
|
||||||
|
eventData.value.sort((a, b) => b.eTime - a.eTime);
|
||||||
|
}
|
||||||
if (eventData.value.length > 0) {
|
if (eventData.value.length > 0) {
|
||||||
eventId.value = eventData.value[0].eId;
|
eventId.value = eventData.value[0].eId;
|
||||||
}
|
}
|
||||||
@@ -71,6 +82,11 @@ export default function useWS() {
|
|||||||
eventData.value.push(v);
|
eventData.value.push(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 有数据进行排序
|
||||||
|
if (eventData.value.length > 10) {
|
||||||
|
eventData.value.sort((a, b) => b.eTime - a.eTime);
|
||||||
|
}
|
||||||
if (eventData.value.length > 0) {
|
if (eventData.value.length > 0) {
|
||||||
eventId.value = eventData.value[0].eId;
|
eventId.value = eventData.value[0].eId;
|
||||||
}
|
}
|
||||||
@@ -225,6 +241,9 @@ export default function useWS() {
|
|||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
ws.close();
|
ws.close();
|
||||||
|
userActivityReset();
|
||||||
|
upfTotalFlowReset();
|
||||||
|
topologyReset();
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ function loadData() {
|
|||||||
upfTFSend(7);
|
upfTFSend(7);
|
||||||
upfTFSend(30);
|
upfTFSend(30);
|
||||||
|
|
||||||
|
clearInterval(interval10s.value);
|
||||||
interval10s.value = setInterval(() => {
|
interval10s.value = setInterval(() => {
|
||||||
upfTFActive.value = upfTFActive.value >= 2 ? 0 : upfTFActive.value + 1;
|
upfTFActive.value = upfTFActive.value >= 2 ? 0 : upfTFActive.value + 1;
|
||||||
if (upfTFActive.value === 0) {
|
if (upfTFActive.value === 0) {
|
||||||
@@ -172,6 +173,7 @@ function loadData() {
|
|||||||
}
|
}
|
||||||
}, 10_000);
|
}, 10_000);
|
||||||
|
|
||||||
|
clearInterval(interval5s.value);
|
||||||
interval5s.value = setInterval(() => {
|
interval5s.value = setInterval(() => {
|
||||||
fnGetSkim(); // 获取概览信息
|
fnGetSkim(); // 获取概览信息
|
||||||
fnGetNeState(); // 获取网元状态
|
fnGetNeState(); // 获取网元状态
|
||||||
@@ -191,7 +193,9 @@ onMounted(() => {
|
|||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
clearInterval(interval10s.value);
|
clearInterval(interval10s.value);
|
||||||
|
interval10s.value = null;
|
||||||
clearInterval(interval5s.value);
|
clearInterval(interval5s.value);
|
||||||
|
interval5s.value = null;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,858 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref, onMounted, toRaw } from 'vue';
|
||||||
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
|
import { message, Modal } from 'ant-design-vue/lib';
|
||||||
|
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||||
|
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
||||||
|
import { ColumnsType } from 'ant-design-vue/lib/table';
|
||||||
|
import { listAct, exportAll } from '@/api/faultManage/eventAlarm';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import useDictStore from '@/store/modules/dict';
|
||||||
|
import saveAs from 'file-saver';
|
||||||
|
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
|
||||||
|
import { writeSheet } from '@/utils/execl-utils';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { readLoalXlsx } from '@/utils/execl-utils';
|
||||||
|
const { getDict } = useDictStore();
|
||||||
|
const { t, currentLocale } = useI18n();
|
||||||
|
|
||||||
|
/**字典数据 */
|
||||||
|
let dict: {
|
||||||
|
/**活动告警类型 */
|
||||||
|
activeAlarmType: DictType[];
|
||||||
|
/**告警清除类型 */
|
||||||
|
activeClearType: DictType[];
|
||||||
|
/**告警清除类型 */
|
||||||
|
activeAckState: DictType[];
|
||||||
|
/**原始严重程度 */
|
||||||
|
activeAlarmSeverity: DictType[];
|
||||||
|
} = reactive({
|
||||||
|
activeAlarmType: [],
|
||||||
|
activeClearType: [],
|
||||||
|
activeAckState: [],
|
||||||
|
activeAlarmSeverity: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格字段列排序 */
|
||||||
|
let tableColumnsDnd = ref<ColumnsType>([]);
|
||||||
|
|
||||||
|
/**记录开始结束时间 */
|
||||||
|
let queryRangePicker = ref<[string, string]>(['', '']);
|
||||||
|
|
||||||
|
/**查询参数 */
|
||||||
|
let queryParams = reactive({
|
||||||
|
/**告警设备类型 */
|
||||||
|
neType: '',
|
||||||
|
/**告警网元名称 */
|
||||||
|
neName: '',
|
||||||
|
/**告警网元标识 */
|
||||||
|
neId: '',
|
||||||
|
/**告警编号 */
|
||||||
|
alarmCode: '',
|
||||||
|
/**告警级别 */
|
||||||
|
origSeverity: undefined,
|
||||||
|
beginTime: '',
|
||||||
|
endTime: '',
|
||||||
|
/**告警产生时间 */
|
||||||
|
eventTime: '',
|
||||||
|
/**虚拟化标识 */
|
||||||
|
pvFlag: undefined,
|
||||||
|
/**告警类型 */
|
||||||
|
alarmType: undefined,
|
||||||
|
/**当前页数 */
|
||||||
|
pageNum: 1,
|
||||||
|
/**每页条数 */
|
||||||
|
pageSize: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**查询参数重置 */
|
||||||
|
function fnQueryReset() {
|
||||||
|
queryParams = Object.assign(queryParams, {
|
||||||
|
/**告警设备类型 */
|
||||||
|
neType: '',
|
||||||
|
/**告警网元名称 */
|
||||||
|
neName: '',
|
||||||
|
/**告警网元标识 */
|
||||||
|
neId: '',
|
||||||
|
/**告警编号 */
|
||||||
|
alarmCode: '',
|
||||||
|
/**告警级别 */
|
||||||
|
origSeverity: undefined,
|
||||||
|
/**告警产生时间 */
|
||||||
|
eventTime: '',
|
||||||
|
/**虚拟化标识 */
|
||||||
|
pvFlag: undefined,
|
||||||
|
/**告警类型 */
|
||||||
|
alarmType: undefined,
|
||||||
|
/**当前页数 */
|
||||||
|
});
|
||||||
|
tablePagination.current = 1;
|
||||||
|
tablePagination.pageSize = 20;
|
||||||
|
fnGetList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格状态类型 */
|
||||||
|
type TabeStateType = {
|
||||||
|
/**加载等待 */
|
||||||
|
loading: boolean;
|
||||||
|
/**紧凑型 */
|
||||||
|
size: SizeType;
|
||||||
|
/**搜索栏 */
|
||||||
|
seached: boolean;
|
||||||
|
/**记录数据 */
|
||||||
|
data: object[];
|
||||||
|
/**勾选记录 */
|
||||||
|
selectedRowKeys: (string | number)[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**表格状态 */
|
||||||
|
let tableState: TabeStateType = reactive({
|
||||||
|
loading: false,
|
||||||
|
size: 'middle',
|
||||||
|
seached: false,
|
||||||
|
data: [],
|
||||||
|
selectedRowKeys: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格字段列 */
|
||||||
|
let tableColumns: ColumnsType = [
|
||||||
|
{
|
||||||
|
title: t('views.faultManage.activeAlarm.alarmId'),
|
||||||
|
dataIndex: 'alarmId',
|
||||||
|
align: 'center',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.faultManage.activeAlarm.neId'),
|
||||||
|
dataIndex: 'neId',
|
||||||
|
align: 'center',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.faultManage.activeAlarm.neName'),
|
||||||
|
dataIndex: 'neName',
|
||||||
|
align: 'center',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.faultManage.activeAlarm.neType'),
|
||||||
|
dataIndex: 'neType',
|
||||||
|
align: 'center',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.faultManage.activeAlarm.alarmCode'),
|
||||||
|
dataIndex: 'alarmCode',
|
||||||
|
align: 'center',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.faultManage.activeAlarm.alarmTitle'),
|
||||||
|
dataIndex: 'alarmTitle',
|
||||||
|
align: 'left',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.faultManage.activeAlarm.eventTime'),
|
||||||
|
dataIndex: 'eventTime',
|
||||||
|
align: 'center',
|
||||||
|
sorter: (a: any, b: any) => 1,
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.faultManage.activeAlarm.pvFlag'),
|
||||||
|
dataIndex: 'pvFlag',
|
||||||
|
align: 'center',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('common.operate'),
|
||||||
|
key: 'alarm_id',
|
||||||
|
align: 'center',
|
||||||
|
fixed: 'right',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**表格分页器参数 */
|
||||||
|
let tablePagination = reactive({
|
||||||
|
/**当前页数 */
|
||||||
|
current: 1,
|
||||||
|
/**每页条数 */
|
||||||
|
pageSize: 20,
|
||||||
|
/**默认的每页条数 */
|
||||||
|
defaultPageSize: 20,
|
||||||
|
/**指定每页可以显示多少条 */
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100'],
|
||||||
|
/**只有一页时是否隐藏分页器 */
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
/**是否可以快速跳转至某页 */
|
||||||
|
showQuickJumper: true,
|
||||||
|
/**是否可以改变 pageSize */
|
||||||
|
showSizeChanger: true,
|
||||||
|
/**数据总数 */
|
||||||
|
total: 0,
|
||||||
|
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
|
||||||
|
onChange: (page: number, pageSize: number) => {
|
||||||
|
tablePagination.current = page;
|
||||||
|
tablePagination.pageSize = pageSize;
|
||||||
|
queryParams.pageNum = page;
|
||||||
|
queryParams.pageSize = pageSize;
|
||||||
|
fnGetList();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格紧凑型变更操作 */
|
||||||
|
function fnTableSize({ key }: MenuInfo) {
|
||||||
|
tableState.size = key as SizeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**详情框是否显示 */
|
||||||
|
visibleByView: boolean;
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
visibleByEdit: boolean;
|
||||||
|
/**显示过滤设置是否显示 */
|
||||||
|
visibleByShowSet: boolean;
|
||||||
|
/**个性化设置置是否显示 */
|
||||||
|
visibleByMyselfSet: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: Record<string, any>;
|
||||||
|
/**表单数据 */
|
||||||
|
showSetFrom: Record<string, any>;
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
visibleByView: false,
|
||||||
|
visibleByEdit: false,
|
||||||
|
visibleByShowSet: false,
|
||||||
|
visibleByMyselfSet: false,
|
||||||
|
title: '全部信息',
|
||||||
|
from: {
|
||||||
|
alarmId: '',
|
||||||
|
alarmSeq: '',
|
||||||
|
neId: '',
|
||||||
|
neName: '',
|
||||||
|
neType: '',
|
||||||
|
alarmCode: '',
|
||||||
|
alarmTitle: '',
|
||||||
|
eventTime: '',
|
||||||
|
alarmType: '',
|
||||||
|
pvFlag: '',
|
||||||
|
objectName: '',
|
||||||
|
locationInfo: '',
|
||||||
|
province: '',
|
||||||
|
alarmStatus: '',
|
||||||
|
specificProblemId: '',
|
||||||
|
specificProblem: '',
|
||||||
|
addInfo: '',
|
||||||
|
clearType: '',
|
||||||
|
clearTime: '',
|
||||||
|
ackState: '',
|
||||||
|
ackUser: '',
|
||||||
|
ackTime: '',
|
||||||
|
origSeverity: '',
|
||||||
|
},
|
||||||
|
showSetFrom: {
|
||||||
|
ne_type: '',
|
||||||
|
ne_id: '',
|
||||||
|
alarm_type: '',
|
||||||
|
orig_severity: '',
|
||||||
|
alarm_code: '',
|
||||||
|
pv_flag: '',
|
||||||
|
},
|
||||||
|
// myselfSetFrom:{
|
||||||
|
|
||||||
|
// }
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 查看
|
||||||
|
* @param row 单行记录信息
|
||||||
|
*/
|
||||||
|
function fnModalVisibleByVive(row: Record<string, any>) {
|
||||||
|
modalState.from = Object.assign(modalState.from, row);
|
||||||
|
modalState.from.clearType = `${modalState.from.clearType}`;
|
||||||
|
modalState.from.ackState = `${modalState.from.ackState}`;
|
||||||
|
modalState.title = t('views.faultManage.activeAlarm.viewIdInfo', {
|
||||||
|
alarmId: row.alarmId,
|
||||||
|
});
|
||||||
|
modalState.visibleByView = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格状态 */
|
||||||
|
const state = reactive<{
|
||||||
|
selectedRowKeys: (string | number)[];
|
||||||
|
selectedRow: Record<string, any>;
|
||||||
|
loading: boolean;
|
||||||
|
}>({
|
||||||
|
selectedRowKeys: [], // Check here to configure the default column
|
||||||
|
selectedRow: {},
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**监听多选 */
|
||||||
|
const onSelectChange = (
|
||||||
|
keys: (string | number)[],
|
||||||
|
record: Record<string, any>
|
||||||
|
) => {
|
||||||
|
state.selectedRowKeys = keys;
|
||||||
|
state.selectedRow = record;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出全部
|
||||||
|
*/
|
||||||
|
function fnExportAll() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: 'Tip',
|
||||||
|
content: t('views.faultManage.eventAlarm.exportSure'),
|
||||||
|
onOk() {
|
||||||
|
const key = 'exportAlarm';
|
||||||
|
message.loading({ content: t('common.loading'), key });
|
||||||
|
let sortArr: any = [];
|
||||||
|
tableColumnsDnd.value.forEach((item: any) => {
|
||||||
|
if (item.dataIndex) sortArr.push(item.dataIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 排序字段
|
||||||
|
const sortData = {
|
||||||
|
header: sortArr,
|
||||||
|
};
|
||||||
|
|
||||||
|
exportAll(queryParams).then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
res.data = res.data.map((objA: any) => {
|
||||||
|
let filteredObj: any = {};
|
||||||
|
sortArr.forEach((key: any) => {
|
||||||
|
if (objA.hasOwnProperty(key)) {
|
||||||
|
filteredObj[key] = objA[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dict.activeAckState.map((item: any) => {
|
||||||
|
if (item.value === `${filteredObj.ackState}`)
|
||||||
|
filteredObj.ackState = item.label;
|
||||||
|
});
|
||||||
|
|
||||||
|
return filteredObj;
|
||||||
|
});
|
||||||
|
message.success({
|
||||||
|
content: t('common.msgSuccess', { msg: t('common.export') }),
|
||||||
|
key,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
writeSheet(res.data, 'alarm', sortData).then(fileBlob =>
|
||||||
|
saveAs(fileBlob, `evnet_${Date.now()}.xlsx`)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
key,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.visibleByEdit = false;
|
||||||
|
modalState.visibleByView = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**查询列表, pageNum初始页数 */
|
||||||
|
function fnGetList(pageNum?: number) {
|
||||||
|
if (tableState.loading) return;
|
||||||
|
tableState.loading = true;
|
||||||
|
if (pageNum) {
|
||||||
|
queryParams.pageNum = pageNum;
|
||||||
|
}
|
||||||
|
if (!queryRangePicker.value) {
|
||||||
|
queryRangePicker.value = ['', ''];
|
||||||
|
}
|
||||||
|
queryParams.beginTime = queryRangePicker.value[0];
|
||||||
|
queryParams.endTime = queryRangePicker.value[1];
|
||||||
|
|
||||||
|
listAct(toRaw(queryParams)).then((res: any) => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
||||||
|
// 取消勾选
|
||||||
|
if (state.selectedRowKeys.length > 0) {
|
||||||
|
state.selectedRowKeys = [];
|
||||||
|
}
|
||||||
|
////
|
||||||
|
tablePagination.total = res.total;
|
||||||
|
tableState.data = res.rows;
|
||||||
|
if (
|
||||||
|
tablePagination.total <=
|
||||||
|
(queryParams.pageNum - 1) * tablePagination.pageSize &&
|
||||||
|
queryParams.pageNum !== 1
|
||||||
|
) {
|
||||||
|
tableState.loading = false;
|
||||||
|
fnGetList(queryParams.pageNum - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tablePagination.total = 0;
|
||||||
|
tableState.data = [];
|
||||||
|
}
|
||||||
|
tableState.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始字典数据
|
||||||
|
Promise.allSettled([
|
||||||
|
getDict('active_alarm_type'),
|
||||||
|
getDict('active_clear_type'),
|
||||||
|
getDict('active_ack_state'),
|
||||||
|
getDict('active_alarm_severity'),
|
||||||
|
]).then(resArr => {
|
||||||
|
if (resArr[0].status === 'fulfilled') {
|
||||||
|
dict.activeAlarmType = resArr[0].value;
|
||||||
|
}
|
||||||
|
if (resArr[1].status === 'fulfilled') {
|
||||||
|
dict.activeClearType = resArr[1].value;
|
||||||
|
}
|
||||||
|
if (resArr[2].status === 'fulfilled') {
|
||||||
|
dict.activeAckState = resArr[2].value;
|
||||||
|
}
|
||||||
|
if (resArr[3].status === 'fulfilled') {
|
||||||
|
dict.activeAlarmSeverity = resArr[3].value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fnGetList();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PageContainer>
|
||||||
|
<a-card
|
||||||
|
v-show="tableState.seached"
|
||||||
|
:bordered="false"
|
||||||
|
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
||||||
|
>
|
||||||
|
<!-- 表格搜索栏 -->
|
||||||
|
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.neType')"
|
||||||
|
name="ne_type"
|
||||||
|
>
|
||||||
|
<a-input v-model:value="queryParams.neType" allow-clear></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.neName')"
|
||||||
|
name="ne_name"
|
||||||
|
>
|
||||||
|
<a-input v-model:value="queryParams.neName" allow-clear></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.neId')"
|
||||||
|
name="ne_id"
|
||||||
|
>
|
||||||
|
<a-input v-model:value="queryParams.neId" allow-clear></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item>
|
||||||
|
<a-space :size="8">
|
||||||
|
<a-button type="primary" @click.prevent="fnGetList(1)">
|
||||||
|
<template #icon><SearchOutlined /></template>
|
||||||
|
{{ t('common.search') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="default" @click.prevent="fnQueryReset">
|
||||||
|
<template #icon><ClearOutlined /></template>
|
||||||
|
{{ t('common.reset') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.alarmCode')"
|
||||||
|
name="alarm_code"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="queryParams.alarmCode"
|
||||||
|
allow-clear
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.pvFlag')"
|
||||||
|
name="pv_flag"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="queryParams.pvFlag"
|
||||||
|
:placeholder="t('common.selectPlease')"
|
||||||
|
:options="[
|
||||||
|
{ label: 'PNF', value: 'PNF' },
|
||||||
|
{ label: 'VNF', value: 'VNF' },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.eventTime')"
|
||||||
|
name="eventTime"
|
||||||
|
>
|
||||||
|
<a-range-picker
|
||||||
|
v-model:value="queryRangePicker"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
show-time
|
||||||
|
style="width: 400px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.alarmType')"
|
||||||
|
name="alarm_type"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="queryParams.alarmType"
|
||||||
|
:placeholder="t('common.selectPlease')"
|
||||||
|
:options="dict.activeAlarmType"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||||
|
<!-- 插槽-卡片左侧侧 -->
|
||||||
|
<template #title>
|
||||||
|
<div class="button-container">
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click.prevent="fnExportAll()"
|
||||||
|
:disabled="tableState.data.length <= 0"
|
||||||
|
>
|
||||||
|
<template #icon> <export-outlined /> </template>
|
||||||
|
{{ t('views.faultManage.activeAlarm.exportAll') }}
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 插槽-卡片右侧 -->
|
||||||
|
<template #extra>
|
||||||
|
<div class="button-container">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.searchBarText') }}</template>
|
||||||
|
<a-switch
|
||||||
|
v-model:checked="tableState.seached"
|
||||||
|
:checked-children="t('common.switch.show')"
|
||||||
|
:un-checked-children="t('common.switch.hide')"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
|
<template #icon><ReloadOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.sizeText') }}</template>
|
||||||
|
<a-dropdown trigger="click">
|
||||||
|
<a-button type="text">
|
||||||
|
<template #icon><ColumnHeightOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu
|
||||||
|
:selected-keys="[tableState.size as string]"
|
||||||
|
@click="fnTableSize"
|
||||||
|
>
|
||||||
|
<a-menu-item key="default">
|
||||||
|
{{ t('common.size.default') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="middle">
|
||||||
|
{{ t('common.size.middle') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="small">
|
||||||
|
{{ t('common.size.small') }}
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</a-tooltip>
|
||||||
|
<TableColumnsDnd
|
||||||
|
cache-id="alarmActive"
|
||||||
|
:columns="tableColumns"
|
||||||
|
v-model:columns-dnd="tableColumnsDnd"
|
||||||
|
></TableColumnsDnd>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 表格列表 -->
|
||||||
|
<a-table
|
||||||
|
class="table"
|
||||||
|
row-key="id"
|
||||||
|
:columns="tableColumnsDnd"
|
||||||
|
:loading="tableState.loading"
|
||||||
|
:data-source="tableState.data"
|
||||||
|
:size="tableState.size"
|
||||||
|
:row-selection="{
|
||||||
|
columnWidth: 2,
|
||||||
|
selectedRowKeys: state.selectedRowKeys,
|
||||||
|
onChange: onSelectChange,
|
||||||
|
}"
|
||||||
|
:pagination="tablePagination"
|
||||||
|
:scroll="{ x: 2500, y: 400 }"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'origSeverity'">
|
||||||
|
<DictTag
|
||||||
|
:options="dict.activeAlarmSeverity"
|
||||||
|
:value="record.origSeverity"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'alarmType'">
|
||||||
|
<DictTag
|
||||||
|
:options="dict.activeAlarmType"
|
||||||
|
:value="record.alarmType"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'clearType'">
|
||||||
|
<DictTag
|
||||||
|
:options="dict.activeClearType"
|
||||||
|
:value="record.clearType"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'ackState'">
|
||||||
|
<DictTag :options="dict.activeAckState" :value="record.ackState" />
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'alarm_id'">
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.viewText') }}</template>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click.prevent="fnModalVisibleByVive(record)"
|
||||||
|
>
|
||||||
|
<template #icon><InfoCircleOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 详情框 -->
|
||||||
|
<a-modal
|
||||||
|
width="800px"
|
||||||
|
:body-style="{ height: '520px', overflowY: 'scroll' }"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:visible="modalState.visibleByView"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<template v-slot:footer>
|
||||||
|
<a-button @click="fnModalCancel">{{
|
||||||
|
t('views.faultManage.activeAlarm.closeModal')
|
||||||
|
}}</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 8 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.alarmId')"
|
||||||
|
name="alarmId"
|
||||||
|
>
|
||||||
|
{{ modalState.from.alarmId }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.alarmSeq')"
|
||||||
|
name="alarmSeq"
|
||||||
|
>
|
||||||
|
{{ modalState.from.alarmSeq }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.neId')"
|
||||||
|
name="neId"
|
||||||
|
>
|
||||||
|
{{ modalState.from.neId }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.neName')"
|
||||||
|
name="neName"
|
||||||
|
>
|
||||||
|
{{ modalState.from.neName }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.neType')"
|
||||||
|
name="neType"
|
||||||
|
>
|
||||||
|
{{ modalState.from.neType }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.alarmCode')"
|
||||||
|
name="alarmCode"
|
||||||
|
>
|
||||||
|
{{ modalState.from.alarmCode }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.alarmTitle')"
|
||||||
|
name="alarmTitle"
|
||||||
|
>
|
||||||
|
{{ modalState.from.alarmTitle }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.eventTime')"
|
||||||
|
name="eventTime"
|
||||||
|
>
|
||||||
|
{{ modalState.from.eventTime }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.locationInfo')"
|
||||||
|
name="locationInfo"
|
||||||
|
:label-col="{ span: 4 }"
|
||||||
|
>
|
||||||
|
{{ modalState.from.locationInfo }}
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-row :gutter="16"> </a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.province')"
|
||||||
|
name="province"
|
||||||
|
>
|
||||||
|
{{ modalState.from.province }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.alarmType')"
|
||||||
|
name="alarmType"
|
||||||
|
>
|
||||||
|
{{ modalState.from.alarmType }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.addInfo')"
|
||||||
|
name="addInfo"
|
||||||
|
:label-col="{ span: 4 }"
|
||||||
|
>
|
||||||
|
{{ modalState.from.addInfo }}
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.specificProblemId')"
|
||||||
|
name="specificProblemId"
|
||||||
|
>
|
||||||
|
{{ modalState.from.specificProblemId }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.objectName')"
|
||||||
|
name="objectName"
|
||||||
|
>
|
||||||
|
{{ modalState.from.objectName }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.faultManage.activeAlarm.specificProblem')"
|
||||||
|
name="specificProblem"
|
||||||
|
:label-col="{ span: 4 }"
|
||||||
|
>
|
||||||
|
{{ modalState.from.specificProblem }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</PageContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.table :deep(.ant-pagination) {
|
||||||
|
padding: 0 24px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.full-modal {
|
||||||
|
.ant-modal {
|
||||||
|
max-width: 100%;
|
||||||
|
top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.ant-modal-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: calc(100vh);
|
||||||
|
}
|
||||||
|
.ant-modal-body {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+45
-28
@@ -2,7 +2,7 @@
|
|||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import { ColumnsType } from 'ant-design-vue/lib/table';
|
import { ColumnsType } from 'ant-design-vue/lib/table';
|
||||||
import { message } from 'ant-design-vue/lib';
|
import { message } from 'ant-design-vue/lib';
|
||||||
import { reactive, toRaw, ref, onMounted, onBeforeUnmount } from 'vue';
|
import { reactive, toRaw, ref, onMounted, onBeforeUnmount, markRaw } from 'vue';
|
||||||
import { listMain } from '@/api/index';
|
import { listMain } from '@/api/index';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
import { TooltipComponent } from 'echarts/components';
|
import { TooltipComponent } from 'echarts/components';
|
||||||
@@ -30,6 +30,12 @@ echarts.use([
|
|||||||
LabelLayout,
|
LabelLayout,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
/**图DOM节点实例对象 */
|
||||||
|
const statusBar = ref<HTMLElement | undefined>(undefined);
|
||||||
|
|
||||||
|
/**图实例对象 */
|
||||||
|
const statusBarChart = ref<any>(null);
|
||||||
|
|
||||||
/**网元状态字典数据 */
|
/**网元状态字典数据 */
|
||||||
let indexColor = ref<DictType[]>([
|
let indexColor = ref<DictType[]>([
|
||||||
{ label: 'Normal', value: 'normal', elTagType: '', elTagClass: '#91cc75' },
|
{ label: 'Normal', value: 'normal', elTagType: '', elTagClass: '#91cc75' },
|
||||||
@@ -74,7 +80,7 @@ let tableColumns: ColumnsType = [
|
|||||||
dataIndex: 'serialNum',
|
dataIndex: 'serialNum',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.index.expiryDate'),
|
title: t('views.index.expiryDate'),
|
||||||
dataIndex: 'expiryDate',
|
dataIndex: 'expiryDate',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
@@ -92,8 +98,6 @@ type TabeStateType = {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
/**紧凑型 */
|
/**紧凑型 */
|
||||||
size: string;
|
size: string;
|
||||||
/**斑马纹 */
|
|
||||||
striped: boolean;
|
|
||||||
/**搜索栏 */
|
/**搜索栏 */
|
||||||
seached: boolean;
|
seached: boolean;
|
||||||
/**记录数据 */
|
/**记录数据 */
|
||||||
@@ -106,7 +110,6 @@ type TabeStateType = {
|
|||||||
let tableState: TabeStateType = reactive({
|
let tableState: TabeStateType = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
striped: false,
|
|
||||||
seached: false,
|
seached: false,
|
||||||
data: [],
|
data: [],
|
||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
@@ -181,17 +184,7 @@ function fnGetList(one: boolean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var chartDom: any = document.getElementById('echarts-records');
|
const optionData: any = {
|
||||||
var existingChart = echarts.getInstanceByDom(chartDom);
|
|
||||||
var myChart: any;
|
|
||||||
if (existingChart) {
|
|
||||||
myChart = existingChart;
|
|
||||||
myChart.clear(); // 清空图表,重新设置数据
|
|
||||||
} else {
|
|
||||||
myChart = echarts.init(chartDom);
|
|
||||||
}
|
|
||||||
|
|
||||||
var option = {
|
|
||||||
title: {
|
title: {
|
||||||
text: '',
|
text: '',
|
||||||
subtext: '',
|
subtext: '',
|
||||||
@@ -228,14 +221,28 @@ function fnGetList(one: boolean) {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
option && myChart.setOption(option);
|
fnDesign(statusBar.value, optionData);
|
||||||
window.onresize = function () {
|
|
||||||
// echarts 窗口缩放自适应 随着div--echarts-records的大小来适应
|
|
||||||
myChart.resize();
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fnDesign(container: HTMLElement | undefined, option: any) {
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
if (!statusBarChart.value) {
|
||||||
|
statusBarChart.value = markRaw(echarts.init(container, 'light'));
|
||||||
|
}
|
||||||
|
option && statusBarChart.value.setOption(option);
|
||||||
|
|
||||||
|
// 创建 ResizeObserver 实例
|
||||||
|
var observer = new ResizeObserver(entries => {
|
||||||
|
if (statusBarChart.value) {
|
||||||
|
statusBarChart.value.resize();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 监听元素大小变化
|
||||||
|
observer.observe(container);
|
||||||
|
}
|
||||||
|
|
||||||
/**抽屉 网元详细信息 */
|
/**抽屉 网元详细信息 */
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const closeDrawer = () => {
|
const closeDrawer = () => {
|
||||||
@@ -255,6 +262,16 @@ function rowClick(record: any, index: any) {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
let pronData = toRaw(record);
|
let pronData = toRaw(record);
|
||||||
|
const totalMemInKB = pronData.memUsage?.totalMem;
|
||||||
|
const nfUsedMemInKB = pronData.memUsage?.nfUsedMem;
|
||||||
|
const sysMemUsageInKB = pronData.memUsage?.sysMemUsage;
|
||||||
|
|
||||||
|
// 将KB转换为MB
|
||||||
|
const totalMemInMB = Math.round((totalMemInKB / 1024) * 100) / 100;
|
||||||
|
const nfUsedMemInMB = Math.round((nfUsedMemInKB / 1024) * 100) / 100;
|
||||||
|
const sysMemUsageInMB =
|
||||||
|
Math.round((sysMemUsageInKB / 1024) * 100) / 100;
|
||||||
|
|
||||||
//渲染详细信息
|
//渲染详细信息
|
||||||
pronInfo = {
|
pronInfo = {
|
||||||
hostName: pronData.hostName,
|
hostName: pronData.hostName,
|
||||||
@@ -273,14 +290,14 @@ function rowClick(record: any, index: any) {
|
|||||||
'%',
|
'%',
|
||||||
memoryUse:
|
memoryUse:
|
||||||
'Total:' +
|
'Total:' +
|
||||||
pronData.memUsage?.totalMem +
|
totalMemInMB +
|
||||||
'KB; ' +
|
'MB; ' +
|
||||||
pronData.name +
|
pronData.name +
|
||||||
':' +
|
':' +
|
||||||
pronData.memUsage?.nfUsedMem +
|
nfUsedMemInMB +
|
||||||
'KB; SYS:' +
|
'MB; SYS:' +
|
||||||
pronData.memUsage?.sysMemUsage +
|
sysMemUsageInMB +
|
||||||
'KB',
|
'MB',
|
||||||
capability: pronData.capability,
|
capability: pronData.capability,
|
||||||
serialNum: pronData.serialNum,
|
serialNum: pronData.serialNum,
|
||||||
expiryDate: pronData.expiryDate,
|
expiryDate: pronData.expiryDate,
|
||||||
@@ -394,8 +411,8 @@ onBeforeUnmount(() => {
|
|||||||
<a-col :lg="10" :md="8" :xs="24">
|
<a-col :lg="10" :md="8" :xs="24">
|
||||||
<a-card :title="t('views.index.runStatus')" style="margin-bottom: 16px">
|
<a-card :title="t('views.index.runStatus')" style="margin-bottom: 16px">
|
||||||
<div
|
<div
|
||||||
id="echarts-records"
|
|
||||||
style="width: 100%; min-height: 200px"
|
style="width: 100%; min-height: 200px"
|
||||||
|
ref="statusBar"
|
||||||
></div>
|
></div>
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-card :title="t('views.index.mark')" style="margin-top: 16px">
|
<a-card :title="t('views.index.mark')" style="margin-top: 16px">
|
||||||
|
|||||||
@@ -80,6 +80,24 @@ let tableColumns: ColumnsType = [
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
width: 3,
|
width: 3,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t('views.logManage.forwarding.alarmInter'),
|
||||||
|
dataIndex: 'interface',
|
||||||
|
align: 'center',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.logManage.forwarding.alarmObj'),
|
||||||
|
dataIndex: 'toUser',
|
||||||
|
align: 'center',
|
||||||
|
width: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.logManage.forwarding.alarmInfo'),
|
||||||
|
dataIndex: 'operResult',
|
||||||
|
align: 'center',
|
||||||
|
width: 6,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t('views.logManage.forwarding.type'),
|
title: t('views.logManage.forwarding.type'),
|
||||||
dataIndex: 'neType',
|
dataIndex: 'neType',
|
||||||
@@ -104,24 +122,12 @@ let tableColumns: ColumnsType = [
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
width: 4,
|
width: 4,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: t('views.logManage.forwarding.alarmObj'),
|
|
||||||
dataIndex: 'toUser',
|
|
||||||
align: 'center',
|
|
||||||
width: 5,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: t('views.logManage.forwarding.alarmTitle'),
|
title: t('views.logManage.forwarding.alarmTitle'),
|
||||||
dataIndex: 'alarmTitle',
|
dataIndex: 'alarmTitle',
|
||||||
align: 'left',
|
align: 'center',
|
||||||
width: 5,
|
width: 5,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: t('views.logManage.forwarding.alarmInfo'),
|
|
||||||
dataIndex: 'operResult',
|
|
||||||
align: 'left',
|
|
||||||
width: 6,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: t('views.logManage.forwarding.eventTime'),
|
title: t('views.logManage.forwarding.eventTime'),
|
||||||
dataIndex: 'eventTime',
|
dataIndex: 'eventTime',
|
||||||
|
|||||||
@@ -1,358 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { reactive, onMounted, toRaw } from 'vue';
|
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
|
||||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
|
||||||
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
|
||||||
import { ColumnsType } from 'ant-design-vue/lib/table';
|
|
||||||
import { parseDateToStr } from '@/utils/date-utils';
|
|
||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
|
||||||
import { listOperationLog } from '@/api/logManage/operation';
|
|
||||||
import useDictStore from '@/store/modules/dict';
|
|
||||||
import useI18n from '@/hooks/useI18n';
|
|
||||||
const { getDict } = useDictStore();
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
/**字典数据 */
|
|
||||||
let dict: {
|
|
||||||
/**操作日志操作类型 */
|
|
||||||
operationLogType: DictType[];
|
|
||||||
} = reactive({
|
|
||||||
operationLogType: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/**查询参数 */
|
|
||||||
let queryParams = reactive({
|
|
||||||
/**登录账号 */
|
|
||||||
accountName: '',
|
|
||||||
/**操作类型 */
|
|
||||||
opType: undefined,
|
|
||||||
/**记录时间 */
|
|
||||||
beginTime: '',
|
|
||||||
endTime: '',
|
|
||||||
/**当前页数 */
|
|
||||||
pageNum: 1,
|
|
||||||
/**每页条数 */
|
|
||||||
pageSize: 20,
|
|
||||||
});
|
|
||||||
|
|
||||||
/**查询参数重置 */
|
|
||||||
function fnQueryReset() {
|
|
||||||
queryParams = Object.assign(queryParams, {
|
|
||||||
accountName: '',
|
|
||||||
opType: undefined,
|
|
||||||
beginTime: '',
|
|
||||||
endTime: '',
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 20,
|
|
||||||
});
|
|
||||||
tablePagination.current = 1;
|
|
||||||
tablePagination.pageSize = 20;
|
|
||||||
fnGetList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**表格状态类型 */
|
|
||||||
type TabeStateType = {
|
|
||||||
/**加载等待 */
|
|
||||||
loading: boolean;
|
|
||||||
/**紧凑型 */
|
|
||||||
size: SizeType;
|
|
||||||
/**搜索栏 */
|
|
||||||
seached: boolean;
|
|
||||||
/**记录数据 */
|
|
||||||
data: object[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**表格状态 */
|
|
||||||
let tableState: TabeStateType = reactive({
|
|
||||||
loading: false,
|
|
||||||
size: 'middle',
|
|
||||||
seached: true,
|
|
||||||
data: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/**表格字段列 */
|
|
||||||
let tableColumns: ColumnsType = [
|
|
||||||
{
|
|
||||||
title: t('common.rowId'),
|
|
||||||
dataIndex: 'opId',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '登录账号',
|
|
||||||
dataIndex: 'accountName',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '用户类型',
|
|
||||||
dataIndex: 'accountType',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '源IP地址',
|
|
||||||
dataIndex: 'opIp',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作对象',
|
|
||||||
dataIndex: 'subsysTag',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作类型',
|
|
||||||
dataIndex: 'opType',
|
|
||||||
key: 'opType',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作内容',
|
|
||||||
dataIndex: 'opContent',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作结果',
|
|
||||||
dataIndex: 'opResult',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '开始时间',
|
|
||||||
dataIndex: 'beginTime',
|
|
||||||
align: 'center',
|
|
||||||
customRender(opt) {
|
|
||||||
if (!opt.value) return '';
|
|
||||||
return parseDateToStr(opt.value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '结束时间',
|
|
||||||
dataIndex: 'endTime',
|
|
||||||
align: 'center',
|
|
||||||
customRender(opt) {
|
|
||||||
if (!opt.value) return '';
|
|
||||||
return parseDateToStr(opt.value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '网元虚拟化标识',
|
|
||||||
dataIndex: 'vnfFlag',
|
|
||||||
align: 'center',
|
|
||||||
customRender(opt) {
|
|
||||||
if (opt.value === 0) return 'PNF';
|
|
||||||
if (opt.value === 1) return 'VNF';
|
|
||||||
return '';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**表格分页器参数 */
|
|
||||||
let tablePagination = reactive({
|
|
||||||
/**当前页数 */
|
|
||||||
current: 1,
|
|
||||||
/**每页条数 */
|
|
||||||
pageSize: 20,
|
|
||||||
/**默认的每页条数 */
|
|
||||||
defaultPageSize: 20,
|
|
||||||
/**指定每页可以显示多少条 */
|
|
||||||
pageSizeOptions: ['10', '20', '50', '100'],
|
|
||||||
/**只有一页时是否隐藏分页器 */
|
|
||||||
hideOnSinglePage: false,
|
|
||||||
/**是否可以快速跳转至某页 */
|
|
||||||
showQuickJumper: true,
|
|
||||||
/**是否可以改变 pageSize */
|
|
||||||
showSizeChanger: true,
|
|
||||||
/**数据总数 */
|
|
||||||
total: 0,
|
|
||||||
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
|
|
||||||
onChange: (page: number, pageSize: number) => {
|
|
||||||
tablePagination.current = page;
|
|
||||||
tablePagination.pageSize = pageSize;
|
|
||||||
queryParams.pageNum = page;
|
|
||||||
queryParams.pageSize = pageSize;
|
|
||||||
fnGetList();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/**表格紧凑型变更操作 */
|
|
||||||
function fnTableSize({ key }: MenuInfo) {
|
|
||||||
tableState.size = key as SizeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**查询备份信息列表, pageNum初始页数 */
|
|
||||||
function fnGetList(pageNum?: number) {
|
|
||||||
if (tableState.loading) return;
|
|
||||||
tableState.loading = true;
|
|
||||||
if(pageNum){
|
|
||||||
queryParams.pageNum = pageNum;
|
|
||||||
}
|
|
||||||
listOperationLog(toRaw(queryParams)).then(res => {
|
|
||||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
|
||||||
tablePagination.total = res.total;
|
|
||||||
tableState.data = res.rows;
|
|
||||||
if (tablePagination.total <=(queryParams.pageNum - 1) * tablePagination.pageSize &&queryParams.pageNum !== 1) {
|
|
||||||
tableState.loading = false;
|
|
||||||
fnGetList(queryParams.pageNum - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tableState.loading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 初始字典数据
|
|
||||||
Promise.allSettled([getDict('operation_log_type')]).then(resArr => {
|
|
||||||
if (resArr[0].status === 'fulfilled') {
|
|
||||||
dict.operationLogType = resArr[0].value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 获取列表数据
|
|
||||||
fnGetList();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<PageContainer>
|
|
||||||
<a-card
|
|
||||||
v-show="tableState.seached"
|
|
||||||
:bordered="false"
|
|
||||||
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
|
||||||
>
|
|
||||||
<!-- 表格搜索栏 -->
|
|
||||||
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
|
||||||
<a-row :gutter="16">
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item label="登录账号" name="accountName">
|
|
||||||
<a-input
|
|
||||||
v-model:value="queryParams.accountName"
|
|
||||||
:allow-clear="true"
|
|
||||||
placeholder="查询登录账号"
|
|
||||||
></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item label="操作类型" name="opType">
|
|
||||||
<a-select
|
|
||||||
v-model:value="queryParams.opType"
|
|
||||||
allow-clear
|
|
||||||
placeholder="请选择操作类型"
|
|
||||||
:options="dict.operationLogType"
|
|
||||||
>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item label="开始时间" name="beginTime">
|
|
||||||
<a-date-picker
|
|
||||||
show-time
|
|
||||||
v-model:value="queryParams.beginTime"
|
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
placeholder="查询结束时间"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item label="结束时间" name="endTime">
|
|
||||||
<a-date-picker
|
|
||||||
show-time
|
|
||||||
v-model:value="queryParams.endTime"
|
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
placeholder="查询结束时间"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item>
|
|
||||||
<a-space :size="8">
|
|
||||||
<a-button type="primary" @click.prevent="fnGetList(1)">
|
|
||||||
<template #icon><SearchOutlined /></template>
|
|
||||||
{{ t('common.search') }}
|
|
||||||
</a-button>
|
|
||||||
<a-button type="default" @click.prevent="fnQueryReset">
|
|
||||||
<template #icon><ClearOutlined /></template>
|
|
||||||
{{ t('common.reset') }}
|
|
||||||
</a-button>
|
|
||||||
</a-space>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-form>
|
|
||||||
</a-card>
|
|
||||||
|
|
||||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
|
||||||
<!-- 插槽-卡片左侧侧 -->
|
|
||||||
<template #title> </template>
|
|
||||||
|
|
||||||
<!-- 插槽-卡片右侧 -->
|
|
||||||
<template #extra>
|
|
||||||
<a-space :size="8" align="center">
|
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.searchBarText') }}</template>
|
|
||||||
<a-switch
|
|
||||||
v-model:checked="tableState.seached"
|
|
||||||
:checked-children="t('common.switch.show')"
|
|
||||||
:un-checked-children="t('common.switch.hide')"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
|
||||||
<template #icon><ReloadOutlined /></template>
|
|
||||||
</a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.sizeText') }}</template>
|
|
||||||
<a-dropdown trigger="click" placement="bottomRight">
|
|
||||||
<a-button type="text">
|
|
||||||
<template #icon><ColumnHeightOutlined /></template>
|
|
||||||
</a-button>
|
|
||||||
<template #overlay>
|
|
||||||
<a-menu
|
|
||||||
:selected-keys="[tableState.size as string]"
|
|
||||||
@click="fnTableSize"
|
|
||||||
>
|
|
||||||
<a-menu-item key="default">
|
|
||||||
{{ t('common.size.default') }}
|
|
||||||
</a-menu-item>
|
|
||||||
<a-menu-item key="middle">
|
|
||||||
{{ t('common.size.middle') }}
|
|
||||||
</a-menu-item>
|
|
||||||
<a-menu-item key="small">
|
|
||||||
{{ t('common.size.small') }}
|
|
||||||
</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
</template>
|
|
||||||
</a-dropdown>
|
|
||||||
</a-tooltip>
|
|
||||||
</a-space>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 表格列表 -->
|
|
||||||
<a-table
|
|
||||||
class="table"
|
|
||||||
row-key="opId"
|
|
||||||
:columns="tableColumns"
|
|
||||||
:loading="tableState.loading"
|
|
||||||
:data-source="tableState.data"
|
|
||||||
:size="tableState.size"
|
|
||||||
:pagination="tablePagination"
|
|
||||||
:scroll="{ x: true }"
|
|
||||||
>
|
|
||||||
<template #bodyCell="{ column, record }">
|
|
||||||
<template v-if="column.key === 'opType'">
|
|
||||||
<DictTag :options="dict.operationLogType" :value="record.opType" />
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</a-table>
|
|
||||||
</a-card>
|
|
||||||
</PageContainer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.table :deep(.ant-pagination) {
|
|
||||||
padding: 0 24px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { reactive, ref, onMounted, toRaw } from 'vue';
|
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
|
||||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
|
||||||
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
|
||||||
import { ColumnsType } from 'ant-design-vue/lib/table';
|
|
||||||
import { parseDateToStr } from '@/utils/date-utils';
|
|
||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
|
||||||
import { listSecurityLog } from '@/api/logManage/security';
|
|
||||||
import useDictStore from '@/store/modules/dict';
|
|
||||||
import useI18n from '@/hooks/useI18n';
|
|
||||||
const { getDict } = useDictStore();
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
/**字典数据 */
|
|
||||||
let dict: {
|
|
||||||
/**安全日志操作类型 */
|
|
||||||
securityLogType: DictType[];
|
|
||||||
} = reactive({
|
|
||||||
securityLogType: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/**记录开始结束时间 */
|
|
||||||
let queryRangePicker = ref<[string, string]>(['', '']);
|
|
||||||
|
|
||||||
/**查询参数 */
|
|
||||||
let queryParams = reactive({
|
|
||||||
/**登录账号 */
|
|
||||||
accountName: '',
|
|
||||||
/**操作类型 */
|
|
||||||
opType: undefined,
|
|
||||||
/**记录时间 */
|
|
||||||
beginTime: '',
|
|
||||||
endTime: '',
|
|
||||||
/**当前页数 */
|
|
||||||
pageNum: 1,
|
|
||||||
/**每页条数 */
|
|
||||||
pageSize: 20,
|
|
||||||
});
|
|
||||||
|
|
||||||
/**查询参数重置 */
|
|
||||||
function fnQueryReset() {
|
|
||||||
queryParams = Object.assign(queryParams, {
|
|
||||||
accountName: '',
|
|
||||||
opType: undefined,
|
|
||||||
beginTime: '',
|
|
||||||
endTime: '',
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 20,
|
|
||||||
});
|
|
||||||
queryRangePicker.value = ['', ''];
|
|
||||||
tablePagination.current = 1;
|
|
||||||
tablePagination.pageSize = 20;
|
|
||||||
fnGetList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**表格状态类型 */
|
|
||||||
type TabeStateType = {
|
|
||||||
/**加载等待 */
|
|
||||||
loading: boolean;
|
|
||||||
/**紧凑型 */
|
|
||||||
size: SizeType;
|
|
||||||
/**搜索栏 */
|
|
||||||
seached: boolean;
|
|
||||||
/**记录数据 */
|
|
||||||
data: object[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**表格状态 */
|
|
||||||
let tableState: TabeStateType = reactive({
|
|
||||||
loading: false,
|
|
||||||
size: 'middle',
|
|
||||||
seached: true,
|
|
||||||
data: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/**表格字段列 */
|
|
||||||
let tableColumns: ColumnsType = [
|
|
||||||
{
|
|
||||||
title: t('common.rowId'),
|
|
||||||
dataIndex: 'id',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '登录账号',
|
|
||||||
dataIndex: 'accountName',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '用户类型',
|
|
||||||
dataIndex: 'accountType',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '源IP地址',
|
|
||||||
dataIndex: 'opIp',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作类型',
|
|
||||||
dataIndex: 'opType',
|
|
||||||
key: 'opType',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作内容',
|
|
||||||
dataIndex: 'opContent',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作结果',
|
|
||||||
dataIndex: 'opResult',
|
|
||||||
align: 'center',
|
|
||||||
customRender(opt) {
|
|
||||||
if (opt.value === 1) return '成功';
|
|
||||||
return '失败';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '记录时间',
|
|
||||||
dataIndex: 'opTime',
|
|
||||||
align: 'center',
|
|
||||||
customRender(opt) {
|
|
||||||
if (!opt.value) return '';
|
|
||||||
return parseDateToStr(opt.value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**表格分页器参数 */
|
|
||||||
let tablePagination = reactive({
|
|
||||||
/**当前页数 */
|
|
||||||
current: 1,
|
|
||||||
/**每页条数 */
|
|
||||||
pageSize: 20,
|
|
||||||
/**默认的每页条数 */
|
|
||||||
defaultPageSize: 20,
|
|
||||||
/**指定每页可以显示多少条 */
|
|
||||||
pageSizeOptions: ['10', '20', '50', '100'],
|
|
||||||
/**只有一页时是否隐藏分页器 */
|
|
||||||
hideOnSinglePage: false,
|
|
||||||
/**是否可以快速跳转至某页 */
|
|
||||||
showQuickJumper: true,
|
|
||||||
/**是否可以改变 pageSize */
|
|
||||||
showSizeChanger: true,
|
|
||||||
/**数据总数 */
|
|
||||||
total: 0,
|
|
||||||
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
|
|
||||||
onChange: (page: number, pageSize: number) => {
|
|
||||||
tablePagination.current = page;
|
|
||||||
tablePagination.pageSize = pageSize;
|
|
||||||
queryParams.pageNum = page;
|
|
||||||
queryParams.pageSize = pageSize;
|
|
||||||
fnGetList();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/**表格紧凑型变更操作 */
|
|
||||||
function fnTableSize({ key }: MenuInfo) {
|
|
||||||
tableState.size = key as SizeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**查询备份信息列表, pageNum初始页数 */
|
|
||||||
function fnGetList(pageNum?: number) {
|
|
||||||
if (tableState.loading) return;
|
|
||||||
tableState.loading = true;
|
|
||||||
if(pageNum){
|
|
||||||
queryParams.pageNum = pageNum;
|
|
||||||
}
|
|
||||||
if (!queryRangePicker.value) {
|
|
||||||
queryRangePicker.value = ['', ''];
|
|
||||||
}
|
|
||||||
queryParams.beginTime = queryRangePicker.value[0];
|
|
||||||
queryParams.endTime = queryRangePicker.value[1];
|
|
||||||
listSecurityLog(toRaw(queryParams)).then(res => {
|
|
||||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
|
||||||
tablePagination.total = res.total;
|
|
||||||
tableState.data = res.rows;
|
|
||||||
if (tablePagination.total <=(queryParams.pageNum - 1) * tablePagination.pageSize &&queryParams.pageNum !== 1) {
|
|
||||||
tableState.loading = false;
|
|
||||||
fnGetList(queryParams.pageNum - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tableState.loading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 初始字典数据
|
|
||||||
Promise.allSettled([getDict('security_log_type')]).then(resArr => {
|
|
||||||
if (resArr[0].status === 'fulfilled') {
|
|
||||||
dict.securityLogType = resArr[0].value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 获取列表数据
|
|
||||||
fnGetList();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<PageContainer>
|
|
||||||
<a-card
|
|
||||||
v-show="tableState.seached"
|
|
||||||
:bordered="false"
|
|
||||||
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
|
||||||
>
|
|
||||||
<!-- 表格搜索栏 -->
|
|
||||||
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
|
||||||
<a-row :gutter="16">
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item label="登录账号" name="accountName">
|
|
||||||
<a-input
|
|
||||||
v-model:value="queryParams.accountName"
|
|
||||||
:allow-clear="true"
|
|
||||||
placeholder="查询登录账号"
|
|
||||||
></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item label="操作类型" name="opType">
|
|
||||||
<a-select
|
|
||||||
v-model:value="queryParams.opType"
|
|
||||||
allow-clear
|
|
||||||
placeholder="请选择操作类型"
|
|
||||||
:options="dict.securityLogType"
|
|
||||||
>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="8" :md="12" :xs="24">
|
|
||||||
<a-form-item label="记录时间" name="queryRangePicker">
|
|
||||||
<a-range-picker
|
|
||||||
v-model:value="queryRangePicker"
|
|
||||||
allow-clear
|
|
||||||
bordered
|
|
||||||
show-time
|
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
:placeholder="['记录开始', '记录结束']"
|
|
||||||
style="width: 100%"
|
|
||||||
></a-range-picker>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item>
|
|
||||||
<a-space :size="8">
|
|
||||||
<a-button type="primary" @click.prevent="fnGetList(1)">
|
|
||||||
<template #icon><SearchOutlined /></template>
|
|
||||||
{{ t('common.search') }}
|
|
||||||
</a-button>
|
|
||||||
<a-button type="default" @click.prevent="fnQueryReset">
|
|
||||||
<template #icon><ClearOutlined /></template>
|
|
||||||
{{ t('common.reset') }}
|
|
||||||
</a-button>
|
|
||||||
</a-space>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-form>
|
|
||||||
</a-card>
|
|
||||||
|
|
||||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
|
||||||
<!-- 插槽-卡片左侧侧 -->
|
|
||||||
<template #title> </template>
|
|
||||||
|
|
||||||
<!-- 插槽-卡片右侧 -->
|
|
||||||
<template #extra>
|
|
||||||
<a-space :size="8" align="center">
|
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.searchBarText') }}</template>
|
|
||||||
<a-switch
|
|
||||||
v-model:checked="tableState.seached"
|
|
||||||
:checked-children="t('common.switch.show')"
|
|
||||||
:un-checked-children="t('common.switch.hide')"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
|
||||||
<template #icon><ReloadOutlined /></template>
|
|
||||||
</a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.sizeText') }}</template>
|
|
||||||
<a-dropdown trigger="click" placement="bottomRight">
|
|
||||||
<a-button type="text">
|
|
||||||
<template #icon><ColumnHeightOutlined /></template>
|
|
||||||
</a-button>
|
|
||||||
<template #overlay>
|
|
||||||
<a-menu
|
|
||||||
:selected-keys="[tableState.size as string]"
|
|
||||||
@click="fnTableSize"
|
|
||||||
>
|
|
||||||
<a-menu-item key="default">
|
|
||||||
{{ t('common.size.default') }}
|
|
||||||
</a-menu-item>
|
|
||||||
<a-menu-item key="middle">
|
|
||||||
{{ t('common.size.middle') }}
|
|
||||||
</a-menu-item>
|
|
||||||
<a-menu-item key="small">
|
|
||||||
{{ t('common.size.small') }}
|
|
||||||
</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
</template>
|
|
||||||
</a-dropdown>
|
|
||||||
</a-tooltip>
|
|
||||||
</a-space>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 表格列表 -->
|
|
||||||
<a-table
|
|
||||||
class="table"
|
|
||||||
row-key="id"
|
|
||||||
:columns="tableColumns"
|
|
||||||
:loading="tableState.loading"
|
|
||||||
:data-source="tableState.data"
|
|
||||||
:size="tableState.size"
|
|
||||||
:pagination="tablePagination"
|
|
||||||
:scroll="{ x: true }"
|
|
||||||
>
|
|
||||||
<template #bodyCell="{ column, record }">
|
|
||||||
<template v-if="column.key === 'opType'">
|
|
||||||
<DictTag :options="dict.securityLogType" :value="record.opType" />
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</a-table>
|
|
||||||
</a-card>
|
|
||||||
</PageContainer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.table :deep(.ant-pagination) {
|
|
||||||
padding: 0 24px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
+6
-8
@@ -14,10 +14,6 @@ const appStore = useAppStore();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
/**登录后重定向页面 */
|
|
||||||
const redirectPath =
|
|
||||||
(route.query && (route.query.redirect as string)) || '/index';
|
|
||||||
|
|
||||||
let state = reactive({
|
let state = reactive({
|
||||||
/**表单属性 */
|
/**表单属性 */
|
||||||
from: {
|
from: {
|
||||||
@@ -52,7 +48,9 @@ function fnFinish() {
|
|||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
message.success(t('views.login.loginSuccess'), 3);
|
message.success(t('views.login.loginSuccess'), 3);
|
||||||
router.push({ path: redirectPath });
|
/**登录后重定向页面 */
|
||||||
|
const redirectPath = route.query?.redirect || '/index';
|
||||||
|
router.push({ path: redirectPath as string });
|
||||||
} else {
|
} else {
|
||||||
message.error(`${res.msg}`, 3);
|
message.error(`${res.msg}`, 3);
|
||||||
}
|
}
|
||||||
@@ -311,7 +309,7 @@ function fnClickHelpDoc(language?: string) {
|
|||||||
v-if="appStore.i18nOpen"
|
v-if="appStore.i18nOpen"
|
||||||
>
|
>
|
||||||
<a-col :offset="18" :span="6">
|
<a-col :offset="18" :span="6">
|
||||||
<a-dropdown :trigger="['click', 'hover']">
|
<a-dropdown trigger="click">
|
||||||
<a-button size="small" type="default">
|
<a-button size="small" type="default">
|
||||||
{{ t('i18n') }}
|
{{ t('i18n') }}
|
||||||
<DownOutlined />
|
<DownOutlined />
|
||||||
@@ -344,7 +342,7 @@ function fnClickHelpDoc(language?: string) {
|
|||||||
|
|
||||||
// background: url('./../assets/black_dot.png') 0% 0% / 14px 14px repeat;
|
// background: url('./../assets/black_dot.png') 0% 0% / 14px 14px repeat;
|
||||||
|
|
||||||
background-image: url(./../assets/background.jpg);
|
background-image: url(@/assets/background.jpg);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
@@ -436,7 +434,7 @@ function fnClickHelpDoc(language?: string) {
|
|||||||
min-width: 260px;
|
min-width: 260px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
margin-left: 60%;
|
margin-left: 60%;
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
|
|
||||||
& .desc {
|
& .desc {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -78,8 +78,6 @@ type TabeStateType = {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
/**紧凑型 */
|
/**紧凑型 */
|
||||||
size: SizeType;
|
size: SizeType;
|
||||||
/**斑马纹 */
|
|
||||||
striped: boolean;
|
|
||||||
/**搜索栏 */
|
/**搜索栏 */
|
||||||
seached: boolean;
|
seached: boolean;
|
||||||
/**记录数据 */
|
/**记录数据 */
|
||||||
@@ -92,7 +90,6 @@ type TabeStateType = {
|
|||||||
let tableState: TabeStateType = reactive({
|
let tableState: TabeStateType = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
striped: false,
|
|
||||||
seached: false,
|
seached: false,
|
||||||
data: [],
|
data: [],
|
||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
@@ -185,11 +182,6 @@ function fnTableSize({ key }: MenuInfo) {
|
|||||||
tableState.size = key as SizeType;
|
tableState.size = key as SizeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**表格斑马纹 */
|
|
||||||
function fnTableStriped(_record: unknown, index: number): any {
|
|
||||||
return tableState.striped && index % 2 === 1 ? 'table-striped' : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**表格多选 */
|
/**表格多选 */
|
||||||
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
||||||
tableState.selectedRowKeys = keys;
|
tableState.selectedRowKeys = keys;
|
||||||
@@ -714,15 +706,6 @@ onMounted(() => {
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.tableStripedText') }}</template>
|
|
||||||
<a-switch
|
|
||||||
v-model:checked="tableState.striped"
|
|
||||||
:checked-children="t('common.switch.open')"
|
|
||||||
:un-checked-children="t('common.switch.shut')"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
@@ -764,7 +747,6 @@ onMounted(() => {
|
|||||||
:loading="tableState.loading"
|
:loading="tableState.loading"
|
||||||
:data-source="tableState.data"
|
:data-source="tableState.data"
|
||||||
:size="tableState.size"
|
:size="tableState.size"
|
||||||
:row-class-name="fnTableStriped"
|
|
||||||
:pagination="tablePagination"
|
:pagination="tablePagination"
|
||||||
:scroll="{ x: tableColumns.length * 120 }"
|
:scroll="{ x: tableColumns.length * 120 }"
|
||||||
:row-selection="{
|
:row-selection="{
|
||||||
@@ -1140,10 +1122,6 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.table :deep(.table-striped) td {
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table :deep(.ant-pagination) {
|
.table :deep(.ant-pagination) {
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,8 +96,6 @@ type TabeStateType = {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
/**紧凑型 */
|
/**紧凑型 */
|
||||||
size: SizeType;
|
size: SizeType;
|
||||||
/**斑马纹 */
|
|
||||||
striped: boolean;
|
|
||||||
/**搜索栏 */
|
/**搜索栏 */
|
||||||
seached: boolean;
|
seached: boolean;
|
||||||
/**记录数据 */
|
/**记录数据 */
|
||||||
@@ -110,7 +108,6 @@ type TabeStateType = {
|
|||||||
let tableState: TabeStateType = reactive({
|
let tableState: TabeStateType = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
striped: false,
|
|
||||||
seached: true,
|
seached: true,
|
||||||
data: [],
|
data: [],
|
||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
@@ -122,6 +119,7 @@ let tableColumns: ColumnsType = [
|
|||||||
title: t('common.rowId'),
|
title: t('common.rowId'),
|
||||||
dataIndex: 'jobLogId',
|
dataIndex: 'jobLogId',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.monitor.jobLog.jobName'),
|
title: t('views.monitor.jobLog.jobName'),
|
||||||
@@ -164,7 +162,7 @@ let tableColumns: ColumnsType = [
|
|||||||
dataIndex: 'costTime',
|
dataIndex: 'costTime',
|
||||||
key: 'costTime',
|
key: 'costTime',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
width: 100,
|
width: 150,
|
||||||
customRender(opt) {
|
customRender(opt) {
|
||||||
return `${opt.value} ms`;
|
return `${opt.value} ms`;
|
||||||
},
|
},
|
||||||
@@ -210,11 +208,6 @@ function fnTableSize({ key }: MenuInfo) {
|
|||||||
tableState.size = key as SizeType;
|
tableState.size = key as SizeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**表格斑马纹 */
|
|
||||||
function fnTableStriped(_record: unknown, index: number): any {
|
|
||||||
return tableState.striped && index % 2 === 1 ? 'table-striped' : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**表格多选 */
|
/**表格多选 */
|
||||||
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
||||||
tableState.selectedRowKeys = keys;
|
tableState.selectedRowKeys = keys;
|
||||||
@@ -478,7 +471,9 @@ onMounted(() => {
|
|||||||
v-model:value="queryRangePicker"
|
v-model:value="queryRangePicker"
|
||||||
allow-clear
|
allow-clear
|
||||||
bordered
|
bordered
|
||||||
value-format="YYYY-MM-DD"
|
:show-time="{ format: 'HH:mm:ss' }"
|
||||||
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
value-format="x"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
></a-range-picker>
|
></a-range-picker>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -551,15 +546,6 @@ onMounted(() => {
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.tableStripedText') }}</template>
|
|
||||||
<a-switch
|
|
||||||
v-model:checked="tableState.striped"
|
|
||||||
:checked-children="t('common.switch.open')"
|
|
||||||
:un-checked-children="t('common.switch.shut')"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
@@ -601,7 +587,6 @@ onMounted(() => {
|
|||||||
:loading="tableState.loading"
|
:loading="tableState.loading"
|
||||||
:data-source="tableState.data"
|
:data-source="tableState.data"
|
||||||
:size="tableState.size"
|
:size="tableState.size"
|
||||||
:row-class-name="fnTableStriped"
|
|
||||||
:scroll="{ x: tableColumns.length * 120 }"
|
:scroll="{ x: tableColumns.length * 120 }"
|
||||||
:pagination="tablePagination"
|
:pagination="tablePagination"
|
||||||
:row-selection="{
|
:row-selection="{
|
||||||
@@ -748,10 +733,6 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.table :deep(.table-striped) td {
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table :deep(.ant-pagination) {
|
.table :deep(.ant-pagination) {
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ let rangePicker = reactive<RangePickerType>({
|
|||||||
t('views.monitor.monitor.endTime'),
|
t('views.monitor.monitor.endTime'),
|
||||||
],
|
],
|
||||||
ranges: {
|
ranges: {
|
||||||
[t('views.monitor.monitor.today')]: [
|
[t('views.monitor.monitor.yesterday')]: [
|
||||||
dayjs().subtract(1, 'day').startOf('day'),
|
dayjs().subtract(1, 'day').startOf('day'),
|
||||||
dayjs().subtract(1, 'day').endOf('day'),
|
dayjs().subtract(1, 'day').endOf('day'),
|
||||||
],
|
],
|
||||||
[t('views.monitor.monitor.yesterday')]: [dayjs().startOf('day'), dayjs()],
|
[t('views.monitor.monitor.today')]: [dayjs().startOf('day'), dayjs()],
|
||||||
[t('views.monitor.monitor.week')]: [
|
[t('views.monitor.monitor.week')]: [
|
||||||
dayjs().startOf('week'),
|
dayjs().startOf('week'),
|
||||||
dayjs().endOf('week'),
|
dayjs().endOf('week'),
|
||||||
@@ -66,21 +66,21 @@ let rangePicker = reactive<RangePickerType>({
|
|||||||
function fnGetList() {
|
function fnGetList() {
|
||||||
let startTime = null;
|
let startTime = null;
|
||||||
let endTime = null;
|
let endTime = null;
|
||||||
const dateString = rangePicker.all;
|
const dateNumber = rangePicker.all;
|
||||||
if (dateString[0]) {
|
if (dateNumber[0]) {
|
||||||
startTime = parseStrToDate(dateString[0], YYYY_MM_DD_HH_MM_SS);
|
startTime = dateNumber[0];
|
||||||
endTime = parseStrToDate(dateString[1], YYYY_MM_DD_HH_MM_SS);
|
endTime = dateNumber[1];
|
||||||
} else {
|
} else {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
now.setHours(0, 0, 0, 0);
|
now.setHours(0, 0, 0, 0);
|
||||||
startTime = now;
|
startTime = `${now.getTime()}`;
|
||||||
endTime = new Date();
|
endTime = `${new Date().getTime()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
getLoad({
|
getLoad({
|
||||||
type: 'all',
|
type: 'all',
|
||||||
startTime: startTime.getTime(),
|
startTime: startTime,
|
||||||
endTime: endTime.getTime(),
|
endTime: endTime,
|
||||||
neType: '#',
|
neType: '#',
|
||||||
neId: '#',
|
neId: '#',
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
@@ -94,10 +94,7 @@ function fnGetList() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 设置初始时间段
|
// 设置初始时间段
|
||||||
const initRangePicker: [string, string] = [
|
const initRangePicker: [string, string] = [startTime, endTime];
|
||||||
parseDateToStr(startTime, YYYY_MM_DD_HH_MM_SS),
|
|
||||||
parseDateToStr(endTime, YYYY_MM_DD_HH_MM_SS),
|
|
||||||
];
|
|
||||||
rangePicker.all = initRangePicker;
|
rangePicker.all = initRangePicker;
|
||||||
rangePicker.load = initRangePicker;
|
rangePicker.load = initRangePicker;
|
||||||
rangePicker.cpu = initRangePicker;
|
rangePicker.cpu = initRangePicker;
|
||||||
@@ -164,7 +161,7 @@ function fnLoadChart(data: Record<string, any>[]) {
|
|||||||
type: 'value',
|
type: 'value',
|
||||||
name: `${t('views.monitor.monitor.resourceUsage')} ( % )`,
|
name: `${t('views.monitor.monitor.resourceUsage')} ( % )`,
|
||||||
position: 'right',
|
position: 'right',
|
||||||
alignTicks: false
|
alignTicks: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
grid: { left: '5%', right: '5%', bottom: '20%' },
|
grid: { left: '5%', right: '5%', bottom: '20%' },
|
||||||
@@ -446,9 +443,9 @@ onMounted(() => {
|
|||||||
v-model:value="rangePicker.all"
|
v-model:value="rangePicker.all"
|
||||||
:allow-clear="false"
|
:allow-clear="false"
|
||||||
bordered
|
bordered
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
:show-time="{ format: 'HH:mm:ss' }"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
show-time
|
value-format="x"
|
||||||
:placeholder="rangePicker.placeholder"
|
:placeholder="rangePicker.placeholder"
|
||||||
:ranges="rangePicker.ranges"
|
:ranges="rangePicker.ranges"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@@ -480,9 +477,9 @@ onMounted(() => {
|
|||||||
v-model:value="rangePicker.load"
|
v-model:value="rangePicker.load"
|
||||||
:allow-clear="false"
|
:allow-clear="false"
|
||||||
bordered
|
bordered
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
:show-time="{ format: 'HH:mm:ss' }"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
show-time
|
value-format="x"
|
||||||
:placeholder="rangePicker.placeholder"
|
:placeholder="rangePicker.placeholder"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="(_:any, d:[string,string]) => fnGetQuery('load', d)"
|
@change="(_:any, d:[string,string]) => fnGetQuery('load', d)"
|
||||||
@@ -510,9 +507,9 @@ onMounted(() => {
|
|||||||
v-model:value="rangePicker.cpu"
|
v-model:value="rangePicker.cpu"
|
||||||
:allow-clear="false"
|
:allow-clear="false"
|
||||||
bordered
|
bordered
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
:show-time="{ format: 'HH:mm:ss' }"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
show-time
|
value-format="x"
|
||||||
:placeholder="rangePicker.placeholder"
|
:placeholder="rangePicker.placeholder"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="(_:any, d:[string,string]) => fnGetQuery('cpu', d)"
|
@change="(_:any, d:[string,string]) => fnGetQuery('cpu', d)"
|
||||||
@@ -538,9 +535,9 @@ onMounted(() => {
|
|||||||
v-model:value="rangePicker.memory"
|
v-model:value="rangePicker.memory"
|
||||||
:allow-clear="false"
|
:allow-clear="false"
|
||||||
bordered
|
bordered
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
:show-time="{ format: 'HH:mm:ss' }"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
show-time
|
value-format="x"
|
||||||
:placeholder="rangePicker.placeholder"
|
:placeholder="rangePicker.placeholder"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="(_:any, d:[string,string]) => fnGetQuery('memory', d)"
|
@change="(_:any, d:[string,string]) => fnGetQuery('memory', d)"
|
||||||
@@ -568,9 +565,9 @@ onMounted(() => {
|
|||||||
v-model:value="rangePicker.io"
|
v-model:value="rangePicker.io"
|
||||||
:allow-clear="false"
|
:allow-clear="false"
|
||||||
bordered
|
bordered
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
:show-time="{ format: 'HH:mm:ss' }"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
show-time
|
value-format="x"
|
||||||
:placeholder="rangePicker.placeholder"
|
:placeholder="rangePicker.placeholder"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="fnGetQueryIO"
|
@change="fnGetQueryIO"
|
||||||
@@ -596,9 +593,9 @@ onMounted(() => {
|
|||||||
v-model:value="rangePicker.network"
|
v-model:value="rangePicker.network"
|
||||||
:allow-clear="false"
|
:allow-clear="false"
|
||||||
bordered
|
bordered
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
:show-time="{ format: 'HH:mm:ss' }"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
show-time
|
value-format="x"
|
||||||
:placeholder="rangePicker.placeholder"
|
:placeholder="rangePicker.placeholder"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="fnGetQueryNetwork"
|
@change="fnGetQueryNetwork"
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ type TabeStateType = {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
/**紧凑型 */
|
/**紧凑型 */
|
||||||
size: SizeType;
|
size: SizeType;
|
||||||
/**斑马纹 */
|
|
||||||
striped: boolean;
|
|
||||||
/**搜索栏 */
|
/**搜索栏 */
|
||||||
seached: boolean;
|
seached: boolean;
|
||||||
/**记录数据 */
|
/**记录数据 */
|
||||||
@@ -37,7 +35,6 @@ type TabeStateType = {
|
|||||||
let tableState: TabeStateType = reactive({
|
let tableState: TabeStateType = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
striped: false,
|
|
||||||
seached: false,
|
seached: false,
|
||||||
data: [],
|
data: [],
|
||||||
});
|
});
|
||||||
@@ -69,11 +66,11 @@ let tableColumns: ColumnsType = [
|
|||||||
dataIndex: 'ipaddr',
|
dataIndex: 'ipaddr',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: t('views.monitor.online.loginDes'),
|
// title: t('views.monitor.online.loginDes'),
|
||||||
dataIndex: 'loginLocation',
|
// dataIndex: 'loginLocation',
|
||||||
align: 'center',
|
// align: 'center',
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
title: t('views.monitor.online.os'),
|
title: t('views.monitor.online.os'),
|
||||||
dataIndex: 'os',
|
dataIndex: 'os',
|
||||||
@@ -130,11 +127,6 @@ function fnTableSize({ key }: MenuInfo) {
|
|||||||
tableState.size = key as SizeType;
|
tableState.size = key as SizeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**表格斑马纹 */
|
|
||||||
function fnTableStriped(_record: unknown, index: number): any {
|
|
||||||
return tableState.striped && index % 2 === 1 ? 'table-striped' : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**查询参数重置 */
|
/**查询参数重置 */
|
||||||
function fnQueryReset() {
|
function fnQueryReset() {
|
||||||
queryParams.ipaddr = '';
|
queryParams.ipaddr = '';
|
||||||
@@ -254,15 +246,6 @@ onMounted(() => {
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.zebra') }}</template>
|
|
||||||
<a-switch
|
|
||||||
v-model:checked="tableState.striped"
|
|
||||||
:checked-children="t('common.switch.show')"
|
|
||||||
:un-checked-children="t('common.switch.hide')"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
@@ -304,7 +287,6 @@ onMounted(() => {
|
|||||||
:loading="tableState.loading"
|
:loading="tableState.loading"
|
||||||
:data-source="tableState.data"
|
:data-source="tableState.data"
|
||||||
:size="tableState.size"
|
:size="tableState.size"
|
||||||
:row-class-name="fnTableStriped"
|
|
||||||
:pagination="tablePagination"
|
:pagination="tablePagination"
|
||||||
:scroll="{ x: true }"
|
:scroll="{ x: true }"
|
||||||
>
|
>
|
||||||
@@ -327,10 +309,6 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.table :deep(.table-striped) td {
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table :deep(.ant-pagination) {
|
.table :deep(.ant-pagination) {
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,341 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { reactive, onMounted, toRaw } from 'vue';
|
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
|
||||||
import { message, Modal } from 'ant-design-vue/lib';
|
|
||||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
|
||||||
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
|
||||||
import { ColumnsType } from 'ant-design-vue/lib/table';
|
|
||||||
import useI18n from '@/hooks/useI18n';
|
|
||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
|
||||||
import { listSession, logoutSession } from '@/api/monitor/session';
|
|
||||||
import { diffValue, parseDateToStr } from '@/utils/date-utils';
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
/**查询参数 */
|
|
||||||
let queryParams = reactive({
|
|
||||||
/**登录账号 */
|
|
||||||
accountId: '',
|
|
||||||
/**IP地址 */
|
|
||||||
ip: '',
|
|
||||||
/**排序字段 */
|
|
||||||
sortField: 'loginTime',
|
|
||||||
/**排序方式 */
|
|
||||||
sortOrder: 'desc',
|
|
||||||
/**当前页数 */
|
|
||||||
pageNum: 1,
|
|
||||||
/**每页条数 */
|
|
||||||
pageSize: 20,
|
|
||||||
});
|
|
||||||
|
|
||||||
/**查询参数重置 */
|
|
||||||
function fnQueryReset() {
|
|
||||||
queryParams = Object.assign(queryParams, {
|
|
||||||
accountId: '',
|
|
||||||
ip: '',
|
|
||||||
sortField: 'loginTime',
|
|
||||||
sortOrder: 'desc',
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 20,
|
|
||||||
});
|
|
||||||
tablePagination.current = 1;
|
|
||||||
tablePagination.pageSize = 20;
|
|
||||||
fnGetList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**表格状态类型 */
|
|
||||||
type TabeStateType = {
|
|
||||||
/**加载等待 */
|
|
||||||
loading: boolean;
|
|
||||||
/**紧凑型 */
|
|
||||||
size: SizeType;
|
|
||||||
/**搜索栏 */
|
|
||||||
seached: boolean;
|
|
||||||
/**记录数据 */
|
|
||||||
data: object[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**表格状态 */
|
|
||||||
let tableState: TabeStateType = reactive({
|
|
||||||
loading: false,
|
|
||||||
size: 'middle',
|
|
||||||
seached: true,
|
|
||||||
data: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/**表格字段列 */
|
|
||||||
let tableColumns: ColumnsType = [
|
|
||||||
{
|
|
||||||
title: t('common.rowId'),
|
|
||||||
dataIndex: 'id',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('views.monitor.session.userName'),
|
|
||||||
dataIndex: 'accountId',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('views.monitor.session.ipaddr'),
|
|
||||||
dataIndex: 'host',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('views.monitor.session.loginTime'),
|
|
||||||
dataIndex: 'loginTime',
|
|
||||||
align: 'center',
|
|
||||||
customRender(opt) {
|
|
||||||
if (!opt.value) return '';
|
|
||||||
return parseDateToStr(opt.value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('views.monitor.session.shakeTime'),
|
|
||||||
dataIndex: 'shakeTime',
|
|
||||||
align: 'center',
|
|
||||||
customRender(opt) {
|
|
||||||
if (!opt.value) return '';
|
|
||||||
return diffValue(new Date(), opt.value, 'minute');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('views.monitor.session.status'),
|
|
||||||
dataIndex: 'status',
|
|
||||||
align: 'center',
|
|
||||||
customRender(opt) {
|
|
||||||
if (opt.value === 'online') {
|
|
||||||
return t('views.monitor.session.online');
|
|
||||||
}
|
|
||||||
return t('views.monitor.session.offline');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('common.operate'),
|
|
||||||
key: 'id',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**表格分页器参数 */
|
|
||||||
let tablePagination = reactive({
|
|
||||||
/**当前页数 */
|
|
||||||
current: 1,
|
|
||||||
/**每页条数 */
|
|
||||||
pageSize: 20,
|
|
||||||
/**默认的每页条数 */
|
|
||||||
defaultPageSize: 20,
|
|
||||||
/**指定每页可以显示多少条 */
|
|
||||||
pageSizeOptions: ['10', '20', '50', '100'],
|
|
||||||
/**只有一页时是否隐藏分页器 */
|
|
||||||
hideOnSinglePage: false,
|
|
||||||
/**是否可以快速跳转至某页 */
|
|
||||||
showQuickJumper: true,
|
|
||||||
/**是否可以改变 pageSize */
|
|
||||||
showSizeChanger: true,
|
|
||||||
/**数据总数 */
|
|
||||||
total: 0,
|
|
||||||
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
|
|
||||||
onChange: (page: number, pageSize: number) => {
|
|
||||||
tablePagination.current = page;
|
|
||||||
tablePagination.pageSize = pageSize;
|
|
||||||
queryParams.pageNum = page;
|
|
||||||
queryParams.pageSize = pageSize;
|
|
||||||
fnGetList();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
/**表格紧凑型变更操作 */
|
|
||||||
function fnTableSize({ key }: MenuInfo) {
|
|
||||||
tableState.size = key as SizeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 强退按钮操作 */
|
|
||||||
function fnForceLogout(row: Record<string, string>) {
|
|
||||||
Modal.confirm({
|
|
||||||
title: t('common.tipTitle'),
|
|
||||||
content: t('views.monitor.session.logoutTip', { num: row.accountId }),
|
|
||||||
onOk() {
|
|
||||||
const hide = message.loading(t('common.loading'), 0);
|
|
||||||
logoutSession(row.id)
|
|
||||||
.then(res => {
|
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
|
||||||
message.success({
|
|
||||||
content: t('views.monitor.session.logoutSuccess', {
|
|
||||||
num: row.accountId,
|
|
||||||
}),
|
|
||||||
duration: 3,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
message.error({
|
|
||||||
content: `${res.msg}`,
|
|
||||||
duration: 3,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
hide();
|
|
||||||
fnGetList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**查询网元列表, pageNum初始页数 */
|
|
||||||
function fnGetList(pageNum?: number) {
|
|
||||||
if (tableState.loading) return;
|
|
||||||
tableState.loading = true;
|
|
||||||
if(pageNum){
|
|
||||||
queryParams.pageNum = pageNum;
|
|
||||||
}
|
|
||||||
listSession(toRaw(queryParams)).then(res => {
|
|
||||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
|
||||||
tablePagination.total = res.total;
|
|
||||||
tableState.data = res.rows;
|
|
||||||
if (tablePagination.total <=(queryParams.pageNum - 1) * tablePagination.pageSize &&queryParams.pageNum !== 1) {
|
|
||||||
tableState.loading = false;
|
|
||||||
fnGetList(queryParams.pageNum - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tableState.loading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 获取列表数据
|
|
||||||
fnGetList();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<PageContainer>
|
|
||||||
<a-card
|
|
||||||
v-show="tableState.seached"
|
|
||||||
:bordered="false"
|
|
||||||
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
|
||||||
>
|
|
||||||
<!-- 表格搜索栏 -->
|
|
||||||
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
|
||||||
<a-row :gutter="16">
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item
|
|
||||||
:label="t('views.monitor.session.userName')"
|
|
||||||
name="accountId "
|
|
||||||
>
|
|
||||||
<a-input
|
|
||||||
v-model:value="queryParams.accountId"
|
|
||||||
allow-clear
|
|
||||||
:placeholder="t('views.monitor.session.userNamePlease')"
|
|
||||||
></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item :label="t('views.monitor.session.ipaddr')" name="ip">
|
|
||||||
<a-input
|
|
||||||
v-model:value="queryParams.ip"
|
|
||||||
allow-clear
|
|
||||||
:placeholder="t('views.monitor.session.ipaddrPlease')"
|
|
||||||
></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
|
||||||
<a-form-item>
|
|
||||||
<a-space :size="8">
|
|
||||||
<a-button type="primary" @click.prevent="fnGetList(1)">
|
|
||||||
<template #icon>
|
|
||||||
<SearchOutlined />
|
|
||||||
</template>
|
|
||||||
{{ t('common.search') }}
|
|
||||||
</a-button>
|
|
||||||
<a-button type="default" @click.prevent="fnQueryReset">
|
|
||||||
<template #icon>
|
|
||||||
<ClearOutlined />
|
|
||||||
</template>
|
|
||||||
{{ t('common.reset') }}
|
|
||||||
</a-button>
|
|
||||||
</a-space>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-form>
|
|
||||||
</a-card>
|
|
||||||
|
|
||||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
|
||||||
<!-- 插槽-卡片左侧侧 -->
|
|
||||||
<template #title></template>
|
|
||||||
|
|
||||||
<!-- 插槽-卡片右侧 -->
|
|
||||||
<template #extra>
|
|
||||||
<a-space :size="8" align="center">
|
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.searchBarText') }}</template>
|
|
||||||
<a-switch
|
|
||||||
v-model:checked="tableState.seached"
|
|
||||||
:checked-children="t('common.switch.show')"
|
|
||||||
:un-checked-children="t('common.switch.hide')"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
|
||||||
<template #icon>
|
|
||||||
<ReloadOutlined />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.sizeText') }}</template>
|
|
||||||
<a-dropdown trigger="click" placement="bottomRight">
|
|
||||||
<a-button type="text">
|
|
||||||
<template #icon>
|
|
||||||
<ColumnHeightOutlined />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
<template #overlay>
|
|
||||||
<a-menu
|
|
||||||
:selected-keys="[tableState.size as string]"
|
|
||||||
@click="fnTableSize"
|
|
||||||
>
|
|
||||||
<a-menu-item key="default">
|
|
||||||
{{ t('common.size.default') }}
|
|
||||||
</a-menu-item>
|
|
||||||
<a-menu-item key="middle">
|
|
||||||
{{ t('common.size.middle') }}
|
|
||||||
</a-menu-item>
|
|
||||||
<a-menu-item key="small">
|
|
||||||
{{ t('common.size.small') }}
|
|
||||||
</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
</template>
|
|
||||||
</a-dropdown>
|
|
||||||
</a-tooltip>
|
|
||||||
</a-space>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 表格列表 -->
|
|
||||||
<a-table
|
|
||||||
class="table"
|
|
||||||
row-key="id"
|
|
||||||
:columns="tableColumns"
|
|
||||||
:loading="tableState.loading"
|
|
||||||
:data-source="tableState.data"
|
|
||||||
:size="tableState.size"
|
|
||||||
:pagination="tablePagination"
|
|
||||||
:scroll="{ x: true }"
|
|
||||||
>
|
|
||||||
<template #bodyCell="{ column, record }">
|
|
||||||
<template v-if="column.key === 'id'">
|
|
||||||
<a-button type="link" danger @click.prevent="fnForceLogout(record)">
|
|
||||||
<template #icon><LogoutOutlined /></template>
|
|
||||||
强退
|
|
||||||
</a-button>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</a-table>
|
|
||||||
</a-card>
|
|
||||||
</PageContainer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.table :deep(.ant-pagination) {
|
|
||||||
padding: 0 24px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -61,7 +61,7 @@ function fnGetList(refresh: boolean = false) {
|
|||||||
res.data.length > 0
|
res.data.length > 0
|
||||||
) {
|
) {
|
||||||
// 根网管
|
// 根网管
|
||||||
let rootNodeInfo = { neName: undefined };
|
let rootNodeInfo = { neName: "OMC_001" };
|
||||||
const nodes = [];
|
const nodes = [];
|
||||||
const edges = [];
|
const edges = [];
|
||||||
for (const item of res.data) {
|
for (const item of res.data) {
|
||||||
@@ -70,7 +70,7 @@ function fnGetList(refresh: boolean = false) {
|
|||||||
const nodeIndex = nodes.findIndex(v => v.id === item.neName);
|
const nodeIndex = nodes.findIndex(v => v.id === item.neName);
|
||||||
if (nodeIndex === -1) {
|
if (nodeIndex === -1) {
|
||||||
if (item.neType === 'OMC') {
|
if (item.neType === 'OMC') {
|
||||||
nodes.push({
|
nodes.unshift({
|
||||||
id: item.neName,
|
id: item.neName,
|
||||||
label: item.neName,
|
label: item.neName,
|
||||||
info: item,
|
info: item,
|
||||||
@@ -120,7 +120,7 @@ function fnGetList(refresh: boolean = false) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
edges.push({
|
edges.unshift({
|
||||||
source: item.neName,
|
source: item.neName,
|
||||||
target: rootNodeInfo.neName,
|
target: rootNodeInfo.neName,
|
||||||
label: `${item.neName}-${rootNodeInfo.neName}`,
|
label: `${item.neName}-${rootNodeInfo.neName}`,
|
||||||
@@ -140,6 +140,7 @@ function fnGetList(refresh: boolean = false) {
|
|||||||
})
|
})
|
||||||
.then(hasNeList => {
|
.then(hasNeList => {
|
||||||
if (!hasNeList) return;
|
if (!hasNeList) return;
|
||||||
|
console.log(graphG6Data)
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
// graphG6.value.get('canvas').set('localRefresh', true);
|
// graphG6.value.get('canvas').set('localRefresh', true);
|
||||||
graphG6.value.destroy();
|
graphG6.value.destroy();
|
||||||
|
|||||||
@@ -230,6 +230,23 @@ function handleRanderGraph(
|
|||||||
|
|
||||||
graphG6.value = graph;
|
graphG6.value = graph;
|
||||||
|
|
||||||
|
// 创建 ResizeObserver 实例
|
||||||
|
var observer = new ResizeObserver(function (entries) {
|
||||||
|
// 当元素大小发生变化时触发回调函数
|
||||||
|
entries.forEach(function (entry) {
|
||||||
|
if (!graphG6.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
graphG6.value.changeSize(
|
||||||
|
entry.contentRect.width,
|
||||||
|
entry.contentRect.height - 30
|
||||||
|
);
|
||||||
|
graphG6.value.fitCenter();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 监听元素大小变化
|
||||||
|
observer.observe(container);
|
||||||
|
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,10 +345,13 @@ function fnGraphDataLoad(reload: boolean = false) {
|
|||||||
} else {
|
} else {
|
||||||
handleRanderGraph(graphG6Dom.value, graphState.data);
|
handleRanderGraph(graphG6Dom.value, graphState.data);
|
||||||
}
|
}
|
||||||
fnGetState();
|
clearInterval(interval10s.value);
|
||||||
interval10s.value = setInterval(() => {
|
interval10s.value = null;
|
||||||
fnGetState(); // 获取网元状态
|
fnGetState().finally(() => {
|
||||||
}, 10_000);
|
interval10s.value = setInterval(() => {
|
||||||
|
fnGetState(); // 获取网元状态
|
||||||
|
}, 10_000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,6 +493,7 @@ onMounted(() => {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
ws.close();
|
ws.close();
|
||||||
clearInterval(interval10s.value);
|
clearInterval(interval10s.value);
|
||||||
|
interval10s.value = null;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
Menu,
|
Menu,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@antv/g6';
|
} from '@antv/g6';
|
||||||
import { ref } from 'vue';
|
import { onBeforeUnmount, ref } from 'vue';
|
||||||
import {
|
import {
|
||||||
edgeCubicAnimateCircleMove,
|
edgeCubicAnimateCircleMove,
|
||||||
edgeCubicAnimateLineDash,
|
edgeCubicAnimateLineDash,
|
||||||
@@ -29,7 +29,7 @@ export const graphEvent = ref<{
|
|||||||
type: string;
|
type: string;
|
||||||
target: HTMLElement | (IShapeBase & ICanvas);
|
target: HTMLElement | (IShapeBase & ICanvas);
|
||||||
item: Item | null;
|
item: Item | null;
|
||||||
}>();
|
} | null>(null);
|
||||||
|
|
||||||
/**图元素选择开始结束点 */
|
/**图元素选择开始结束点 */
|
||||||
export const selectSourceTargetOptions = ref<Record<string, any>[]>([]);
|
export const selectSourceTargetOptions = ref<Record<string, any>[]>([]);
|
||||||
@@ -592,6 +592,23 @@ export default function useGraph() {
|
|||||||
|
|
||||||
graphG6.value = graph;
|
graphG6.value = graph;
|
||||||
|
|
||||||
|
// 创建 ResizeObserver 实例
|
||||||
|
var observer = new ResizeObserver(function (entries) {
|
||||||
|
// 当元素大小发生变化时触发回调函数
|
||||||
|
entries.forEach(function (entry) {
|
||||||
|
if (!graphG6.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
graphG6.value.changeSize(
|
||||||
|
entry.contentRect.width,
|
||||||
|
entry.contentRect.height - 30
|
||||||
|
);
|
||||||
|
graphG6.value.fitCenter();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 监听元素大小变化
|
||||||
|
observer.observe(container);
|
||||||
|
|
||||||
// 图元素选择开始结束点数据
|
// 图元素选择开始结束点数据
|
||||||
fnSelectSourceTargetOptionsData();
|
fnSelectSourceTargetOptionsData();
|
||||||
|
|
||||||
@@ -605,6 +622,13 @@ export default function useGraph() {
|
|||||||
graphMode.value = graphG6.value.getCurrentMode();
|
graphMode.value = graphG6.value.getCurrentMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
graphG6.value = null;
|
||||||
|
graphEvent.value = null;
|
||||||
|
selectSourceTargetOptions.value = [];
|
||||||
|
selectComboOptions.value = [];
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
graphMode,
|
graphMode,
|
||||||
graphModeOptions,
|
graphModeOptions,
|
||||||
|
|||||||
@@ -0,0 +1,507 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, watch } from 'vue';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['update:data']);
|
||||||
|
const props = defineProps({
|
||||||
|
/**表单数据 */
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
/**根据网元显示配置项 */
|
||||||
|
ne: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
amf: false,
|
||||||
|
upf: false,
|
||||||
|
ims: false,
|
||||||
|
mme: false,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type StateType = {
|
||||||
|
/**表单数据 */
|
||||||
|
from: Record<string, any>;
|
||||||
|
/**根据网元显示配置项 */
|
||||||
|
hasNE: {
|
||||||
|
amf: boolean;
|
||||||
|
upf: boolean;
|
||||||
|
ims: boolean;
|
||||||
|
mme: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let state: StateType = reactive({
|
||||||
|
from: {
|
||||||
|
basic: {
|
||||||
|
plmnId: {
|
||||||
|
mcc: '001',
|
||||||
|
mnc: '01',
|
||||||
|
},
|
||||||
|
tac: '4388',
|
||||||
|
snssai: {
|
||||||
|
sst: '1',
|
||||||
|
sd: '000001',
|
||||||
|
},
|
||||||
|
dnn_data: 'internet',
|
||||||
|
dnn_ims: 'ims',
|
||||||
|
},
|
||||||
|
external: {
|
||||||
|
amfn2_ip: '192.168.8.120',
|
||||||
|
upfn3_ip: '192.168.8.190/24',
|
||||||
|
upfn3_gw: '192.168.1.1',
|
||||||
|
upfn6_ip: '192.168.8.191/24',
|
||||||
|
upfn6_gw: '192.168.1.1',
|
||||||
|
ue_pool: '10.2.1.0/24',
|
||||||
|
// 非指定属性
|
||||||
|
mmes1_ip: '192.168.8.220/20',
|
||||||
|
mmes10_ip: '172.16.5.221/24',
|
||||||
|
mmes11_ip: '172.16.5.220/24',
|
||||||
|
ims_sip_ip: '192.168.8.110',
|
||||||
|
upf_type: 'LightUPF',
|
||||||
|
upfn3_pci: '0000:00:00.0',
|
||||||
|
upfn3_mac: '00:00:00:00:00:00',
|
||||||
|
upfn6_pci: '0000:00:00.0',
|
||||||
|
upfn6_mac: '00:00:00:00:00:00',
|
||||||
|
},
|
||||||
|
sbi: {
|
||||||
|
omc_ip: '172.16.5.100',
|
||||||
|
ims_ip: '172.16.5.110',
|
||||||
|
amf_ip: '172.16.5.120',
|
||||||
|
ausf_ip: '172.16.5.130',
|
||||||
|
udm_ip: '172.16.5.140',
|
||||||
|
adb_ip: '0.0.0.0',
|
||||||
|
smf_ip: '172.16.5.150',
|
||||||
|
pcf_ip: '172.16.5.160',
|
||||||
|
nssf_ip: '172.16.5.170',
|
||||||
|
nrf_ip: '172.16.5.180',
|
||||||
|
upf_ip: '172.16.5.190',
|
||||||
|
lmf_ip: '172.16.5.200',
|
||||||
|
nef_ip: '172.16.5.210',
|
||||||
|
mme_ip: '172.16.5.220',
|
||||||
|
n3iwf_ip: '172.16.5.230',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hasNE: {
|
||||||
|
amf: false,
|
||||||
|
upf: false,
|
||||||
|
ims: false,
|
||||||
|
mme: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**监听数据 */
|
||||||
|
watch(
|
||||||
|
() => props.data,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
Object.assign(state.from, val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.ne,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
Object.assign(state.hasNE, val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => state.from,
|
||||||
|
val => {
|
||||||
|
if (val) emit('update:data', val);
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-form
|
||||||
|
name="para5GFileeFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 8 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="16" :md="16" :xs="24">
|
||||||
|
<a-divider orientation="left">Basic</a-divider>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item label="DNN_DATA" name="basic.dnn_data">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.basic.dnn_data"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title> DNN </template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="MCC" name="basic.plmnId.mcc">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.basic.plmnId.mcc"
|
||||||
|
placeholder="1-65535"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="SST" name="basic.snssai.sst">
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="state.from.basic.snssai.sst"
|
||||||
|
:min="1"
|
||||||
|
:max="3"
|
||||||
|
placeholder="1-3"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title> 1-3 </template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="TAC" name="basic.tac">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.basic.tac"
|
||||||
|
placeholder="1-65535"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item label="DNN_IMS" name="basic.dnn_ims">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.basic.dnn_ims"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="MNC" name="basic.plmnId.mnc">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.basic.plmnId.mnc"
|
||||||
|
placeholder="1-65535"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="SD" name="basic.snssai.sd">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.basic.snssai.sd"
|
||||||
|
placeholder="1-65535"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :lg="8" :md="8" :xs="24">
|
||||||
|
<a-divider orientation="left">OMC</a-divider>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="24" :md="24" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
label="EMS_IP"
|
||||||
|
name="sbi.omc_ip"
|
||||||
|
:required="true"
|
||||||
|
:validate-on-rule-change="false"
|
||||||
|
:validateTrigger="[]"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.sbi.omc_ip"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
Network Elemment send data tu EMS IP
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<template v-if="state.hasNE.amf">
|
||||||
|
<a-divider orientation="left">AMF</a-divider>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="24" :md="24" :xs="24">
|
||||||
|
<a-form-item label="N2_IP" name="external.amfn2_ip">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.amfn2_ip"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title> AMF N2 </template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :lg="16" :md="16" :xs="24" v-if="state.hasNE.upf">
|
||||||
|
<a-divider orientation="left">UPF</a-divider>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
label="UPF_TYPE"
|
||||||
|
name="external.upf_type"
|
||||||
|
help="Install of Standard or Light"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="state.from.external.upf_type"
|
||||||
|
:placeholder="t('common.selectPlease')"
|
||||||
|
>
|
||||||
|
<a-select-option value="StandardUPF">
|
||||||
|
StandardUPF
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option value="LightUPF">LightUPF</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item label="UE_POOL" name="external.ue_pool">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.ue_pool"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title> UE IP and maxk </template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item label="N3_IP" name="external.upfn3_ip">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.upfn3_ip"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title> netwrok ip </template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="N3_GW" name="external.upfn3_gw">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.upfn3_gw"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title> geteway </template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item label="N3_PCI" name="external.upfn3_pci">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.upfn3_pci"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
use `ip a` show info, to inet ip
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="N3_MAC" name="external.upfn3_mac">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.upfn3_mac"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
use `ip a` show info, to inet ip
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<template v-if="state.from.external.upf_type === 'StandardUPF'">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item label="N6_IP" name="external.upfn6_ip">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.upfn6_ip"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="N6_GW" name="external.upfn6_gw">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.upfn6_gw"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item label="N6_PCI" name="external.upfn6_pci">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.upfn6_pci"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="N6_MAC" name="external.upfn6_mac">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.upfn6_mac"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
</a-col>
|
||||||
|
|
||||||
|
<a-col :lg="8" :md="8" :xs="24">
|
||||||
|
<template v-if="state.hasNE.ims">
|
||||||
|
<a-divider orientation="left">IMS</a-divider>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="24" :md="24" :xs="24">
|
||||||
|
<a-form-item label="SIP_IP" name="external.ims_sip_ip">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.ims_sip_ip"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title> IMS SIP </template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="state.hasNE.mme">
|
||||||
|
<a-divider orientation="left">MME</a-divider>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="24" :md="24" :xs="24">
|
||||||
|
<a-form-item label="S1_IP" name="external.mmes1_ip">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.mmes1_ip"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
MME binded interface for S1-C or S1-MME communication
|
||||||
|
(S1AP), can be ethernet interface, virtual ethernet
|
||||||
|
interface, we don't advise wireless interfaces
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="S10_IP" name="external.mmes10_ip">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.mmes10_ip"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title> Interface </template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="S11_IP" name="external.mmes11_ip">
|
||||||
|
<a-input
|
||||||
|
v-model:value="state.from.external.mmes11_ip"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="50"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
MME binded interface for S11-U communication (GTPV1-U)
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</template>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, toRaw } from 'vue';
|
||||||
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
|
import { message } from 'ant-design-vue/lib';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import {
|
||||||
|
getPara5GFilee,
|
||||||
|
listNeInfo,
|
||||||
|
savePara5GFile,
|
||||||
|
updateNeInfo,
|
||||||
|
} from '@/api/ne/neInfo';
|
||||||
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
|
import Para5GForm from './components/Para5GForm.vue';
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
/**对象信息信息状态类型 */
|
||||||
|
type StateType = {
|
||||||
|
/**保存选择同步到网元窗 */
|
||||||
|
visible: boolean;
|
||||||
|
/**网元选择 */
|
||||||
|
neSelectOtions: any[];
|
||||||
|
/**同步到网元 */
|
||||||
|
sync: boolean;
|
||||||
|
syncNe: string[];
|
||||||
|
syncMsg: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: Record<string, any>;
|
||||||
|
/**OMC信息,需修改当前的IP */
|
||||||
|
omcInfo: Record<string, any>;
|
||||||
|
/**根据网元显示配置项 */
|
||||||
|
hasNE: {
|
||||||
|
amf: boolean;
|
||||||
|
upf: boolean;
|
||||||
|
ims: boolean;
|
||||||
|
mme: boolean;
|
||||||
|
};
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对象信息状态 */
|
||||||
|
let state: StateType = reactive({
|
||||||
|
visible: false,
|
||||||
|
neSelectOtions: [],
|
||||||
|
sync: false,
|
||||||
|
syncNe: [],
|
||||||
|
syncMsg: '',
|
||||||
|
from: {},
|
||||||
|
omcInfo: {},
|
||||||
|
hasNE: {
|
||||||
|
amf: false,
|
||||||
|
upf: false,
|
||||||
|
ims: false,
|
||||||
|
mme: false,
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框弹出确认执行函数*/
|
||||||
|
function fnModalOk() {
|
||||||
|
if (state.confirmLoading) return;
|
||||||
|
state.confirmLoading = true;
|
||||||
|
savePara5GFile({
|
||||||
|
content: toRaw(state.from),
|
||||||
|
syncNe: state.sync ? state.syncNe : [],
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (state.sync) {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
state.syncMsg = t('views.ne.neConfPara5G.syncNeDone');
|
||||||
|
} else {
|
||||||
|
state.syncMsg = res.msg;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.success(t('views.ne.neConfPara5G.saveOk'));
|
||||||
|
// 更新omc_ip
|
||||||
|
state.omcInfo.ip = state.from.sbi.omc_ip;
|
||||||
|
updateNeInfo(toRaw(state.omcInfo));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
state.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框弹出关闭执行函数*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
state.visible = false;
|
||||||
|
state.sync = false;
|
||||||
|
state.syncNe = [];
|
||||||
|
state.syncMsg = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**保存文件数据*/
|
||||||
|
function fnSaveData() {
|
||||||
|
state.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**获取文件数据*/
|
||||||
|
function fnGetData() {
|
||||||
|
state.confirmLoading = true;
|
||||||
|
Promise.all([
|
||||||
|
getPara5GFilee(),
|
||||||
|
listNeInfo({
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
}),
|
||||||
|
]).then(resArr => {
|
||||||
|
// 已保存的配置
|
||||||
|
if (resArr[0].code === RESULT_CODE_SUCCESS) {
|
||||||
|
Object.assign(state.from, resArr[0].data);
|
||||||
|
}
|
||||||
|
// 填充固定网元类型的ip
|
||||||
|
if (
|
||||||
|
resArr[1].code === RESULT_CODE_SUCCESS &&
|
||||||
|
Array.isArray(resArr[1].rows)
|
||||||
|
) {
|
||||||
|
for (const item of resArr[1].rows) {
|
||||||
|
switch (item.neType) {
|
||||||
|
case 'OMC':
|
||||||
|
state.from.sbi.omc_ip = item.ip;
|
||||||
|
Object.assign(state.omcInfo, item);
|
||||||
|
break;
|
||||||
|
case 'IMS':
|
||||||
|
state.from.sbi.ims_ip = item.ip;
|
||||||
|
// state.from.external.ims_sip_ip = item.ip;
|
||||||
|
state.hasNE.ims = true;
|
||||||
|
break;
|
||||||
|
case 'AMF':
|
||||||
|
state.from.sbi.amf_ip = item.ip;
|
||||||
|
state.hasNE.amf = true;
|
||||||
|
break;
|
||||||
|
case 'AUSF':
|
||||||
|
state.from.sbi.ausf_ip = item.ip;
|
||||||
|
break;
|
||||||
|
case 'UDM':
|
||||||
|
state.from.sbi.udm_ip = item.ip;
|
||||||
|
state.from.sbi.adb_ip = '0.0.0.0';
|
||||||
|
break;
|
||||||
|
case 'SMF':
|
||||||
|
state.from.sbi.smf_ip = item.ip;
|
||||||
|
break;
|
||||||
|
case 'PCF':
|
||||||
|
state.from.sbi.pcf_ip = item.ip;
|
||||||
|
break;
|
||||||
|
case 'NSSF':
|
||||||
|
state.from.sbi.nssf_ip = item.ip;
|
||||||
|
break;
|
||||||
|
case 'NRF':
|
||||||
|
state.from.sbi.nrf_ip = item.ip;
|
||||||
|
break;
|
||||||
|
case 'UPF':
|
||||||
|
state.from.sbi.upf_ip = item.ip;
|
||||||
|
state.hasNE.upf = true;
|
||||||
|
break;
|
||||||
|
case 'LMF':
|
||||||
|
state.from.sbi.lmf_ip = item.ip;
|
||||||
|
break;
|
||||||
|
case 'NEF':
|
||||||
|
state.from.sbi.nef_ip = item.ip;
|
||||||
|
break;
|
||||||
|
case 'MME':
|
||||||
|
state.from.sbi.mme_ip = item.ip;
|
||||||
|
if (item.ip.includes('.')) {
|
||||||
|
state.from.external.mmes11_ip = item.ip + '/24';
|
||||||
|
}
|
||||||
|
state.hasNE.mme = true;
|
||||||
|
break;
|
||||||
|
case 'N3IWF':
|
||||||
|
state.from.sbi.n3iwf_ip = item.ip;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
useNeInfoStore()
|
||||||
|
.fnNelist()
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||||
|
for (const row of res.data) {
|
||||||
|
state.neSelectOtions.push({
|
||||||
|
label: `[${row.neType} ${row.neId}] ${row.neName}`,
|
||||||
|
value: `${row.neType}@${row.neId}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.warning({
|
||||||
|
content: t('common.noData'),
|
||||||
|
duration: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
// 获取文件数据
|
||||||
|
fnGetData();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PageContainer>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<!-- 公共参数表单 -->
|
||||||
|
<Para5GForm v-model:data="state.from" :ne="state.hasNE"></Para5GForm>
|
||||||
|
|
||||||
|
<div style="padding: 24px 12px 0; text-align: end">
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
:loading="state.confirmLoading"
|
||||||
|
@click="fnSaveData()"
|
||||||
|
>
|
||||||
|
<template #icon><SaveOutlined /></template>
|
||||||
|
{{ t('views.ne.neConfPara5G.save') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
type="default"
|
||||||
|
:loading="state.confirmLoading"
|
||||||
|
@click.prevent="fnGetData()"
|
||||||
|
>
|
||||||
|
<template #icon><ReloadOutlined /></template>
|
||||||
|
{{ t('views.ne.neConfPara5G.reload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 保存选择同步网元 -->
|
||||||
|
<a-modal
|
||||||
|
width="500px"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:visible="state.visible"
|
||||||
|
:title="t('views.ne.neConfPara5G.title')"
|
||||||
|
:confirm-loading="state.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="syncNeModal"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 5 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-form-item :label="t('views.ne.neConfPara5G.sync')" name="sync">
|
||||||
|
<a-switch
|
||||||
|
:checked-children="t('common.switch.open')"
|
||||||
|
:un-checked-children="t('common.switch.shut')"
|
||||||
|
v-model:checked="state.sync"
|
||||||
|
:disabled="state.confirmLoading"
|
||||||
|
></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neConfPara5G.syncNe')"
|
||||||
|
name="syncNe"
|
||||||
|
v-if="state.sync"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="state.syncNe"
|
||||||
|
mode="multiple"
|
||||||
|
:placeholder="t('common.selectPlease')"
|
||||||
|
:max-tag-count="3"
|
||||||
|
:options="state.neSelectOtions"
|
||||||
|
>
|
||||||
|
<template #maxTagPlaceholder="omittedValues">
|
||||||
|
<span>+ {{ omittedValues.length }} ...</span>
|
||||||
|
</template>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="Sync Msg" name="syncMsg" v-if="state.syncMsg">
|
||||||
|
<a-textarea
|
||||||
|
:disabled="true"
|
||||||
|
:value="state.syncMsg"
|
||||||
|
:auto-size="{ minRows: 2, maxRows: 8 }"
|
||||||
|
style="background-color: transparent; color: rgba(0, 0, 0, 0.85)"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</PageContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
@@ -78,7 +78,7 @@ type TabeStateType = {
|
|||||||
let tableState: TabeStateType = reactive({
|
let tableState: TabeStateType = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
seached: true,
|
seached: false,
|
||||||
data: [],
|
data: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ let tableColumns: ColumnsType = [
|
|||||||
width: 100,
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.ne.neHost.createTime'),
|
title: t('common.createTime'),
|
||||||
dataIndex: 'createTime',
|
dataIndex: 'createTime',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 150,
|
width: 150,
|
||||||
@@ -287,7 +287,7 @@ const modalStateFrom = Form.useForm(
|
|||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 128,
|
max: 3000,
|
||||||
message: t('views.ne.neHost.privateKeyPlease'),
|
message: t('views.ne.neHost.privateKeyPlease'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -414,7 +414,8 @@ function fnModalTest() {
|
|||||||
const validateArr = ['title', 'addr', 'port', 'user'];
|
const validateArr = ['title', 'addr', 'port', 'user'];
|
||||||
if (form.authMode === '0') {
|
if (form.authMode === '0') {
|
||||||
validateArr.push('password');
|
validateArr.push('password');
|
||||||
} else {
|
}
|
||||||
|
if (form.authMode === '1') {
|
||||||
validateArr.push('privateKey');
|
validateArr.push('privateKey');
|
||||||
}
|
}
|
||||||
modalStateFrom
|
modalStateFrom
|
||||||
@@ -710,6 +711,7 @@ onMounted(() => {
|
|||||||
:min="10"
|
:min="10"
|
||||||
:max="65535"
|
:max="65535"
|
||||||
:step="1"
|
:step="1"
|
||||||
|
:maxlength="5"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
></a-input-number>
|
></a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -726,7 +728,7 @@ onMounted(() => {
|
|||||||
<a-input
|
<a-input
|
||||||
v-model:value="modalState.from.user"
|
v-model:value="modalState.from.user"
|
||||||
allow-clear
|
allow-clear
|
||||||
:maxlength="50"
|
:maxlength="32"
|
||||||
:placeholder="t('common.inputPlease')"
|
:placeholder="t('common.inputPlease')"
|
||||||
>
|
>
|
||||||
</a-input>
|
</a-input>
|
||||||
@@ -796,7 +798,7 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.ne.neHost.remark')"
|
:label="t('common.remark')"
|
||||||
name="remark"
|
name="remark"
|
||||||
:label-col="{ span: 3 }"
|
:label-col="{ span: 3 }"
|
||||||
:label-wrap="true"
|
:label-wrap="true"
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ type TabeStateType = {
|
|||||||
let tableState: TabeStateType = reactive({
|
let tableState: TabeStateType = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
seached: true,
|
seached: false,
|
||||||
data: [],
|
data: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ let tableColumns: ColumnsType = [
|
|||||||
width: 100,
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.ne.neHostCmd.createTime'),
|
title: t('common.createTime'),
|
||||||
dataIndex: 'createTime',
|
dataIndex: 'createTime',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 150,
|
width: 150,
|
||||||
@@ -572,7 +572,7 @@ onMounted(() => {
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.ne.neHostCmd.remark')"
|
:label="t('common.remark')"
|
||||||
name="remark"
|
name="remark"
|
||||||
:label-col="{ span: 3 }"
|
:label-col="{ span: 3 }"
|
||||||
:label-wrap="true"
|
:label-wrap="true"
|
||||||
@@ -582,6 +582,7 @@ onMounted(() => {
|
|||||||
:auto-size="{ minRows: 4, maxRows: 6 }"
|
:auto-size="{ minRows: 4, maxRows: 6 }"
|
||||||
:maxlength="450"
|
:maxlength="450"
|
||||||
:show-count="true"
|
:show-count="true"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
|
|||||||
@@ -0,0 +1,337 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, toRaw, watch } from 'vue';
|
||||||
|
import { Form, Modal, Upload, message } from 'ant-design-vue/lib';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||||
|
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||||
|
import {
|
||||||
|
exportSet,
|
||||||
|
importFile,
|
||||||
|
listServerFile,
|
||||||
|
} from '@/api/configManage/neManage';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
|
||||||
|
const props = defineProps({
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**网元ID */
|
||||||
|
neId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
neType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格所需option */
|
||||||
|
const neManageOption = reactive({
|
||||||
|
importType: [
|
||||||
|
{ label: t('views.ne.neInfo.backConf.server'), value: 'server' },
|
||||||
|
{ label: t('views.ne.neInfo.backConf.local'), value: 'local' },
|
||||||
|
],
|
||||||
|
serverFileName: <any[]>[],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**查询网元远程服务器备份文件 */
|
||||||
|
function typeChange(value: any) {
|
||||||
|
if (value === 'server') {
|
||||||
|
modalState.from.fileName = undefined;
|
||||||
|
listServerFile(modalState.from).then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||||
|
neManageOption.serverFileName = [];
|
||||||
|
res.data.forEach((item: any) => {
|
||||||
|
neManageOption.serverFileName.push({
|
||||||
|
label: item.fileName,
|
||||||
|
value: item.fileName,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
modalState.from.file = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
visibleByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: {
|
||||||
|
neType: string;
|
||||||
|
neId: string;
|
||||||
|
importType: 'local' | 'server';
|
||||||
|
file: File | null;
|
||||||
|
fileName: string | undefined;
|
||||||
|
};
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
/**上传文件 */
|
||||||
|
uploadFiles: any[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
visibleByEdit: false,
|
||||||
|
title: '配置文件导入',
|
||||||
|
from: {
|
||||||
|
neType: '',
|
||||||
|
neId: '',
|
||||||
|
importType: 'local',
|
||||||
|
file: null,
|
||||||
|
fileName: undefined,
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
uploadFiles: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
file: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.neInfo.backConf.filePlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
fileName: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.neInfo.backConf.fileNamePlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
let validateName = ['importType'];
|
||||||
|
if (from.importType === 'local') {
|
||||||
|
validateName.push('file');
|
||||||
|
} else {
|
||||||
|
validateName.push('fileName');
|
||||||
|
}
|
||||||
|
|
||||||
|
modalStateFrom
|
||||||
|
.validate(validateName)
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
importFile(from)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
// 返回无引用信息
|
||||||
|
emit('ok', JSON.parse(JSON.stringify(from)));
|
||||||
|
fnModalCancel();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.visibleByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
modalState.uploadFiles = [];
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:visible', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩 */
|
||||||
|
function fnBeforeUploadFile(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
if (!file.name.endsWith('.zip')) {
|
||||||
|
const msg = `${t('components.UploadModal.onlyAllow')} .zip`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
const isLt3M = file.size / 1024 / 1024 < 100;
|
||||||
|
if (!isLt3M) {
|
||||||
|
const msg = `${t('components.UploadModal.allowFilter')} 100MB`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件 */
|
||||||
|
function fnUploadFile(up: UploadRequestOption) {
|
||||||
|
// 改为完成状态
|
||||||
|
const file = modalState.uploadFiles[0];
|
||||||
|
file.percent = 100;
|
||||||
|
file.status = 'done';
|
||||||
|
// 预置到表单
|
||||||
|
modalState.from.file = up.file as File;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
if (props.neType && props.neId) {
|
||||||
|
modalState.from.neType = props.neType;
|
||||||
|
modalState.from.neId = props.neId;
|
||||||
|
modalState.title = t('views.ne.neInfo.backConf.title');
|
||||||
|
modalState.visibleByEdit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网元导出配置
|
||||||
|
* @param row 网元编号ID
|
||||||
|
*/
|
||||||
|
function fnExportConf(neType: string, neId: string) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neInfo.backConf.exportTip'),
|
||||||
|
onOk() {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
exportSet({ neType, neId })
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('views.ne.neInfo.backConf.exportMsg'), 3);
|
||||||
|
} else {
|
||||||
|
message.error(`${res.msg}`, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 给组件设置属性 ref="xxxBackConf"
|
||||||
|
// setup内使用 const xxxBackConf = ref();
|
||||||
|
defineExpose({
|
||||||
|
/**导出文件 */
|
||||||
|
exportConf: fnExportConf,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
width="800px"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:visible="modalState.visibleByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form name="modalStateFrom" layout="horizontal" :label-col="{ span: 6 }">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.neType')"
|
||||||
|
name="neType"
|
||||||
|
v-bind="modalStateFrom.validateInfos.neType"
|
||||||
|
>
|
||||||
|
{{ modalState.from.neType }}
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.backConf.importType')"
|
||||||
|
name="importType"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="modalState.from.importType"
|
||||||
|
default-value="server"
|
||||||
|
:options="neManageOption.importType"
|
||||||
|
@change="typeChange"
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.neId')"
|
||||||
|
name="neId"
|
||||||
|
v-bind="modalStateFrom.validateInfos.neId"
|
||||||
|
>
|
||||||
|
{{ modalState.from.neId }}
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.backConf.server')"
|
||||||
|
name="fileName"
|
||||||
|
v-bind="modalStateFrom.validateInfos.fileName"
|
||||||
|
v-if="modalState.from.importType === 'server'"
|
||||||
|
>
|
||||||
|
<a-select
|
||||||
|
v-model:value="modalState.from.fileName"
|
||||||
|
:options="neManageOption.serverFileName"
|
||||||
|
:placeholder="t('common.selectPlease')"
|
||||||
|
>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.backConf.local')"
|
||||||
|
name="file"
|
||||||
|
v-bind="modalStateFrom.validateInfos.file"
|
||||||
|
v-if="modalState.from.importType === 'local'"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFiles"
|
||||||
|
accept=".zip"
|
||||||
|
list-type="text"
|
||||||
|
:max-count="1"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: false,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
:before-upload="fnBeforeUploadFile"
|
||||||
|
:custom-request="fnUploadFile"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neInfo.backConf.localUpload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted, toRaw, watch } from 'vue';
|
import { reactive, onMounted, toRaw, watch } from 'vue';
|
||||||
import { message, Form } from 'ant-design-vue/lib';
|
import { message, Form, Modal } from 'ant-design-vue/lib';
|
||||||
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 useNeInfoStore from '@/store/modules/neinfo';
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
import { getNeInfo, addNeInfo, updateNeInfo } from '@/api/ne/neInfo';
|
|
||||||
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||||
import { testNeHost } from '@/api/ne/neHost';
|
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
|
||||||
|
import { getNeInfo, addNeInfo, updateNeInfo } from '@/api/ne/neInfo';
|
||||||
|
import { neHostAuthorizedRSA, testNeHost } from '@/api/ne/neHost';
|
||||||
import useDictStore from '@/store/modules/dict';
|
import useDictStore from '@/store/modules/dict';
|
||||||
const { getDict } = useDictStore();
|
const { getDict } = useDictStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
@@ -37,10 +38,10 @@ let dict: {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对话框弹出测试连接
|
* 测试主机连接
|
||||||
*/
|
*/
|
||||||
function fnModalTest(row: Record<string, any>) {
|
function fnHostTest(row: Record<string, any>) {
|
||||||
if (modalState.confirmLoading) return;
|
if (modalState.confirmLoading || !row.addr) return;
|
||||||
modalState.confirmLoading = true;
|
modalState.confirmLoading = true;
|
||||||
const hide = message.loading(t('common.loading'), 0);
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
testNeHost(row)
|
testNeHost(row)
|
||||||
@@ -63,6 +64,27 @@ function fnModalTest(row: Record<string, any>) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**测试主机连接-免密直连 */
|
||||||
|
function fnHostAuthorized(row: Record<string, any>) {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neHost.authRSATip'),
|
||||||
|
onOk: () => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
neHostAuthorizedRSA(row).then(res => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
} else {
|
||||||
|
message.error(t('common.operateErr'), 3);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**对话框对象信息状态类型 */
|
/**对话框对象信息状态类型 */
|
||||||
type ModalStateType = {
|
type ModalStateType = {
|
||||||
/**新增框或修改框是否显示 */
|
/**新增框或修改框是否显示 */
|
||||||
@@ -82,16 +104,17 @@ let modalState: ModalStateType = reactive({
|
|||||||
from: {
|
from: {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
neId: '001',
|
neId: '001',
|
||||||
neType: 'OMC',
|
neType: 'AMF',
|
||||||
neName: '',
|
neName: '',
|
||||||
ip: '',
|
ip: '',
|
||||||
port: 3030,
|
port: 33030,
|
||||||
pvFlag: 'PNF',
|
pvFlag: 'PNF',
|
||||||
rmUid: '4400HX1OMC001',
|
rmUid: '4400HXAMF001',
|
||||||
neAddress: '',
|
neAddress: '',
|
||||||
dn: '',
|
dn: '',
|
||||||
vendorName: '',
|
vendorName: '',
|
||||||
province: '',
|
province: '',
|
||||||
|
remark: '',
|
||||||
// 主机
|
// 主机
|
||||||
hosts: [
|
hosts: [
|
||||||
{
|
{
|
||||||
@@ -132,36 +155,58 @@ const modalStateFrom = Form.useForm(
|
|||||||
neType: [
|
neType: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入网元类型',
|
message: t('views.ne.common.neTypePlease'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
neId: [
|
neId: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入网元标识',
|
message: t('views.ne.common.neIdPlease'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
rmUid: [
|
rmUid: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入资源唯一标识',
|
message: t('views.ne.common.rmUidPlease'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ip: [
|
ip: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入网元IP地址',
|
validator: modalStateFromEqualIPV4AndIPV6,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
neName: [
|
neName: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入网元名称',
|
message: t('views.ne.common.neNamePlease'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**表单验证IP地址是否有效 */
|
||||||
|
function modalStateFromEqualIPV4AndIPV6(
|
||||||
|
rule: Record<string, any>,
|
||||||
|
value: string,
|
||||||
|
callback: (error?: string) => void
|
||||||
|
) {
|
||||||
|
if (!value) {
|
||||||
|
return Promise.reject(t('views.ne.common.ipAddrPlease'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.indexOf('.') === -1 && value.indexOf(':') === -1) {
|
||||||
|
return Promise.reject(t('valid.ipPlease'));
|
||||||
|
}
|
||||||
|
if (value.indexOf('.') !== -1 && !regExpIPv4.test(value)) {
|
||||||
|
return Promise.reject(t('valid.ipv4Reg'));
|
||||||
|
}
|
||||||
|
if (value.indexOf(':') !== -1 && !regExpIPv6.test(value)) {
|
||||||
|
return Promise.reject(t('valid.ipv6Reg'));
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对话框弹出显示为 新增或者修改
|
* 对话框弹出显示为 新增或者修改
|
||||||
* @param editId 网元id, 不传为新增
|
* @param editId 网元id, 不传为新增
|
||||||
@@ -169,7 +214,7 @@ const modalStateFrom = Form.useForm(
|
|||||||
function fnModalVisibleByEdit(editId: string) {
|
function fnModalVisibleByEdit(editId: string) {
|
||||||
if (!editId) {
|
if (!editId) {
|
||||||
modalStateFrom.resetFields();
|
modalStateFrom.resetFields();
|
||||||
modalState.title = t('views.configManage.neManage.addNe');
|
modalState.title = t('views.ne.neInfo.addTitle');
|
||||||
modalState.visibleByEdit = true;
|
modalState.visibleByEdit = true;
|
||||||
} else {
|
} else {
|
||||||
if (modalState.confirmLoading) return;
|
if (modalState.confirmLoading) return;
|
||||||
@@ -179,8 +224,8 @@ function fnModalVisibleByEdit(editId: string) {
|
|||||||
modalState.confirmLoading = false;
|
modalState.confirmLoading = false;
|
||||||
hide();
|
hide();
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
modalState.from = Object.assign(modalState.from, res.data);
|
Object.assign(modalState.from, res.data);
|
||||||
modalState.title = '编辑网元信息';
|
modalState.title = t('views.ne.neInfo.editTitle');
|
||||||
modalState.visibleByEdit = true;
|
modalState.visibleByEdit = true;
|
||||||
} else {
|
} else {
|
||||||
message.error(t('common.getInfoFail'), 2);
|
message.error(t('common.getInfoFail'), 2);
|
||||||
@@ -204,17 +249,14 @@ function fnModalOk() {
|
|||||||
result
|
result
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
message.success({
|
message.success(t('common.operateOk'), 3);
|
||||||
content: '操作成功',
|
|
||||||
duration: 3,
|
|
||||||
});
|
|
||||||
// 刷新缓存的网元信息
|
// 刷新缓存的网元信息
|
||||||
useNeInfoStore().fnRefreshNelist();
|
useNeInfoStore().fnRefreshNelist();
|
||||||
emit('ok');
|
emit('ok');
|
||||||
fnModalCancel();
|
fnModalCancel();
|
||||||
} else {
|
} else {
|
||||||
message.error({
|
message.error({
|
||||||
content: `${t('views.configManage.neManage.operFail')}`,
|
content: `${res.msg}`,
|
||||||
duration: 3,
|
duration: 3,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -235,8 +277,10 @@ function fnModalOk() {
|
|||||||
*/
|
*/
|
||||||
function fnModalCancel() {
|
function fnModalCancel() {
|
||||||
modalState.visibleByEdit = false;
|
modalState.visibleByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
modalStateFrom.resetFields();
|
modalStateFrom.resetFields();
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
|
emit('update:visible', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -325,7 +369,7 @@ onMounted(() => {
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.configManage.neManage.neType')"
|
:label="t('views.ne.common.neType')"
|
||||||
name="neType"
|
name="neType"
|
||||||
v-bind="modalStateFrom.validateInfos.neType"
|
v-bind="modalStateFrom.validateInfos.neType"
|
||||||
>
|
>
|
||||||
@@ -342,7 +386,7 @@ onMounted(() => {
|
|||||||
<template #prefix>
|
<template #prefix>
|
||||||
<a-tooltip placement="topLeft">
|
<a-tooltip placement="topLeft">
|
||||||
<template #title>
|
<template #title>
|
||||||
{{ t('views.configManage.neManage.neTypeTip') }}
|
{{ t('views.ne.common.neTypeTip') }}
|
||||||
</template>
|
</template>
|
||||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
@@ -353,7 +397,7 @@ onMounted(() => {
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.configManage.neManage.pvflag')"
|
:label="t('views.ne.neInfo.pvflag')"
|
||||||
name="pvFlag"
|
name="pvFlag"
|
||||||
v-bind="modalStateFrom.validateInfos.pvFlag"
|
v-bind="modalStateFrom.validateInfos.pvFlag"
|
||||||
>
|
>
|
||||||
@@ -361,10 +405,10 @@ onMounted(() => {
|
|||||||
v-model:value="modalState.from.pvFlag"
|
v-model:value="modalState.from.pvFlag"
|
||||||
default-value="PNF"
|
default-value="PNF"
|
||||||
>
|
>
|
||||||
<a-select-opt-group :label="t('views.configManage.neManage.pnf')">
|
<a-select-opt-group :label="t('views.ne.neInfo.pnf')">
|
||||||
<a-select-option value="PNF">PNF</a-select-option>
|
<a-select-option value="PNF">PNF</a-select-option>
|
||||||
</a-select-opt-group>
|
</a-select-opt-group>
|
||||||
<a-select-opt-group :label="t('views.configManage.neManage.vnf')">
|
<a-select-opt-group :label="t('views.ne.neInfo.vnf')">
|
||||||
<a-select-option value="VNF">VNF</a-select-option>
|
<a-select-option value="VNF">VNF</a-select-option>
|
||||||
</a-select-opt-group>
|
</a-select-opt-group>
|
||||||
</a-select>
|
</a-select>
|
||||||
@@ -375,7 +419,7 @@ onMounted(() => {
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.configManage.neManage.neId')"
|
:label="t('views.ne.common.neId')"
|
||||||
name="neId"
|
name="neId"
|
||||||
v-bind="modalStateFrom.validateInfos.neId"
|
v-bind="modalStateFrom.validateInfos.neId"
|
||||||
>
|
>
|
||||||
@@ -384,12 +428,21 @@ onMounted(() => {
|
|||||||
allow-clear
|
allow-clear
|
||||||
:placeholder="t('common.inputPlease')"
|
:placeholder="t('common.inputPlease')"
|
||||||
:maxlength="32"
|
:maxlength="32"
|
||||||
></a-input>
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
{{ t('views.ne.common.neIdTip') }}
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.configManage.neManage.neName')"
|
:label="t('views.ne.common.neName')"
|
||||||
name="neName"
|
name="neName"
|
||||||
v-bind="modalStateFrom.validateInfos.neName"
|
v-bind="modalStateFrom.validateInfos.neName"
|
||||||
>
|
>
|
||||||
@@ -407,7 +460,7 @@ onMounted(() => {
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.configManage.neManage.ip')"
|
:label="t('views.ne.common.ipAddr')"
|
||||||
name="ip"
|
name="ip"
|
||||||
v-bind="modalStateFrom.validateInfos.ip"
|
v-bind="modalStateFrom.validateInfos.ip"
|
||||||
>
|
>
|
||||||
@@ -422,7 +475,7 @@ onMounted(() => {
|
|||||||
<a-tooltip placement="topLeft">
|
<a-tooltip placement="topLeft">
|
||||||
<template #title>
|
<template #title>
|
||||||
<div>
|
<div>
|
||||||
{{ t('views.ne.neInfo.ipAddr') }}
|
{{ t('views.ne.common.ipAddrTip') }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
@@ -433,7 +486,7 @@ onMounted(() => {
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.configManage.neManage.port')"
|
:label="t('views.ne.common.port')"
|
||||||
name="port"
|
name="port"
|
||||||
v-bind="modalStateFrom.validateInfos.port"
|
v-bind="modalStateFrom.validateInfos.port"
|
||||||
>
|
>
|
||||||
@@ -442,12 +495,13 @@ onMounted(() => {
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="65535"
|
:max="65535"
|
||||||
|
:maxlength="5"
|
||||||
placeholder="<=65535"
|
placeholder="<=65535"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<a-tooltip placement="topLeft">
|
<a-tooltip placement="topLeft">
|
||||||
<template #title>
|
<template #title>
|
||||||
<div>{{ t('views.configManage.neManage.portTip') }}</div>
|
<div>{{ t('views.ne.common.portTip') }}</div>
|
||||||
</template>
|
</template>
|
||||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
@@ -458,7 +512,7 @@ onMounted(() => {
|
|||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.configManage.neManage.uid')"
|
:label="t('views.ne.common.rmUid')"
|
||||||
name="rmUid"
|
name="rmUid"
|
||||||
v-bind="modalStateFrom.validateInfos.rmUid"
|
v-bind="modalStateFrom.validateInfos.rmUid"
|
||||||
:label-col="{ span: 3 }"
|
:label-col="{ span: 3 }"
|
||||||
@@ -474,7 +528,7 @@ onMounted(() => {
|
|||||||
<a-tooltip placement="topLeft">
|
<a-tooltip placement="topLeft">
|
||||||
<template #title>
|
<template #title>
|
||||||
<div>
|
<div>
|
||||||
{{ t('views.ne.neInfo.rmUID') }}
|
{{ t('views.ne.common.rmUidTip') }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
@@ -485,10 +539,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item :label="t('views.ne.neInfo.neAddress')" name="neAddress">
|
||||||
:label="t('views.configManage.neManage.mac')"
|
|
||||||
name="neAddress"
|
|
||||||
>
|
|
||||||
<a-input
|
<a-input
|
||||||
v-model:value="modalState.from.neAddress"
|
v-model:value="modalState.from.neAddress"
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -498,7 +549,7 @@ onMounted(() => {
|
|||||||
<template #prefix>
|
<template #prefix>
|
||||||
<a-tooltip placement="topLeft">
|
<a-tooltip placement="topLeft">
|
||||||
<template #title>
|
<template #title>
|
||||||
<div>{{ t('views.configManage.neManage.macTip') }}</div>
|
<div>{{ t('views.ne.neInfo.neAddressTip') }}</div>
|
||||||
</template>
|
</template>
|
||||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
@@ -507,7 +558,7 @@ onMounted(() => {
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item :label="t('views.configManage.neManage.dn')" name="dn">
|
<a-form-item :label="t('views.ne.neInfo.dn')" name="dn">
|
||||||
<a-input
|
<a-input
|
||||||
v-model:value="modalState.from.dn"
|
v-model:value="modalState.from.dn"
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -521,7 +572,7 @@ onMounted(() => {
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.configManage.neManage.vendorName')"
|
:label="t('views.ne.neInfo.vendorName')"
|
||||||
name="vendorName"
|
name="vendorName"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
@@ -534,10 +585,7 @@ onMounted(() => {
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item :label="t('views.ne.neInfo.province')" name="province">
|
||||||
:label="t('views.configManage.neManage.province')"
|
|
||||||
name="province"
|
|
||||||
>
|
|
||||||
<a-input
|
<a-input
|
||||||
v-model:value="modalState.from.province"
|
v-model:value="modalState.from.province"
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -548,11 +596,24 @@ onMounted(() => {
|
|||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('common.remark')"
|
||||||
|
:label-col="{ span: 3 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="modalState.from.remark"
|
||||||
|
:auto-size="{ minRows: 1, maxRows: 6 }"
|
||||||
|
:maxlength="450"
|
||||||
|
:show-count="true"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 主机连接配置 -->
|
||||||
<a-divider orientation="left">
|
<a-divider orientation="left">
|
||||||
{{ t('views.ne.neInfo.hostConfig') }}
|
{{ t('views.ne.neInfo.hostConfig') }}
|
||||||
</a-divider>
|
</a-divider>
|
||||||
|
|
||||||
<!-- 主机连接配置 -->
|
|
||||||
<a-collapse class="collapse" ghost>
|
<a-collapse class="collapse" ghost>
|
||||||
<a-collapse-panel
|
<a-collapse-panel
|
||||||
v-for="host in modalState.from.hosts"
|
v-for="host in modalState.from.hosts"
|
||||||
@@ -578,6 +639,7 @@ onMounted(() => {
|
|||||||
:min="10"
|
:min="10"
|
||||||
:max="65535"
|
:max="65535"
|
||||||
:step="1"
|
:step="1"
|
||||||
|
:maxlength="5"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
></a-input-number>
|
></a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -590,7 +652,7 @@ onMounted(() => {
|
|||||||
<a-input
|
<a-input
|
||||||
v-model:value="host.user"
|
v-model:value="host.user"
|
||||||
allow-clear
|
allow-clear
|
||||||
:maxlength="50"
|
:maxlength="32"
|
||||||
:placeholder="t('common.inputPlease')"
|
:placeholder="t('common.inputPlease')"
|
||||||
>
|
>
|
||||||
</a-input>
|
</a-input>
|
||||||
@@ -653,7 +715,7 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.ne.neHost.remark')"
|
:label="t('common.remark')"
|
||||||
:label-col="{ span: 3 }"
|
:label-col="{ span: 3 }"
|
||||||
:label-wrap="true"
|
:label-wrap="true"
|
||||||
>
|
>
|
||||||
@@ -675,11 +737,20 @@ onMounted(() => {
|
|||||||
<a-button
|
<a-button
|
||||||
type="primary"
|
type="primary"
|
||||||
shape="round"
|
shape="round"
|
||||||
@click="fnModalTest(host)"
|
@click="fnHostTest(host)"
|
||||||
:loading="modalState.confirmLoading"
|
:loading="modalState.confirmLoading"
|
||||||
>
|
>
|
||||||
<template #icon><LinkOutlined /></template>
|
<template #icon><LinkOutlined /></template>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click="fnHostAuthorized(host)"
|
||||||
|
:loading="modalState.confirmLoading"
|
||||||
|
v-if="host.hostType === 'ssh' && host.authMode !== '2'"
|
||||||
|
>
|
||||||
|
{{ t('views.ne.neHost.authRSA') }}
|
||||||
|
</a-button>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
</a-collapse>
|
</a-collapse>
|
||||||
|
|||||||
@@ -0,0 +1,307 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, toRaw, watch } from 'vue';
|
||||||
|
import { message, Form } from 'ant-design-vue/lib';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { getOAMFile, saveOAMFile } from '@/api/ne/neInfo';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
|
||||||
|
const props = defineProps({
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**网元ID */
|
||||||
|
neId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
neType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
visibleByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**是否同步 */
|
||||||
|
sync: boolean;
|
||||||
|
/**表单数据 */
|
||||||
|
from: Record<string, any>;
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
visibleByEdit: false,
|
||||||
|
title: 'OAM Configuration',
|
||||||
|
sync: true,
|
||||||
|
from: {
|
||||||
|
oamEnable: true,
|
||||||
|
oamPort: 33030,
|
||||||
|
snmpEnable: true,
|
||||||
|
snmpPort: 4957,
|
||||||
|
kpiEnable: true,
|
||||||
|
kpiTimer: 60,
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
kpiTimer: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.neInfo.oam.kpiTimerPlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 新增或者修改
|
||||||
|
* @param neType 网元类型
|
||||||
|
* @param neId 网元ID
|
||||||
|
*/
|
||||||
|
function fnModalVisibleByTypeAndId(neType: string, neId: string) {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
getOAMFile(neType, neId)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
const data = res.data;
|
||||||
|
Object.assign(modalState.from, {
|
||||||
|
oamEnable: data.oamConfig.enable,
|
||||||
|
oamPort: data.oamConfig.port,
|
||||||
|
snmpEnable: data.snmpConfig.enable,
|
||||||
|
snmpPort: data.snmpConfig.port,
|
||||||
|
kpiEnable: data.kpiConfig.enable,
|
||||||
|
kpiTimer: data.kpiConfig.timer,
|
||||||
|
});
|
||||||
|
modalState.title = t('views.ne.neInfo.oam.title');
|
||||||
|
modalState.visibleByEdit = true;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
saveOAMFile({
|
||||||
|
neType: props.neType,
|
||||||
|
neId: props.neId,
|
||||||
|
content: from,
|
||||||
|
sync: modalState.sync,
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
emit('ok');
|
||||||
|
fnModalCancel();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.visibleByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:visible', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
if (props.neType && props.neId) {
|
||||||
|
fnModalVisibleByTypeAndId(props.neType, props.neId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DraggableModal
|
||||||
|
width="500px"
|
||||||
|
:body-style="{ maxHeight: '650px', 'overflow-y': 'auto' }"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:visible="modalState.visibleByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 12 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.sync')"
|
||||||
|
name="sync"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-switch
|
||||||
|
:checked-children="t('common.switch.open')"
|
||||||
|
:un-checked-children="t('common.switch.shut')"
|
||||||
|
v-model:checked="modalState.sync"
|
||||||
|
></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-collapse class="collapse" ghost>
|
||||||
|
<a-collapse-panel header="OAM">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.oamEnable')"
|
||||||
|
name="oamEnable"
|
||||||
|
>
|
||||||
|
<a-switch
|
||||||
|
:checked-children="t('common.switch.open')"
|
||||||
|
:un-checked-children="t('common.switch.shut')"
|
||||||
|
v-model:checked="modalState.from.oamEnable"
|
||||||
|
></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.oamPort')"
|
||||||
|
name="oamPort"
|
||||||
|
v-bind="modalStateFrom.validateInfos.oamPort"
|
||||||
|
>
|
||||||
|
<a-input-number
|
||||||
|
:min="3000"
|
||||||
|
:max="65535"
|
||||||
|
:step="1"
|
||||||
|
:maxlength="5"
|
||||||
|
v-model:value="modalState.from.oamPort"
|
||||||
|
style="width: 100%"
|
||||||
|
></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-collapse-panel>
|
||||||
|
<a-collapse-panel header="SNMP">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.snmpEnable')"
|
||||||
|
name="snmpEnable"
|
||||||
|
>
|
||||||
|
<a-switch
|
||||||
|
:checked-children="t('common.switch.open')"
|
||||||
|
:un-checked-children="t('common.switch.shut')"
|
||||||
|
v-model:checked="modalState.from.snmpEnable"
|
||||||
|
></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.snmpPort')"
|
||||||
|
name="snmpPort"
|
||||||
|
v-bind="modalStateFrom.validateInfos.snmpPort"
|
||||||
|
>
|
||||||
|
<a-input-number
|
||||||
|
:min="3000"
|
||||||
|
:max="65535"
|
||||||
|
:step="1"
|
||||||
|
:maxlength="5"
|
||||||
|
v-model:value="modalState.from.snmpPort"
|
||||||
|
style="width: 100%"
|
||||||
|
></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-collapse-panel>
|
||||||
|
<a-collapse-panel header="KPI">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.kpiEnable')"
|
||||||
|
name="kpiEnable"
|
||||||
|
>
|
||||||
|
<a-switch
|
||||||
|
:checked-children="t('common.switch.open')"
|
||||||
|
:un-checked-children="t('common.switch.shut')"
|
||||||
|
v-model:checked="modalState.from.kpiEnable"
|
||||||
|
></a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neInfo.oam.kpiTimer')"
|
||||||
|
name="kpiTimer"
|
||||||
|
v-bind="modalStateFrom.validateInfos.kpiTimer"
|
||||||
|
>
|
||||||
|
<a-input-number
|
||||||
|
:min="5"
|
||||||
|
:max="3600"
|
||||||
|
:step="1"
|
||||||
|
:maxlength="4"
|
||||||
|
v-model:value="modalState.from.kpiTimer"
|
||||||
|
style="width: 100%"
|
||||||
|
></a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-collapse-panel>
|
||||||
|
</a-collapse>
|
||||||
|
</a-form>
|
||||||
|
</DraggableModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.collapse :deep(.ant-collapse-item) > .ant-collapse-header {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
.collapse-header {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
import { restartNf, startNf, stopNf } from '@/api/configManage/neManage';
|
|
||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
import { Modal, message } from 'ant-design-vue/lib';
|
import { Modal, message } from 'ant-design-vue/lib';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { updateNeConfigReload } from '@/api/configManage/configParam';
|
import { updateNeConfigReload } from '@/api/configManage/configParam';
|
||||||
|
import { serviceNeAction } from '@/api/ne/neInfo';
|
||||||
|
import useLockedStore from '@/store/modules/locked';
|
||||||
|
|
||||||
export default function useNeOptions() {
|
export default function useNeOptions() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const lockedStore = useLockedStore();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网元启动
|
* 网元启动
|
||||||
@@ -16,30 +18,24 @@ export default function useNeOptions() {
|
|||||||
function fnNeStart(row: Record<string, any>) {
|
function fnNeStart(row: Record<string, any>) {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: t('common.tipTitle'),
|
title: t('common.tipTitle'),
|
||||||
content: t('views.configManage.neManage.totalSure', {
|
content: t('views.ne.common.startTip'),
|
||||||
msg: row.neName,
|
|
||||||
oper: t('views.configManage.neManage.start'),
|
|
||||||
}),
|
|
||||||
onOk() {
|
onOk() {
|
||||||
const key = 'startNf';
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
message.loading({ content: t('common.loading'), key });
|
serviceNeAction({
|
||||||
startNf(row).then(res => {
|
neType: row.neType,
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
neId: row.neId,
|
||||||
message.success({
|
action: 'start',
|
||||||
content: t('common.msgSuccess', {
|
})
|
||||||
msg: t('views.configManage.neManage.start'),
|
.then(res => {
|
||||||
}),
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
key,
|
message.success(t('common.operateOk'), 3);
|
||||||
duration: 2,
|
} else {
|
||||||
});
|
message.error(`${res.msg}`, 3);
|
||||||
} else {
|
}
|
||||||
message.error({
|
})
|
||||||
content: `${res.msg}`,
|
.finally(() => {
|
||||||
key: key,
|
hide();
|
||||||
duration: 2,
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -51,30 +47,36 @@ export default function useNeOptions() {
|
|||||||
function fnNeRestart(row: Record<string, any>) {
|
function fnNeRestart(row: Record<string, any>) {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: t('common.tipTitle'),
|
title: t('common.tipTitle'),
|
||||||
content: t('views.configManage.neManage.totalSure', {
|
content: t('views.ne.common.restartTip'),
|
||||||
msg: row.neName,
|
|
||||||
oper: t('views.configManage.neManage.restart'),
|
|
||||||
}),
|
|
||||||
onOk() {
|
onOk() {
|
||||||
const key = 'restartNf';
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
message.loading({ content: t('common.loading'), key });
|
serviceNeAction({
|
||||||
restartNf(row).then(res => {
|
neType: row.neType,
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
neId: row.neId,
|
||||||
message.success({
|
action: 'restart',
|
||||||
content: t('common.msgSuccess', {
|
})
|
||||||
msg: t('views.configManage.neManage.restart'),
|
.then(res => {
|
||||||
}),
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
key,
|
// OMC自升级
|
||||||
duration: 3,
|
if (row.neType.toUpperCase() === 'OMC') {
|
||||||
});
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
} else {
|
lockedStore.fnLock('reload');
|
||||||
message.error({
|
} else {
|
||||||
content: `${res.msg}`,
|
message.error({
|
||||||
key: key,
|
content: `${res.msg}`,
|
||||||
duration: 3,
|
duration: 3,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
} else {
|
||||||
|
message.error(`${res.msg}`, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -86,30 +88,24 @@ export default function useNeOptions() {
|
|||||||
function fnNeStop(row: Record<string, any>) {
|
function fnNeStop(row: Record<string, any>) {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: t('common.tipTitle'),
|
title: t('common.tipTitle'),
|
||||||
content: t('views.configManage.neManage.totalSure', {
|
content: t('views.ne.common.stopTip'),
|
||||||
msg: row.neName,
|
|
||||||
oper: t('views.configManage.neManage.stop'),
|
|
||||||
}),
|
|
||||||
onOk() {
|
onOk() {
|
||||||
const key = 'restartNf';
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
message.loading({ content: t('common.loading'), key });
|
serviceNeAction({
|
||||||
stopNf(row).then(res => {
|
neType: row.neType,
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
neId: row.neId,
|
||||||
message.success({
|
action: 'stop',
|
||||||
content: t('common.msgSuccess', {
|
})
|
||||||
msg: t('views.configManage.neManage.stop'),
|
.then(res => {
|
||||||
}),
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
key: key,
|
message.success(t('common.operateOk'), 3);
|
||||||
duration: 3,
|
} else {
|
||||||
});
|
message.error(`${res.msg}`, 3);
|
||||||
} else {
|
}
|
||||||
message.error({
|
})
|
||||||
content: `${res.msg}`,
|
.finally(() => {
|
||||||
key: key,
|
hide();
|
||||||
duration: 3,
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -121,30 +117,20 @@ export default function useNeOptions() {
|
|||||||
function fnNeReload(row: Record<string, any>) {
|
function fnNeReload(row: Record<string, any>) {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: t('common.tipTitle'),
|
title: t('common.tipTitle'),
|
||||||
content: t('views.configManage.neManage.totalSure', {
|
content: t('views.ne.common.reloadTip'),
|
||||||
msg: row.neName,
|
|
||||||
oper: t('views.configManage.neManage.reload'),
|
|
||||||
}),
|
|
||||||
onOk() {
|
onOk() {
|
||||||
const key = 'stopNf';
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
message.loading({ content: t('common.loading'), key });
|
updateNeConfigReload(row.neType, row.neId)
|
||||||
updateNeConfigReload(row.neType, row.neId).then(res => {
|
.then(res => {
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
message.success({
|
message.success(t('common.operateOk'), 3);
|
||||||
content: t('common.msgSuccess', {
|
} else {
|
||||||
msg: t('views.configManage.neManage.reload'),
|
message.error(`${res.msg}`, 3);
|
||||||
}),
|
}
|
||||||
key,
|
})
|
||||||
duration: 2,
|
.finally(() => {
|
||||||
});
|
hide();
|
||||||
} else {
|
});
|
||||||
message.error({
|
|
||||||
content: `${res.msg}`,
|
|
||||||
key: key,
|
|
||||||
duration: 2,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+184
-166
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted, toRaw } from 'vue';
|
import { reactive, onMounted, toRaw, defineAsyncComponent, ref } from 'vue';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import { message, Modal } from 'ant-design-vue/lib';
|
import { message, Modal } from 'ant-design-vue/lib';
|
||||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||||
@@ -7,7 +7,6 @@ import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
|||||||
import { ColumnsType } from 'ant-design-vue/lib/table';
|
import { ColumnsType } from 'ant-design-vue/lib/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 EditModal from './components/EditModal.vue';
|
|
||||||
import useNeInfoStore from '@/store/modules/neinfo';
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
import { listNeInfo, delNeInfo } from '@/api/ne/neInfo';
|
import { listNeInfo, delNeInfo } from '@/api/ne/neInfo';
|
||||||
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||||
@@ -17,6 +16,18 @@ const { getDict } = useDictStore();
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { fnNeStart, fnNeRestart, fnNeStop, fnNeReload, fnNeLogFile } =
|
const { fnNeStart, fnNeRestart, fnNeStop, fnNeReload, fnNeLogFile } =
|
||||||
useNeOptions();
|
useNeOptions();
|
||||||
|
// 异步加载组件
|
||||||
|
const EditModal = defineAsyncComponent(
|
||||||
|
() => import('./components/EditModal.vue')
|
||||||
|
);
|
||||||
|
const OAMModal = defineAsyncComponent(
|
||||||
|
() => import('./components/OAMModal.vue')
|
||||||
|
);
|
||||||
|
// 配置备份文件导入
|
||||||
|
const BackConfModal = defineAsyncComponent(
|
||||||
|
() => import('./components/BackConfModal.vue')
|
||||||
|
);
|
||||||
|
const backConf = ref(); // 引用句柄,取导出函数
|
||||||
|
|
||||||
/**字典数据 */
|
/**字典数据 */
|
||||||
let dict: {
|
let dict: {
|
||||||
@@ -56,8 +67,6 @@ type TabeStateType = {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
/**紧凑型 */
|
/**紧凑型 */
|
||||||
size: SizeType;
|
size: SizeType;
|
||||||
/**斑马纹 */
|
|
||||||
striped: boolean;
|
|
||||||
/**搜索栏 */
|
/**搜索栏 */
|
||||||
seached: boolean;
|
seached: boolean;
|
||||||
/**记录数据 */
|
/**记录数据 */
|
||||||
@@ -70,8 +79,7 @@ type TabeStateType = {
|
|||||||
let tableState: TabeStateType = reactive({
|
let tableState: TabeStateType = reactive({
|
||||||
loading: false,
|
loading: false,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
striped: false,
|
seached: false,
|
||||||
seached: true,
|
|
||||||
data: [],
|
data: [],
|
||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
});
|
});
|
||||||
@@ -79,37 +87,37 @@ let tableState: TabeStateType = reactive({
|
|||||||
/**表格字段列 */
|
/**表格字段列 */
|
||||||
let tableColumns: ColumnsType = [
|
let tableColumns: ColumnsType = [
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.neType'),
|
title: t('views.ne.common.neType'),
|
||||||
dataIndex: 'neType',
|
dataIndex: 'neType',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.neId'),
|
title: t('views.ne.common.neId'),
|
||||||
dataIndex: 'neId',
|
dataIndex: 'neId',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.uid'),
|
title: t('views.ne.common.rmUid'),
|
||||||
dataIndex: 'rmUid',
|
dataIndex: 'rmUid',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.neName'),
|
title: t('views.ne.common.neName'),
|
||||||
dataIndex: 'neName',
|
dataIndex: 'neName',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.ip'),
|
title: t('views.ne.common.ipAddr'),
|
||||||
dataIndex: 'ip',
|
dataIndex: 'ip',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('views.configManage.neManage.port'),
|
title: t('views.ne.common.port'),
|
||||||
dataIndex: 'port',
|
dataIndex: 'port',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
width: 100,
|
width: 100,
|
||||||
@@ -161,11 +169,6 @@ function fnTableSize({ key }: MenuInfo) {
|
|||||||
tableState.size = key as SizeType;
|
tableState.size = key as SizeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**表格斑马纹 */
|
|
||||||
function fnTableStriped(_record: unknown, index: number): any {
|
|
||||||
return tableState.striped && index % 2 === 1 ? 'table-striped' : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**表格多选 */
|
/**表格多选 */
|
||||||
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
||||||
tableState.selectedRowKeys = keys;
|
tableState.selectedRowKeys = keys;
|
||||||
@@ -173,18 +176,29 @@ function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
|||||||
|
|
||||||
/**对话框对象信息状态类型 */
|
/**对话框对象信息状态类型 */
|
||||||
type ModalStateType = {
|
type ModalStateType = {
|
||||||
|
/**配置备份框是否显示 */
|
||||||
|
visibleByBackConf: boolean;
|
||||||
|
/**OAM文件配置框是否显示 */
|
||||||
|
visibleByOAM: boolean;
|
||||||
/**新增框或修改框是否显示 */
|
/**新增框或修改框是否显示 */
|
||||||
visibleByEdit: boolean;
|
visibleByEdit: boolean;
|
||||||
/**新增框或修改框ID */
|
/**新增框或修改框ID */
|
||||||
editId: string;
|
editId: string;
|
||||||
|
/**OAM框网元类型ID */
|
||||||
|
neId: string;
|
||||||
|
neType: string;
|
||||||
/**确定按钮 loading */
|
/**确定按钮 loading */
|
||||||
confirmLoading: boolean;
|
confirmLoading: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**对话框对象信息状态 */
|
/**对话框对象信息状态 */
|
||||||
let modalState: ModalStateType = reactive({
|
let modalState: ModalStateType = reactive({
|
||||||
|
visibleByBackConf: false,
|
||||||
|
visibleByOAM: false,
|
||||||
visibleByEdit: false,
|
visibleByEdit: false,
|
||||||
editId: '',
|
editId: '',
|
||||||
|
neId: '',
|
||||||
|
neType: '',
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -216,6 +230,8 @@ function fnModalEditOk() {
|
|||||||
function fnModalEditCancel() {
|
function fnModalEditCancel() {
|
||||||
modalState.editId = '';
|
modalState.editId = '';
|
||||||
modalState.visibleByEdit = false;
|
modalState.visibleByEdit = false;
|
||||||
|
modalState.visibleByOAM = false;
|
||||||
|
modalState.visibleByBackConf = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,36 +240,21 @@ function fnModalEditCancel() {
|
|||||||
*/
|
*/
|
||||||
function fnRecordDelete(id: string) {
|
function fnRecordDelete(id: string) {
|
||||||
if (!id || modalState.confirmLoading) return;
|
if (!id || modalState.confirmLoading) return;
|
||||||
let msg = '';
|
let msg = t('views.ne.neInfo.delTip');
|
||||||
if (id === '0') {
|
if (id === '0') {
|
||||||
const neInfo: any = tableState.data.find(
|
msg = `${msg} ...${tableState.selectedRowKeys.length}`;
|
||||||
(item: any) => item.id === tableState.selectedRowKeys[0]
|
|
||||||
);
|
|
||||||
if (neInfo) {
|
|
||||||
msg = neInfo.neName;
|
|
||||||
}
|
|
||||||
msg = `${msg}... ${tableState.selectedRowKeys.length}`;
|
|
||||||
id = tableState.selectedRowKeys.join(',');
|
|
||||||
} else {
|
|
||||||
const neInfo: any = tableState.data.find((item: any) => item.id === id);
|
|
||||||
if (neInfo) {
|
|
||||||
msg = neInfo.neName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: t('common.tipTitle'),
|
title: t('common.tipTitle'),
|
||||||
content: `确认删除网元名称为【${msg}】的数据项?`,
|
content: msg,
|
||||||
onOk() {
|
onOk() {
|
||||||
modalState.confirmLoading = true;
|
modalState.confirmLoading = true;
|
||||||
const hide = message.loading(t('common.loading'), 0);
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
delNeInfo(id)
|
delNeInfo(id)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
message.success({
|
message.success(t('common.operateOk'), 3);
|
||||||
content: `操作成功`,
|
|
||||||
duration: 3,
|
|
||||||
});
|
|
||||||
fnGetList(1);
|
fnGetList(1);
|
||||||
} else {
|
} else {
|
||||||
message.error({
|
message.error({
|
||||||
@@ -293,6 +294,19 @@ function fnRecordMore(type: string | number, row: Record<string, any>) {
|
|||||||
case 'log':
|
case 'log':
|
||||||
fnNeLogFile(row);
|
fnNeLogFile(row);
|
||||||
break;
|
break;
|
||||||
|
case 'oam':
|
||||||
|
modalState.neId = row.neId;
|
||||||
|
modalState.neType = row.neType;
|
||||||
|
modalState.visibleByOAM = !modalState.visibleByOAM;
|
||||||
|
break;
|
||||||
|
case 'backConfExport':
|
||||||
|
backConf.value.exportConf(row.neType, row.neId);
|
||||||
|
break;
|
||||||
|
case 'backConfImport':
|
||||||
|
modalState.neId = row.neId;
|
||||||
|
modalState.neType = row.neType;
|
||||||
|
modalState.visibleByBackConf = !modalState.visibleByBackConf;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn(type);
|
console.warn(type);
|
||||||
break;
|
break;
|
||||||
@@ -402,10 +416,7 @@ onMounted(() => {
|
|||||||
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="6" :md="12" :xs="24">
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
<a-form-item
|
<a-form-item :label="t('views.ne.common.neType')" name="neType ">
|
||||||
:label="t('views.configManage.neManage.neType')"
|
|
||||||
name="neType "
|
|
||||||
>
|
|
||||||
<a-auto-complete
|
<a-auto-complete
|
||||||
v-model:value="queryParams.neType"
|
v-model:value="queryParams.neType"
|
||||||
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
|
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
|
||||||
@@ -465,15 +476,6 @@ onMounted(() => {
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
|
||||||
<template #title>{{ t('common.tableStripedText') }}</template>
|
|
||||||
<a-switch
|
|
||||||
v-model:checked="tableState.striped"
|
|
||||||
:checked-children="t('common.switch.open')"
|
|
||||||
:un-checked-children="t('common.switch.shut')"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>{{ t('common.reloadText') }}</template>
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
<a-button type="text" @click.prevent="fnGetList()">
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
@@ -516,8 +518,7 @@ onMounted(() => {
|
|||||||
:data-source="tableState.data"
|
:data-source="tableState.data"
|
||||||
:size="tableState.size"
|
:size="tableState.size"
|
||||||
:pagination="tablePagination"
|
:pagination="tablePagination"
|
||||||
:row-class-name="fnTableStriped"
|
:scroll="{ x: tableColumns.length * 150 }"
|
||||||
:scroll="{ x: tableColumns.length * 120, y: 'calc(100vh - 480px)' }"
|
|
||||||
:row-selection="{
|
:row-selection="{
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
columnWidth: '48px',
|
columnWidth: '48px',
|
||||||
@@ -542,7 +543,7 @@ onMounted(() => {
|
|||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>
|
<template #title>
|
||||||
{{ t('views.configManage.neManage.restart') }}
|
{{ t('views.ne.common.restart') }}
|
||||||
</template>
|
</template>
|
||||||
<a-button
|
<a-button
|
||||||
type="link"
|
type="link"
|
||||||
@@ -551,23 +552,9 @@ onMounted(() => {
|
|||||||
<template #icon><UndoOutlined /></template>
|
<template #icon><UndoOutlined /></template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip>
|
|
||||||
<template #title>
|
|
||||||
{{ t('views.configManage.neManage.stop') }}
|
|
||||||
</template>
|
|
||||||
<a-button
|
|
||||||
type="link"
|
|
||||||
@click.prevent="fnRecordMore('stop', record)"
|
|
||||||
>
|
|
||||||
<template #icon><CloseSquareOutlined /> </template>
|
|
||||||
</a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-tooltip placement="left">
|
<a-tooltip placement="left">
|
||||||
<template #title>{{ t('common.moreText') }}</template>
|
<template #title>{{ t('common.moreText') }}</template>
|
||||||
<a-dropdown
|
<a-dropdown placement="bottomRight" trigger="click">
|
||||||
placement="bottomRight"
|
|
||||||
:trigger="['hover', 'click']"
|
|
||||||
>
|
|
||||||
<a-button type="link">
|
<a-button type="link">
|
||||||
<template #icon><EllipsisOutlined /> </template>
|
<template #icon><EllipsisOutlined /> </template>
|
||||||
</a-button>
|
</a-button>
|
||||||
@@ -575,11 +562,15 @@ onMounted(() => {
|
|||||||
<a-menu @click="({ key }:any) => fnRecordMore(key, record)">
|
<a-menu @click="({ key }:any) => fnRecordMore(key, record)">
|
||||||
<a-menu-item key="log">
|
<a-menu-item key="log">
|
||||||
<FileTextOutlined />
|
<FileTextOutlined />
|
||||||
{{ t('views.configManage.neManage.log') }}
|
{{ t('views.ne.common.log') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item key="start">
|
<a-menu-item key="start">
|
||||||
<ThunderboltOutlined />
|
<ThunderboltOutlined />
|
||||||
{{ t('views.configManage.neManage.start') }}
|
{{ t('views.ne.common.start') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="stop">
|
||||||
|
<CloseSquareOutlined />
|
||||||
|
{{ t('views.ne.common.stop') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item
|
<a-menu-item
|
||||||
key="reload"
|
key="reload"
|
||||||
@@ -588,12 +579,25 @@ onMounted(() => {
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<SyncOutlined />
|
<SyncOutlined />
|
||||||
{{ t('views.configManage.neManage.reload') }}
|
{{ t('views.ne.common.reload') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item key="delete">
|
<a-menu-item key="delete">
|
||||||
<DeleteOutlined />
|
<DeleteOutlined />
|
||||||
{{ t('common.deleteText') }}
|
{{ t('common.deleteText') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
|
<a-menu-item key="oam">
|
||||||
|
<FileTextOutlined />
|
||||||
|
{{ t('views.ne.common.oam') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<!-- 配置备份 -->
|
||||||
|
<a-menu-item key="backConfExport">
|
||||||
|
<ExportOutlined />
|
||||||
|
{{ t('views.ne.neInfo.backConf.export') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="backConfImport">
|
||||||
|
<ImportOutlined />
|
||||||
|
{{ t('views.ne.neInfo.backConf.import') }}
|
||||||
|
</a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
@@ -602,117 +606,131 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template #expandedRowRender="{ record }">
|
<template #expandedRowRender="{ record }">
|
||||||
<div style="width: 46%; padding-left: 32px; padding-bottom: 16px">
|
<a-row :gutter="16">
|
||||||
<a-divider orientation="left">
|
<a-col :offset="2" :lg="8" :md="8" :xs="8">
|
||||||
{{ t('views.ne.neInfo.info') }}
|
<a-divider orientation="left">
|
||||||
</a-divider>
|
{{ t('views.ne.neInfo.info') }}
|
||||||
<div>
|
</a-divider>
|
||||||
<span>{{ t('views.ne.neInfo.serviceState') }}:</span>
|
<div>
|
||||||
<a-tag
|
<span>{{ t('views.ne.neInfo.serviceState') }}:</span>
|
||||||
:color="record.serverState.online ? 'processing' : 'error'"
|
<a-tag
|
||||||
>
|
:color="record.serverState.online ? 'processing' : 'error'"
|
||||||
{{
|
>
|
||||||
record.serverState.online
|
{{
|
||||||
? t('views.ne.neInfo.normalcy')
|
record.serverState.online
|
||||||
: t('views.ne.neInfo.exceptions')
|
? t('views.ne.common.normalcy')
|
||||||
}}
|
: t('views.ne.common.exceptions')
|
||||||
</a-tag>
|
}}
|
||||||
</div>
|
</a-tag>
|
||||||
<div>
|
</div>
|
||||||
<span>{{ t('views.ne.neInfo.version') }}:</span>
|
<div>
|
||||||
<span>{{ record.serverState.version }}</span>
|
<span>{{ t('views.ne.neVersion.version') }}:</span>
|
||||||
</div>
|
<span>{{ record.serverState.version }}</span>
|
||||||
<div>
|
</div>
|
||||||
<span>{{ t('views.ne.neInfo.serialNum') }}:</span>
|
<div>
|
||||||
<span>{{ record.serverState.sn }}</span>
|
<span>{{ t('views.ne.common.serialNum') }}:</span>
|
||||||
</div>
|
<span>{{ record.serverState.sn }}</span>
|
||||||
<div>
|
</div>
|
||||||
<span>{{ t('views.ne.neInfo.expiryDate') }}:</span>
|
<div>
|
||||||
<span>{{ record.serverState.expire }}</span>
|
<span>{{ t('views.ne.common.expiryDate') }}:</span>
|
||||||
</div>
|
<span>{{ record.serverState.expire }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 46%; padding-left: 32px; padding-bottom: 16px">
|
</a-col>
|
||||||
<a-divider orientation="left">
|
<a-col :offset="2" :lg="8" :md="8" :xs="8">
|
||||||
{{ t('views.ne.neInfo.resourceInfo') }}
|
<a-divider orientation="left">
|
||||||
</a-divider>
|
{{ t('views.ne.neInfo.resourceInfo') }}
|
||||||
<div>
|
</a-divider>
|
||||||
<span>{{ t('views.ne.neInfo.neCpu') }}:</span>
|
<div>
|
||||||
<a-progress
|
<span>{{ t('views.ne.neInfo.neCpu') }}:</span>
|
||||||
status="normal"
|
<a-progress
|
||||||
:stroke-color="
|
status="normal"
|
||||||
record.resoures.nfCpuUsage < 30
|
:stroke-color="
|
||||||
? '#52c41a'
|
record.resoures.nfCpuUsage < 30
|
||||||
: record.resoures.nfCpuUsage > 70
|
? '#52c41a'
|
||||||
? '#ff4d4f'
|
: record.resoures.nfCpuUsage > 70
|
||||||
: '#1890ff'
|
? '#ff4d4f'
|
||||||
"
|
: '#1890ff'
|
||||||
:percent="record.resoures.nfCpuUsage"
|
"
|
||||||
/>
|
:percent="record.resoures.nfCpuUsage"
|
||||||
</div>
|
/>
|
||||||
<div>
|
</div>
|
||||||
<span>{{ t('views.ne.neInfo.sysCpu') }}:</span>
|
<div>
|
||||||
<a-progress
|
<span>{{ t('views.ne.neInfo.sysCpu') }}:</span>
|
||||||
status="normal"
|
<a-progress
|
||||||
:stroke-color="
|
status="normal"
|
||||||
record.resoures.sysCpuUsage < 30
|
:stroke-color="
|
||||||
? '#52c41a'
|
record.resoures.sysCpuUsage < 30
|
||||||
: record.resoures.sysCpuUsage > 70
|
? '#52c41a'
|
||||||
? '#ff4d4f'
|
: record.resoures.sysCpuUsage > 70
|
||||||
: '#1890ff'
|
? '#ff4d4f'
|
||||||
"
|
: '#1890ff'
|
||||||
:percent="record.resoures.sysCpuUsage"
|
"
|
||||||
/>
|
:percent="record.resoures.sysCpuUsage"
|
||||||
</div>
|
/>
|
||||||
<div>
|
</div>
|
||||||
<span>{{ t('views.ne.neInfo.sysMem') }}:</span>
|
<div>
|
||||||
<a-progress
|
<span>{{ t('views.ne.neInfo.sysMem') }}:</span>
|
||||||
status="normal"
|
<a-progress
|
||||||
:stroke-color="
|
status="normal"
|
||||||
record.resoures.sysMemUsage < 30
|
:stroke-color="
|
||||||
? '#52c41a'
|
record.resoures.sysMemUsage < 30
|
||||||
: record.resoures.sysMemUsage > 70
|
? '#52c41a'
|
||||||
? '#ff4d4f'
|
: record.resoures.sysMemUsage > 70
|
||||||
: '#1890ff'
|
? '#ff4d4f'
|
||||||
"
|
: '#1890ff'
|
||||||
:percent="record.resoures.sysMemUsage"
|
"
|
||||||
/>
|
:percent="record.resoures.sysMemUsage"
|
||||||
</div>
|
/>
|
||||||
<div>
|
</div>
|
||||||
<span>{{ t('views.ne.neInfo.sysDisk') }}:</span>
|
<div>
|
||||||
<a-progress
|
<span>{{ t('views.ne.neInfo.sysDisk') }}:</span>
|
||||||
status="normal"
|
<a-progress
|
||||||
:stroke-color="
|
status="normal"
|
||||||
record.resoures.sysDiskUsage < 30
|
:stroke-color="
|
||||||
? '#52c41a'
|
record.resoures.sysDiskUsage < 30
|
||||||
: record.resoures.sysDiskUsage > 70
|
? '#52c41a'
|
||||||
? '#ff4d4f'
|
: record.resoures.sysDiskUsage > 70
|
||||||
: '#1890ff'
|
? '#ff4d4f'
|
||||||
"
|
: '#1890ff'
|
||||||
:percent="record.resoures.sysDiskUsage"
|
"
|
||||||
/>
|
:percent="record.resoures.sysDiskUsage"
|
||||||
</div>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
<!-- 新增框或修改框 -->
|
<!-- 新增框或修改框 -->
|
||||||
<EditModal
|
<EditModal
|
||||||
:visible="modalState.visibleByEdit"
|
v-model:visible="modalState.visibleByEdit"
|
||||||
:edit-id="modalState.editId"
|
:edit-id="modalState.editId"
|
||||||
@ok="fnModalEditOk"
|
@ok="fnModalEditOk"
|
||||||
@cancel="fnModalEditCancel"
|
@cancel="fnModalEditCancel"
|
||||||
></EditModal>
|
></EditModal>
|
||||||
|
|
||||||
|
<!-- OAM编辑框 -->
|
||||||
|
<OAMModal
|
||||||
|
v-model:visible="modalState.visibleByOAM"
|
||||||
|
:ne-id="modalState.neId"
|
||||||
|
:ne-type="modalState.neType"
|
||||||
|
@cancel="fnModalEditCancel"
|
||||||
|
></OAMModal>
|
||||||
|
|
||||||
|
<!-- 配置文件备份框 -->
|
||||||
|
<BackConfModal
|
||||||
|
ref="backConf"
|
||||||
|
v-model:visible="modalState.visibleByBackConf"
|
||||||
|
:ne-id="modalState.neId"
|
||||||
|
:ne-type="modalState.neType"
|
||||||
|
@cancel="fnModalEditCancel"
|
||||||
|
></BackConfModal>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.table :deep(.table-striped) td {
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table :deep(.ant-pagination) {
|
.table :deep(.ant-pagination) {
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
./components/useNeOptions
|
|
||||||
@@ -0,0 +1,393 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, toRaw, watch } from 'vue';
|
||||||
|
import { Form, Modal, Upload, message } from 'ant-design-vue/lib';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import {
|
||||||
|
changeNeLicense,
|
||||||
|
getNeLicense,
|
||||||
|
getNeLicenseByTypeAndID,
|
||||||
|
} from '@/api/ne/neLicense';
|
||||||
|
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||||
|
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||||
|
import { uploadFile } from '@/api/tool/file';
|
||||||
|
import { useClipboard } from '@vueuse/core';
|
||||||
|
import saveAs from 'file-saver';
|
||||||
|
const { copy } = useClipboard({ legacy: true });
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
|
||||||
|
const props = defineProps({
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**记录ID 优先级高于neId */
|
||||||
|
editId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
/**网元ID */
|
||||||
|
neId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
neType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
/**是否重启服务 */
|
||||||
|
reload: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
visibleByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: {
|
||||||
|
id: string;
|
||||||
|
neType: string;
|
||||||
|
neId: string;
|
||||||
|
activationRequestCode: string;
|
||||||
|
licensePath: string;
|
||||||
|
remark: string;
|
||||||
|
reload: boolean;
|
||||||
|
};
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
/**上传文件 */
|
||||||
|
uploadFiles: any[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
visibleByEdit: false,
|
||||||
|
title: '授权文件',
|
||||||
|
from: {
|
||||||
|
id: '',
|
||||||
|
neType: '',
|
||||||
|
neId: '',
|
||||||
|
activationRequestCode: '',
|
||||||
|
licensePath: '',
|
||||||
|
remark: '',
|
||||||
|
reload: false,
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
uploadFiles: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
licensePath: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.neLicense.licensePathTip'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
if (modalState.confirmLoading || !modalState.from.id) return;
|
||||||
|
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
changeNeLicense(from).then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success({
|
||||||
|
content: t('common.operateOk'),
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
// 返回无引用信息
|
||||||
|
emit('ok', JSON.parse(JSON.stringify(from)));
|
||||||
|
fnModalCancel();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.visibleByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
modalState.uploadFiles = [];
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:visible', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩 */
|
||||||
|
function fnBeforeUploadFile(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
if (!file.name.endsWith('.ini')) {
|
||||||
|
const msg = `${t('components.UploadModal.onlyAllow')} .ini`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
const isLt3M = file.size / 1024 / 1024 < 3;
|
||||||
|
if (!isLt3M) {
|
||||||
|
const msg = `${t('components.UploadModal.allowFilter')} 3MB`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件 */
|
||||||
|
function fnUploadFile(up: UploadRequestOption) {
|
||||||
|
// 发送请求
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append('file', up.file);
|
||||||
|
formData.append('subPath', 'license');
|
||||||
|
uploadFile(formData)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// 改为完成状态
|
||||||
|
const file = modalState.uploadFiles[0];
|
||||||
|
file.percent = 100;
|
||||||
|
file.status = 'done';
|
||||||
|
// 预置到表单
|
||||||
|
const { fileName } = res.data;
|
||||||
|
modalState.from.licensePath = fileName;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**复制授权申请码 */
|
||||||
|
function fnCopyCode() {
|
||||||
|
const code = modalState.from.activationRequestCode;
|
||||||
|
if (!code) return;
|
||||||
|
copy(code).then(() => {
|
||||||
|
message.success(t('common.copyOk'), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**下载授权申请码文件 */
|
||||||
|
function fnDownCode() {
|
||||||
|
const { activationRequestCode, neType, neId } = modalState.from;
|
||||||
|
if (!activationRequestCode) return;
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neLicense.downCodeTop'),
|
||||||
|
onOk() {
|
||||||
|
const blob = new Blob([activationRequestCode], {
|
||||||
|
type: 'text/plain',
|
||||||
|
});
|
||||||
|
saveAs(blob, `${neType}_${neId}_code.txt`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 ID编辑
|
||||||
|
* @param id id
|
||||||
|
*/
|
||||||
|
function fnModalVisibleById(id: string) {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
getNeLicense(id)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
Object.assign(modalState.from, res.data);
|
||||||
|
modalState.from.licensePath = '';
|
||||||
|
modalState.from.reload = props.reload;
|
||||||
|
modalState.title = t('views.ne.neLicense.updateTtile');
|
||||||
|
modalState.visibleByEdit = true;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 新增或者修改
|
||||||
|
* @param neType 网元类型
|
||||||
|
* @param neId 网元ID
|
||||||
|
*/
|
||||||
|
function fnModalVisibleByTypeAndId(neType: string, neId: string) {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
getNeLicenseByTypeAndID(neType, neId)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
Object.assign(modalState.from, res.data);
|
||||||
|
modalState.from.licensePath = '';
|
||||||
|
modalState.from.reload = props.reload;
|
||||||
|
modalState.title = t('views.ne.neLicense.updateTtile');
|
||||||
|
modalState.visibleByEdit = true;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
if (props.editId) {
|
||||||
|
fnModalVisibleById(props.editId);
|
||||||
|
}
|
||||||
|
if (props.neType && props.neId) {
|
||||||
|
fnModalVisibleByTypeAndId(props.neType, props.neId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
width="800px"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:visible="modalState.visibleByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label-col="{ span: 12 }"
|
||||||
|
:label="t('views.ne.common.neType')"
|
||||||
|
name="neType"
|
||||||
|
>
|
||||||
|
{{ modalState.from.neType }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label-col="{ span: 12 }"
|
||||||
|
:label="t('views.ne.common.neId')"
|
||||||
|
name="neId"
|
||||||
|
>
|
||||||
|
{{ modalState.from.neId }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neLicense.activationRequestCode')"
|
||||||
|
name="activationRequestCode"
|
||||||
|
v-bind="modalStateFrom.validateInfos.activationRequestCode"
|
||||||
|
>
|
||||||
|
<a-input-group compact>
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.activationRequestCode"
|
||||||
|
:disabled="true"
|
||||||
|
style="width: calc(100% - 64px)"
|
||||||
|
/>
|
||||||
|
<a-tooltip :title="t('common.copyText')" placement="topRight">
|
||||||
|
<a-button type="default" @click="fnCopyCode()">
|
||||||
|
<template #icon><CopyOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip :title="t('common.downloadText')" placement="topRight">
|
||||||
|
<a-button type="primary" @click="fnDownCode()">
|
||||||
|
<template #icon><DownloadOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-input-group>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neLicense.licensePath')"
|
||||||
|
name="file"
|
||||||
|
v-bind="modalStateFrom.validateInfos.licensePath"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFiles"
|
||||||
|
accept=".ini"
|
||||||
|
list-type="text"
|
||||||
|
:max-count="1"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: false,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
:before-upload="fnBeforeUploadFile"
|
||||||
|
:custom-request="fnUploadFile"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neLicense.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 网元授权不允许操作重启,上传后根据情况去网元信息操作重启 -->
|
||||||
|
<a-form-item label="NE Reload" name="reload" v-if="false">
|
||||||
|
<a-switch v-model:checked="modalState.from.reload"> </a-switch>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item :label="t('common.remark')" name="remark">
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="modalState.from.remark"
|
||||||
|
:maxlength="200"
|
||||||
|
:show-count="true"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
@@ -0,0 +1,242 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, watch, PropType, h } from 'vue';
|
||||||
|
import { message, notification, Upload } from 'ant-design-vue/lib';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||||
|
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||||
|
import { uploadFile } from '@/api/tool/file';
|
||||||
|
import { changeNeLicense } from '@/api/ne/neLicense';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
|
||||||
|
const props = defineProps({
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**指定网元类型 */
|
||||||
|
licenseList: {
|
||||||
|
type: Array as PropType<Record<string, any>[]>,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
visibleByUploadFile: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**授权文件路径 */
|
||||||
|
licensePath: string;
|
||||||
|
/**上传文件 */
|
||||||
|
uploadFiles: any[];
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
visibleByUploadFile: false,
|
||||||
|
licensePath: '',
|
||||||
|
uploadFiles: [],
|
||||||
|
title: '授权文件',
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
async function fnModalOk() {
|
||||||
|
if (!modalState.licensePath) {
|
||||||
|
message.warning(t('views.ne.neLicense.licensePathTip'), 3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
|
||||||
|
const notificationKey = 'NE_LICENSE_MORE';
|
||||||
|
notification.info({
|
||||||
|
key: notificationKey,
|
||||||
|
message: modalState.title,
|
||||||
|
description: t('common.loading'),
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (props.licenseList.length === 0) {
|
||||||
|
notification.close(notificationKey);
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasFailNeType: string[] = [];
|
||||||
|
for (const item of props.licenseList) {
|
||||||
|
try {
|
||||||
|
const res = await changeNeLicense({
|
||||||
|
neType: item.neType,
|
||||||
|
neId: item.neId,
|
||||||
|
licensePath: modalState.licensePath,
|
||||||
|
reload: true, // 重启网元
|
||||||
|
});
|
||||||
|
if (res.code !== RESULT_CODE_SUCCESS) {
|
||||||
|
hasFailNeType.push(item.neType);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存在错误网元提示
|
||||||
|
if (hasFailNeType.length > 0) {
|
||||||
|
notification.warning({
|
||||||
|
message: modalState.title,
|
||||||
|
description: h('div', {}, [
|
||||||
|
h('p', t('views.ne.neLicense.uploadChangeFail')),
|
||||||
|
h('div', { style: { color: '#f5222d' } }, hasFailNeType.join('、')),
|
||||||
|
]),
|
||||||
|
duration: 4.5,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
emit('ok', hasFailNeType);
|
||||||
|
fnModalCancel();
|
||||||
|
notification.close(notificationKey);
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.visibleByUploadFile = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalState.licensePath = '';
|
||||||
|
modalState.uploadFiles = [];
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:visible', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩 */
|
||||||
|
function fnBeforeUploadFile(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
if (!file.name.endsWith('.ini')) {
|
||||||
|
const msg = `${t('components.UploadModal.onlyAllow')} .ini`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
const isLt3M = file.size / 1024 / 1024 < 3;
|
||||||
|
if (!isLt3M) {
|
||||||
|
const msg = `${t('components.UploadModal.allowFilter')} 3MB`;
|
||||||
|
message.error(msg, 3);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件 */
|
||||||
|
function fnUploadFile(up: UploadRequestOption) {
|
||||||
|
// 发送请求
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append('file', up.file);
|
||||||
|
formData.append('subPath', 'license');
|
||||||
|
uploadFile(formData)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// 改为完成状态
|
||||||
|
const file = modalState.uploadFiles[0];
|
||||||
|
file.percent = 100;
|
||||||
|
file.status = 'done';
|
||||||
|
// 预置到表单
|
||||||
|
const { fileName } = res.data;
|
||||||
|
modalState.licensePath = fileName;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
modalState.title = t('views.ne.neLicense.updateTtile');
|
||||||
|
modalState.visibleByUploadFile = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
width="500px"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:visible="modalState.visibleByUploadFile"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
:cancel-button-props="{ disabled: modalState.confirmLoading }"
|
||||||
|
:closable="false"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-form-item :label="t('views.ne.common.neType')">
|
||||||
|
<a-tag color="processing" v-for="s in props.licenseList">
|
||||||
|
{{ s.neType }}
|
||||||
|
</a-tag>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neLicense.licensePath')"
|
||||||
|
name="file"
|
||||||
|
:required="true"
|
||||||
|
:validate-on-rule-change="false"
|
||||||
|
:validateTrigger="[]"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFiles"
|
||||||
|
accept=".ini"
|
||||||
|
list-type="text"
|
||||||
|
:multiple="true"
|
||||||
|
:max-count="1"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: false,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
:before-upload="fnBeforeUploadFile"
|
||||||
|
:custom-request="fnUploadFile"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neLicense.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
@@ -0,0 +1,543 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref, onMounted, toRaw, defineAsyncComponent } from 'vue';
|
||||||
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
|
import { Modal, TableColumnsType, message } from 'ant-design-vue/lib';
|
||||||
|
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||||
|
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
||||||
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import useDictStore from '@/store/modules/dict';
|
||||||
|
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { listNeLicense, stateNeLicense } from '@/api/ne/neLicense';
|
||||||
|
import { parseDateToStr } from '@/utils/date-utils';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { getDict } = useDictStore();
|
||||||
|
const EditModal = defineAsyncComponent(
|
||||||
|
() => import('./components/EditModal.vue')
|
||||||
|
);
|
||||||
|
|
||||||
|
/**字典数据-状态 */
|
||||||
|
let dictStatus = ref<DictType[]>([]);
|
||||||
|
|
||||||
|
/**网元参数 */
|
||||||
|
let neOtions = ref<Record<string, any>[]>([]);
|
||||||
|
|
||||||
|
/**查询参数 */
|
||||||
|
let queryParams = reactive({
|
||||||
|
/**网元类型 */
|
||||||
|
neType: undefined,
|
||||||
|
/**网元ID */
|
||||||
|
neId: '',
|
||||||
|
/**序列号 */
|
||||||
|
serialNum: '',
|
||||||
|
/**当前页数 */
|
||||||
|
pageNum: 1,
|
||||||
|
/**每页条数 */
|
||||||
|
pageSize: 20,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**查询参数重置 */
|
||||||
|
function fnQueryReset() {
|
||||||
|
queryParams = Object.assign(queryParams, {
|
||||||
|
neType: undefined,
|
||||||
|
neId: '',
|
||||||
|
serialNum: '',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
});
|
||||||
|
tablePagination.current = 1;
|
||||||
|
tablePagination.pageSize = 20;
|
||||||
|
fnGetList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格状态类型 */
|
||||||
|
type TabeStateType = {
|
||||||
|
/**加载等待 */
|
||||||
|
loading: boolean;
|
||||||
|
/**紧凑型 */
|
||||||
|
size: SizeType;
|
||||||
|
/**搜索栏 */
|
||||||
|
seached: boolean;
|
||||||
|
/**记录数据 */
|
||||||
|
data: any[];
|
||||||
|
/**勾选记录 */
|
||||||
|
selectedRowKeys: (string | number)[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**表格状态 */
|
||||||
|
let tableState: TabeStateType = reactive({
|
||||||
|
loading: false,
|
||||||
|
size: 'middle',
|
||||||
|
seached: false,
|
||||||
|
data: [],
|
||||||
|
selectedRowKeys: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格字段列 */
|
||||||
|
let tableColumns = ref<TableColumnsType>([
|
||||||
|
{
|
||||||
|
title: t('common.rowId'),
|
||||||
|
dataIndex: 'id',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.neType'),
|
||||||
|
dataIndex: 'neType',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.neId'),
|
||||||
|
dataIndex: 'neId',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.neLicense.status'),
|
||||||
|
dataIndex: 'status',
|
||||||
|
key: 'status',
|
||||||
|
align: 'left',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.serialNum'),
|
||||||
|
dataIndex: 'serialNum',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.expiryDate'),
|
||||||
|
dataIndex: 'expiryDate',
|
||||||
|
align: 'left',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('common.remark'),
|
||||||
|
dataIndex: 'remark',
|
||||||
|
key: 'remark',
|
||||||
|
align: 'left',
|
||||||
|
width: 150,
|
||||||
|
resizable: true,
|
||||||
|
minWidth: 100,
|
||||||
|
maxWidth: 300,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('common.updateTime'),
|
||||||
|
dataIndex: 'updateTime',
|
||||||
|
align: 'center',
|
||||||
|
customRender(opt) {
|
||||||
|
if (!opt.value) return '';
|
||||||
|
return parseDateToStr(opt.value);
|
||||||
|
},
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('common.operate'),
|
||||||
|
key: 'id',
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**表格分页器参数 */
|
||||||
|
let tablePagination = reactive({
|
||||||
|
/**当前页数 */
|
||||||
|
current: 1,
|
||||||
|
/**每页条数 */
|
||||||
|
pageSize: 20,
|
||||||
|
/**默认的每页条数 */
|
||||||
|
defaultPageSize: 20,
|
||||||
|
/**指定每页可以显示多少条 */
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100'],
|
||||||
|
/**只有一页时是否隐藏分页器 */
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
/**是否可以快速跳转至某页 */
|
||||||
|
showQuickJumper: true,
|
||||||
|
/**是否可以改变 pageSize */
|
||||||
|
showSizeChanger: true,
|
||||||
|
/**数据总数 */
|
||||||
|
total: 0,
|
||||||
|
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
|
||||||
|
onChange: (page: number, pageSize: number) => {
|
||||||
|
tablePagination.current = page;
|
||||||
|
tablePagination.pageSize = pageSize;
|
||||||
|
queryParams.pageNum = page;
|
||||||
|
queryParams.pageSize = pageSize;
|
||||||
|
fnGetList();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格紧凑型变更操作 */
|
||||||
|
function fnTableSize({ key }: MenuInfo) {
|
||||||
|
tableState.size = key as SizeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表格多选 */
|
||||||
|
function fnTableSelectedRowKeys(keys: (string | number)[]) {
|
||||||
|
tableState.selectedRowKeys = keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**查询列表, pageNum初始页数 */
|
||||||
|
function fnGetList(pageNum?: number) {
|
||||||
|
if (tableState.loading) return;
|
||||||
|
tableState.loading = true;
|
||||||
|
if (pageNum) {
|
||||||
|
queryParams.pageNum = pageNum;
|
||||||
|
}
|
||||||
|
listNeLicense(toRaw(queryParams)).then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
||||||
|
tablePagination.total = res.total;
|
||||||
|
tableState.data = res.rows.filter(s => s.neType !== 'OMC');
|
||||||
|
if (
|
||||||
|
tablePagination.total <=
|
||||||
|
(queryParams.pageNum - 1) * tablePagination.pageSize &&
|
||||||
|
queryParams.pageNum !== 1
|
||||||
|
) {
|
||||||
|
tableState.loading = false;
|
||||||
|
fnGetList(queryParams.pageNum - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tablePagination.total = 0;
|
||||||
|
tableState.data = [];
|
||||||
|
}
|
||||||
|
tableState.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
visibleByEdit: boolean;
|
||||||
|
/**授权记录ID */
|
||||||
|
licenseId: string;
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
visibleByEdit: false,
|
||||||
|
licenseId: '',
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 新增或者修改
|
||||||
|
* @param licenseId id
|
||||||
|
*/
|
||||||
|
function fnModalVisibleByEdit(licenseId: string) {
|
||||||
|
modalState.licenseId = licenseId;
|
||||||
|
modalState.visibleByEdit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
// 获取列表数据
|
||||||
|
fnGetList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.visibleByEdit = false;
|
||||||
|
modalState.licenseId = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**刷新网元授权状态 */
|
||||||
|
function fnRecordState(row: Record<string, any>) {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neLicense.reloadTip'),
|
||||||
|
onOk() {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
stateNeLicense(row.neType, row.neId)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
row.status = '1';
|
||||||
|
row.serialNum = res.data.sn;
|
||||||
|
row.expiryDate = res.data.expire;
|
||||||
|
message.success(
|
||||||
|
`${row.neType} ${row.neId} ${dictStatus.value[1].label}`,
|
||||||
|
3
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
row.status = '0';
|
||||||
|
message.warning(
|
||||||
|
`${row.neType} ${row.neId} ${dictStatus.value[0].label}`,
|
||||||
|
3
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**刷新网元授权状态 勾选 */
|
||||||
|
function fnRecordStateBatch() {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neLicense.reloadBatchTip'),
|
||||||
|
onOk: async () => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
// 勾选的网元数据
|
||||||
|
const selectRows = tableState.data.filter(item =>
|
||||||
|
tableState.selectedRowKeys.includes(item.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const row of selectRows) {
|
||||||
|
if (row.neType.toUpperCase() === 'OMC') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const res = await stateNeLicense(row.neType, row.neId);
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
||||||
|
row.status = '1';
|
||||||
|
row.serialNum = res.data.sn;
|
||||||
|
row.expiryDate = res.data.expire;
|
||||||
|
} else {
|
||||||
|
row.status = '0';
|
||||||
|
}
|
||||||
|
tableState.selectedRowKeys = [];
|
||||||
|
}
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始字典数据
|
||||||
|
getDict('ne_license_status').then(res => {
|
||||||
|
dictStatus.value = res;
|
||||||
|
});
|
||||||
|
// 获取网元网元列表
|
||||||
|
useNeInfoStore()
|
||||||
|
.fnNelist()
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||||
|
neOtions.value = useNeInfoStore().getNeSelectOtions;
|
||||||
|
} else {
|
||||||
|
message.warning({
|
||||||
|
content: t('common.noData'),
|
||||||
|
duration: 2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
// 获取列表数据
|
||||||
|
fnGetList();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PageContainer>
|
||||||
|
<a-card
|
||||||
|
v-show="tableState.seached"
|
||||||
|
:bordered="false"
|
||||||
|
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
||||||
|
>
|
||||||
|
<!-- 表格搜索栏 -->
|
||||||
|
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item :label="t('views.ne.common.neType')" name="neType ">
|
||||||
|
<a-auto-complete
|
||||||
|
v-model:value="queryParams.neType"
|
||||||
|
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
|
||||||
|
:allow-clear="true"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item :label="t('views.ne.common.neId')" name="neId">
|
||||||
|
<a-input
|
||||||
|
v-model:value="queryParams.neId"
|
||||||
|
:allow-clear="true"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.serialNum')"
|
||||||
|
name="serialNum"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="queryParams.serialNum"
|
||||||
|
:allow-clear="true"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="12" :xs="24">
|
||||||
|
<a-form-item>
|
||||||
|
<a-space :size="8">
|
||||||
|
<a-button type="primary" @click.prevent="fnGetList(1)">
|
||||||
|
<template #icon><SearchOutlined /></template>
|
||||||
|
{{ t('common.search') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="default" @click.prevent="fnQueryReset">
|
||||||
|
<template #icon><ClearOutlined /></template>
|
||||||
|
{{ t('common.reset') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||||
|
<!-- 插槽-卡片左侧侧 -->
|
||||||
|
<template #title>
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-button
|
||||||
|
type="default"
|
||||||
|
:disabled="tableState.selectedRowKeys.length <= 0"
|
||||||
|
:loading="modalState.confirmLoading"
|
||||||
|
@click.prevent="fnRecordStateBatch()"
|
||||||
|
>
|
||||||
|
<template #icon><SecurityScanOutlined /></template>
|
||||||
|
{{ t('views.ne.neLicense.reloadBatch') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 插槽-卡片右侧 -->
|
||||||
|
<template #extra>
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.searchBarText') }}</template>
|
||||||
|
<a-switch
|
||||||
|
v-model:checked="tableState.seached"
|
||||||
|
:checked-children="t('common.switch.show')"
|
||||||
|
:un-checked-children="t('common.switch.hide')"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title>{{ t('common.reloadText') }}</template>
|
||||||
|
<a-button type="text" @click.prevent="fnGetList()">
|
||||||
|
<template #icon><ReloadOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip placement="topRight">
|
||||||
|
<template #title>{{ t('common.sizeText') }}</template>
|
||||||
|
<a-dropdown placement="bottomRight" trigger="click">
|
||||||
|
<a-button type="text">
|
||||||
|
<template #icon><ColumnHeightOutlined /></template>
|
||||||
|
</a-button>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu
|
||||||
|
:selected-keys="[tableState.size as string]"
|
||||||
|
@click="fnTableSize"
|
||||||
|
>
|
||||||
|
<a-menu-item key="default">
|
||||||
|
{{ t('common.size.default') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="middle">
|
||||||
|
{{ t('common.size.middle') }}
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="small">
|
||||||
|
{{ t('common.size.small') }}
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 表格列表 -->
|
||||||
|
<a-table
|
||||||
|
class="table"
|
||||||
|
row-key="id"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:loading="tableState.loading"
|
||||||
|
:data-source="tableState.data"
|
||||||
|
:size="tableState.size"
|
||||||
|
:pagination="tablePagination"
|
||||||
|
:scroll="{ x: tableColumns.length * 120 }"
|
||||||
|
@resizeColumn="(w:number, col:any) => (col.width = w)"
|
||||||
|
:row-selection="{
|
||||||
|
type: 'checkbox',
|
||||||
|
columnWidth: '48px',
|
||||||
|
selectedRowKeys: tableState.selectedRowKeys,
|
||||||
|
onChange: fnTableSelectedRowKeys,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'status'">
|
||||||
|
<DictTag :options="dictStatus" :value="record.status" />
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'remark'">
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>{{ record.remark }}</template>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 50px;
|
||||||
|
"
|
||||||
|
:style="{ width: column.width + 'px' }"
|
||||||
|
>
|
||||||
|
{{ record.remark }}
|
||||||
|
</div>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'id'">
|
||||||
|
<a-space :size="8" align="center">
|
||||||
|
<a-tooltip placement="topRight">
|
||||||
|
<template #title>{{ t('views.ne.neLicense.change') }}</template>
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click.prevent="fnModalVisibleByEdit(record.id)"
|
||||||
|
>
|
||||||
|
<template #icon><InteractionOutlined /> </template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<a-tooltip placement="topRight">
|
||||||
|
<template #title>{{ t('views.ne.neLicense.reload') }}</template>
|
||||||
|
<a-button type="link" @click.prevent="fnRecordState(record)">
|
||||||
|
<template #icon><SecurityScanOutlined /> </template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 文件上传框 -->
|
||||||
|
<EditModal
|
||||||
|
v-model:visible="modalState.visibleByEdit"
|
||||||
|
:edit-id="modalState.licenseId"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
></EditModal>
|
||||||
|
</PageContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.table :deep(.ant-pagination) {
|
||||||
|
padding: 0 24px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,484 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Form, Modal, message } from 'ant-design-vue/lib';
|
||||||
|
import { onMounted, reactive, toRaw } from 'vue';
|
||||||
|
import { addNeInfo, getNeInfoByTypeAndID, updateNeInfo } from '@/api/ne/neInfo';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||||
|
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
|
||||||
|
import { fnRestStepState, fnToStepName, stepState } from '../hooks/useStep';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import useDictStore from '@/store/modules/dict';
|
||||||
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
|
const { getDict } = useDictStore();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
/**字典数据 */
|
||||||
|
let dict: {
|
||||||
|
/**主机类型 */
|
||||||
|
neHostType: DictType[];
|
||||||
|
/**分组 */
|
||||||
|
neHostGroupId: DictType[];
|
||||||
|
/**认证模式 */
|
||||||
|
neHostAuthMode: DictType[];
|
||||||
|
} = reactive({
|
||||||
|
neHostType: [],
|
||||||
|
neHostGroupId: [],
|
||||||
|
neHostAuthMode: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**是否可以下一步 */
|
||||||
|
stepNext: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: Record<string, any>;
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
stepNext: false,
|
||||||
|
title: '网元',
|
||||||
|
from: {
|
||||||
|
id: undefined,
|
||||||
|
neId: '',
|
||||||
|
neType: '',
|
||||||
|
neName: '',
|
||||||
|
ip: '',
|
||||||
|
port: 33030,
|
||||||
|
pvFlag: 'PNF',
|
||||||
|
rmUid: '4400HXAMF001',
|
||||||
|
neAddress: '',
|
||||||
|
dn: '-',
|
||||||
|
vendorName: '-',
|
||||||
|
province: '-',
|
||||||
|
// 主机
|
||||||
|
hosts: [
|
||||||
|
{
|
||||||
|
hostId: undefined,
|
||||||
|
hostType: 'ssh',
|
||||||
|
groupId: '1',
|
||||||
|
title: 'SSH_NE_22',
|
||||||
|
addr: '',
|
||||||
|
port: 22,
|
||||||
|
user: 'user',
|
||||||
|
authMode: '0',
|
||||||
|
password: 'user',
|
||||||
|
privateKey: '',
|
||||||
|
passPhrase: '',
|
||||||
|
remark: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostId: undefined,
|
||||||
|
hostType: 'telnet',
|
||||||
|
groupId: '1',
|
||||||
|
title: 'Telnet_NE_4100',
|
||||||
|
addr: '',
|
||||||
|
port: 4100,
|
||||||
|
user: 'admin',
|
||||||
|
authMode: '0',
|
||||||
|
password: 'admin',
|
||||||
|
remark: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
neType: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.common.neTypePlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
neId: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.common.neIdPlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
ip: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: modalStateFromEqualIPV4AndIPV6,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**表单验证IP地址是否有效 */
|
||||||
|
function modalStateFromEqualIPV4AndIPV6(
|
||||||
|
rule: Record<string, any>,
|
||||||
|
value: string,
|
||||||
|
callback: (error?: string) => void
|
||||||
|
) {
|
||||||
|
if (!value) {
|
||||||
|
return Promise.reject(t('views.ne.common.ipAddrPlease'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.indexOf('.') === -1 && value.indexOf(':') === -1) {
|
||||||
|
return Promise.reject(t('valid.ipPlease'));
|
||||||
|
}
|
||||||
|
if (value.indexOf('.') !== -1 && !regExpIPv4.test(value)) {
|
||||||
|
return Promise.reject(t('valid.ipv4Reg'));
|
||||||
|
}
|
||||||
|
if (value.indexOf(':') !== -1 && !regExpIPv6.test(value)) {
|
||||||
|
return Promise.reject(t('valid.ipv6Reg'));
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
return getNeInfoByTypeAndID(from.neType, from.neId);
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// 补充更新必要信息
|
||||||
|
from.id = res.data.id;
|
||||||
|
from.hostIds = res.data.hostIds;
|
||||||
|
const hostIds = res.data.hostIds.split(',');
|
||||||
|
if (hostIds.length == 2) {
|
||||||
|
from.hosts[0].hostId = hostIds[0];
|
||||||
|
from.hosts[1].hostId = hostIds[1];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// 清除更新必要信息
|
||||||
|
from.id = undefined;
|
||||||
|
from.hostIds = '';
|
||||||
|
for (let index = 0; index < from.hosts.length; index++) {
|
||||||
|
from.hosts[index].hostId = undefined;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(isUpdate => {
|
||||||
|
let confirmTitle = t('views.ne.neQuickSetup.configAddTitle');
|
||||||
|
let confirmContent = t('views.ne.neQuickSetup.configAddTip');
|
||||||
|
if (isUpdate) {
|
||||||
|
confirmTitle = t('views.ne.neQuickSetup.configUpdateTitle');
|
||||||
|
confirmContent = t('views.ne.neQuickSetup.configUpdateTip');
|
||||||
|
}
|
||||||
|
Modal.confirm({
|
||||||
|
title: confirmTitle,
|
||||||
|
content: confirmContent,
|
||||||
|
onCancel: () => {
|
||||||
|
// 清除更新必要信息
|
||||||
|
from.id = undefined;
|
||||||
|
from.hostIds = '';
|
||||||
|
for (let index = 0; index < from.hosts.length; index++) {
|
||||||
|
from.hosts[index].hostId = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onOk: () => {
|
||||||
|
from.rmUid = `4400HX${from.neType}${from.neId}`; // 4400HX1AMF001
|
||||||
|
from.neName = `${from.neType}_${from.neId}`; // AMF_001
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const result =
|
||||||
|
isUpdate && from.id ? updateNeInfo(from) : addNeInfo(from);
|
||||||
|
result
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success({
|
||||||
|
content: `${t('common.operateOk')}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
// 刷新缓存的网元信息
|
||||||
|
useNeInfoStore().fnRefreshNelist();
|
||||||
|
stepState.neInfo = from; // 保存网元信息
|
||||||
|
modalState.stepNext = true; // 开启下一步
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: res.msg,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单修改网元类型
|
||||||
|
*/
|
||||||
|
function fnNeTypeChange(v: any) {
|
||||||
|
const hostsLen = modalState.from.hosts.length;
|
||||||
|
// 网元默认只含22和4100
|
||||||
|
if (hostsLen === 3 && v !== 'UPF') {
|
||||||
|
modalState.from.hosts.pop();
|
||||||
|
}
|
||||||
|
// UPF标准版本可支持5002
|
||||||
|
if (hostsLen === 2 && v === 'UPF') {
|
||||||
|
modalState.from.hosts.push({
|
||||||
|
hostId: undefined,
|
||||||
|
hostType: 'telnet',
|
||||||
|
groupId: '1',
|
||||||
|
title: 'Telnet_NE_5002',
|
||||||
|
addr: modalState.from.ip,
|
||||||
|
port: 5002,
|
||||||
|
user: 'admin',
|
||||||
|
authMode: '0',
|
||||||
|
password: 'admin',
|
||||||
|
remark: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单修改网元IP
|
||||||
|
*/
|
||||||
|
function fnNeIPChange(e: any) {
|
||||||
|
const v = e.target.value;
|
||||||
|
if (v.length < 7) return;
|
||||||
|
for (const host of modalState.from.hosts) {
|
||||||
|
host.addr = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**返回上一步 */
|
||||||
|
function fnStepPrev() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neQuickSetup.stepPrevTip'),
|
||||||
|
onOk() {
|
||||||
|
fnRestStepState();
|
||||||
|
fnToStepName('Start');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**下一步操作 */
|
||||||
|
function fnStepNext() {
|
||||||
|
if (!modalState.stepNext) return;
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neQuickSetup.configStepNext'),
|
||||||
|
onOk() {
|
||||||
|
fnToStepName('NeInfoSoftwareInstall');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始字典数据
|
||||||
|
Promise.allSettled([
|
||||||
|
getDict('ne_host_type'),
|
||||||
|
getDict('ne_host_groupId'),
|
||||||
|
getDict('ne_host_authMode'),
|
||||||
|
])
|
||||||
|
.then(resArr => {
|
||||||
|
if (resArr[0].status === 'fulfilled') {
|
||||||
|
dict.neHostType = resArr[0].value;
|
||||||
|
}
|
||||||
|
if (resArr[1].status === 'fulfilled') {
|
||||||
|
dict.neHostGroupId = resArr[1].value;
|
||||||
|
}
|
||||||
|
if (resArr[2].status === 'fulfilled') {
|
||||||
|
dict.neHostAuthMode = resArr[2].value;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
if (stepState.neInfo.id) {
|
||||||
|
Object.assign(modalState.from, stepState.neInfo);
|
||||||
|
} else {
|
||||||
|
modalState.from.ip = stepState.neHost.addr;
|
||||||
|
Object.assign(modalState.from.hosts[0], stepState.neHost);
|
||||||
|
Object.assign(modalState.from.hosts[1], {
|
||||||
|
addr: modalState.from.ip,
|
||||||
|
user: 'admin',
|
||||||
|
password: 'admin',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="ne">
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="6" :md="6" :xs="24" :offset="6">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.neType')"
|
||||||
|
name="neType"
|
||||||
|
v-bind="modalStateFrom.validateInfos.neType"
|
||||||
|
>
|
||||||
|
<a-auto-complete
|
||||||
|
v-model:value="modalState.from.neType"
|
||||||
|
:options="
|
||||||
|
NE_TYPE_LIST.filter(s => s !== 'OMC').map(v => ({ value: v }))
|
||||||
|
"
|
||||||
|
@change="fnNeTypeChange"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="32"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
{{ t('views.ne.common.neTypeTip') }}
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-auto-complete>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="6" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.neId')"
|
||||||
|
name="neId"
|
||||||
|
v-bind="modalStateFrom.validateInfos.neId"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.neId"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="24"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
{{ t('views.ne.common.neIdTip') }}
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :lg="6" :md="6" :xs="24" :offset="6">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.ipAddr')"
|
||||||
|
name="ip"
|
||||||
|
v-bind="modalStateFrom.validateInfos.ip"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.ip"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="128"
|
||||||
|
@change="fnNeIPChange"
|
||||||
|
:disabled="true"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
<div>
|
||||||
|
{{ t('views.ne.common.ipAddrTip') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :lg="6" :md="6" :xs="24">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.port')"
|
||||||
|
name="port"
|
||||||
|
v-bind="modalStateFrom.validateInfos.port"
|
||||||
|
>
|
||||||
|
<a-input-number
|
||||||
|
v-model:value="modalState.from.port"
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
:maxlength="5"
|
||||||
|
placeholder="<=65535"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>
|
||||||
|
<div>{{ t('views.ne.common.portTip') }}</div>
|
||||||
|
</template>
|
||||||
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input-number>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-form>
|
||||||
|
|
||||||
|
<div class="ne-oper">
|
||||||
|
<a-space direction="horizontal" :size="18">
|
||||||
|
<a-button @click="fnStepPrev()">
|
||||||
|
{{ t('views.ne.neQuickSetup.stepPrev') }}
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
ghost
|
||||||
|
@click="fnModalOk()"
|
||||||
|
:loading="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
{{ t('views.ne.neQuickSetup.stepSave') }}
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click="fnStepNext()"
|
||||||
|
:disabled="!modalState.stepNext"
|
||||||
|
>
|
||||||
|
{{ t('views.ne.neQuickSetup.stepNext') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.ne {
|
||||||
|
min-height: 400px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
& .ant-form {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-oper {
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,441 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Modal, TableColumnsType, message } from 'ant-design-vue/lib';
|
||||||
|
import { defineAsyncComponent, onMounted, reactive, ref, toRaw } from 'vue';
|
||||||
|
import { fnToStepName, stepState } from '../hooks/useStep';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { listNeVersion, operateNeVersion } from '@/api/ne/neVersion';
|
||||||
|
import {
|
||||||
|
RESULT_CODE_ERROR,
|
||||||
|
RESULT_CODE_SUCCESS,
|
||||||
|
} from '@/constants/result-constants';
|
||||||
|
import {
|
||||||
|
addNeSoftware,
|
||||||
|
listNeSoftware,
|
||||||
|
newNeVersion,
|
||||||
|
} from '@/api/ne/neSoftware';
|
||||||
|
import { parseDateToStr } from '@/utils/date-utils';
|
||||||
|
import { ColumnsType } from 'ant-design-vue/lib/table';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const EditModal = defineAsyncComponent(
|
||||||
|
() => import('../../../ne/neSoftware/components/EditModal.vue')
|
||||||
|
);
|
||||||
|
|
||||||
|
/**表格字段列 */
|
||||||
|
let tableColumns: ColumnsType = [
|
||||||
|
{
|
||||||
|
title: t('common.rowId'),
|
||||||
|
dataIndex: 'id',
|
||||||
|
align: 'left',
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.common.neType'),
|
||||||
|
dataIndex: 'neType',
|
||||||
|
align: 'left',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.neSoftware.version'),
|
||||||
|
dataIndex: 'version',
|
||||||
|
align: 'left',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.neSoftware.name'),
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name',
|
||||||
|
align: 'left',
|
||||||
|
width: 300,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('common.description'),
|
||||||
|
dataIndex: 'description',
|
||||||
|
key: 'description',
|
||||||
|
align: 'left',
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('common.createTime'),
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
align: 'left',
|
||||||
|
width: 150,
|
||||||
|
customRender(opt) {
|
||||||
|
if (!opt.value) return '';
|
||||||
|
return parseDateToStr(+opt.value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**表格分页器参数 */
|
||||||
|
let tablePagination = reactive({
|
||||||
|
/**当前页数 */
|
||||||
|
current: 1,
|
||||||
|
/**每页条数 */
|
||||||
|
pageSize: 10,
|
||||||
|
/**默认的每页条数 */
|
||||||
|
defaultPageSize: 10,
|
||||||
|
/**指定每页可以显示多少条 */
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100'],
|
||||||
|
/**只有一页时是否隐藏分页器 */
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
/**是否可以快速跳转至某页 */
|
||||||
|
showQuickJumper: true,
|
||||||
|
/**是否可以改变 pageSize */
|
||||||
|
showSizeChanger: true,
|
||||||
|
/**数据总数 */
|
||||||
|
total: 0,
|
||||||
|
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
|
||||||
|
onChange: (page: number, pageSize: number) => {
|
||||||
|
tablePagination.current = page;
|
||||||
|
tablePagination.pageSize = pageSize;
|
||||||
|
tableState.queryParams.pageNum = page;
|
||||||
|
tableState.queryParams.pageSize = pageSize;
|
||||||
|
fnGetList();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格状态类型 */
|
||||||
|
type TabeStateType = {
|
||||||
|
/**查询参数 */
|
||||||
|
queryParams: Record<string, any>;
|
||||||
|
/**加载等待 */
|
||||||
|
loading: boolean;
|
||||||
|
/**记录数据 */
|
||||||
|
data: object[];
|
||||||
|
/**勾选记录 */
|
||||||
|
selectedRowKeys: (string | number)[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**表格状态 */
|
||||||
|
let tableState: TabeStateType = reactive({
|
||||||
|
queryParams: {
|
||||||
|
neType: '',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
},
|
||||||
|
loading: false,
|
||||||
|
data: [],
|
||||||
|
selectedRowKeys: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**表格多选 */
|
||||||
|
function fnTableSelectedRowKeys(
|
||||||
|
keys: (string | number)[],
|
||||||
|
selectedRows: any[]
|
||||||
|
) {
|
||||||
|
tableState.selectedRowKeys = keys;
|
||||||
|
// 选择的表单数据填充
|
||||||
|
Object.assign(state.from, selectedRows[0], { id: '' });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**查询列表, pageNum初始页数 */
|
||||||
|
function fnGetList(pageNum?: number) {
|
||||||
|
if (tableState.loading) return;
|
||||||
|
tableState.loading = true;
|
||||||
|
if (pageNum) {
|
||||||
|
tableState.queryParams.pageNum = pageNum;
|
||||||
|
}
|
||||||
|
listNeSoftware(toRaw(tableState.queryParams)).then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
||||||
|
// 取消勾选
|
||||||
|
if (tableState.selectedRowKeys.length > 0) {
|
||||||
|
tableState.selectedRowKeys = [];
|
||||||
|
}
|
||||||
|
tablePagination.total = res.total;
|
||||||
|
// 遍历处理资源情况数值
|
||||||
|
tableState.data = res.rows;
|
||||||
|
}
|
||||||
|
tableState.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对象信息信息状态类型 */
|
||||||
|
type StateType = {
|
||||||
|
/**是否可以下一步 */
|
||||||
|
stepNext: boolean;
|
||||||
|
/**文件操作类型 上传 or 选择 */
|
||||||
|
optionType: 'upload' | 'option';
|
||||||
|
/**文件上传 */
|
||||||
|
visibleByFile: boolean;
|
||||||
|
/**
|
||||||
|
* 依赖包类型
|
||||||
|
* IMS-rtproxy/mf/adb
|
||||||
|
* UDM-adb
|
||||||
|
*/
|
||||||
|
depType: string[];
|
||||||
|
/**软件包信息数据 */
|
||||||
|
from: {
|
||||||
|
neType: string; // 版本需要
|
||||||
|
neId: string; // 版本需要
|
||||||
|
name: string; // 软件需要
|
||||||
|
path: string;
|
||||||
|
version: string; // 软件需要
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对象信息状态 */
|
||||||
|
let state: StateType = reactive({
|
||||||
|
stepNext: false,
|
||||||
|
optionType: 'option',
|
||||||
|
visibleByFile: false,
|
||||||
|
depType: [],
|
||||||
|
from: {
|
||||||
|
id: undefined,
|
||||||
|
neType: '',
|
||||||
|
neId: '',
|
||||||
|
name: '',
|
||||||
|
path: '',
|
||||||
|
version: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单修改文件操作类型
|
||||||
|
*/
|
||||||
|
function fnOptionTypeChange() {
|
||||||
|
state.from.name = '';
|
||||||
|
state.from.version = '';
|
||||||
|
tableState.selectedRowKeys = [];
|
||||||
|
if (state.optionType === 'option') {
|
||||||
|
fnGetList(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框弹出 */
|
||||||
|
function fnModalOpen() {
|
||||||
|
state.visibleByFile = !state.visibleByFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框弹出确认执行函数*/
|
||||||
|
function fnModalOk(e: any) {
|
||||||
|
Object.assign(state.from, e, { id: '' });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框弹出关闭执行函数*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
state.visibleByFile = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**版本安装 */
|
||||||
|
function fnRecordInstall() {
|
||||||
|
const from = toRaw(state.from);
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neQuickSetup.installConfirmTip', {
|
||||||
|
name: from.name,
|
||||||
|
}),
|
||||||
|
onOk: async () => {
|
||||||
|
if (state.confirmLoading) return;
|
||||||
|
state.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
|
||||||
|
// 选择的软件需要更新版本
|
||||||
|
if (state.optionType === 'option') {
|
||||||
|
const res = await newNeVersion(from);
|
||||||
|
if (res.code === RESULT_CODE_ERROR) {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
hide();
|
||||||
|
state.confirmLoading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进行安装
|
||||||
|
let preinput = {};
|
||||||
|
if (from.neType.toUpperCase() === 'IMS') {
|
||||||
|
preinput = { pisCSCF: 'y', updateMFetc: 'No', updateMFshare: 'No' };
|
||||||
|
}
|
||||||
|
const res = await operateNeVersion({
|
||||||
|
neType: from.neType,
|
||||||
|
neId: from.neId,
|
||||||
|
action: 'install',
|
||||||
|
preinput: preinput,
|
||||||
|
});
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success(t('common.operateOk'), 3);
|
||||||
|
state.stepNext = true;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非选择的重置
|
||||||
|
state.optionType = 'option';
|
||||||
|
fnOptionTypeChange();
|
||||||
|
hide();
|
||||||
|
state.confirmLoading = false;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**返回上一步 */
|
||||||
|
function fnStepPrev() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neQuickSetup.stepPrevTip'),
|
||||||
|
onOk() {
|
||||||
|
fnToStepName('NeInfoConfig');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**下一步操作 */
|
||||||
|
function fnStepNext() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neQuickSetup.installStepNext'),
|
||||||
|
onOk() {
|
||||||
|
fnToStepName('NeInfoSoftwareLicense');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const { neType, neId } = stepState.neInfo;
|
||||||
|
if (neId) {
|
||||||
|
tableState.queryParams.neType = neType;
|
||||||
|
state.from.neType = neType;
|
||||||
|
state.from.neId = neId;
|
||||||
|
fnGetList(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="ne">
|
||||||
|
<a-form
|
||||||
|
name="installStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:label-col="{ span: 4 }"
|
||||||
|
:wrapper-col="{ span: 16 }"
|
||||||
|
:label-wrap="true"
|
||||||
|
>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neQuickSetup.installSource')"
|
||||||
|
name="optionType"
|
||||||
|
>
|
||||||
|
<a-radio-group
|
||||||
|
v-model:value="state.optionType"
|
||||||
|
button-style="solid"
|
||||||
|
:disabled="state.confirmLoading"
|
||||||
|
@change="fnOptionTypeChange"
|
||||||
|
>
|
||||||
|
<a-radio-button value="option">
|
||||||
|
{{ t('views.ne.neQuickSetup.installSourceOption') }}
|
||||||
|
</a-radio-button>
|
||||||
|
<a-radio-button value="upload">
|
||||||
|
{{ t('views.ne.neQuickSetup.installSourceUpload') }}
|
||||||
|
</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<!-- 选择已上传 -->
|
||||||
|
<template v-if="state.optionType === 'option'">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neQuickSetup.installSelect')"
|
||||||
|
name="option"
|
||||||
|
>
|
||||||
|
<a-table
|
||||||
|
class="table"
|
||||||
|
row-key="id"
|
||||||
|
:columns="tableColumns"
|
||||||
|
:loading="tableState.loading"
|
||||||
|
:data-source="tableState.data"
|
||||||
|
:pagination="tablePagination"
|
||||||
|
size="small"
|
||||||
|
:scroll="{ x: tableColumns.length * 100, y: '400px' }"
|
||||||
|
:row-selection="{
|
||||||
|
type: 'radio',
|
||||||
|
columnWidth: '48px',
|
||||||
|
selectedRowKeys: tableState.selectedRowKeys,
|
||||||
|
onChange: fnTableSelectedRowKeys,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'name'">
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>{{ record.path }}</template>
|
||||||
|
<div style="cursor: pointer">{{ record.name }}</div>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'description'">
|
||||||
|
<a-tooltip placement="topLeft">
|
||||||
|
<template #title>{{ record.description }}</template>
|
||||||
|
<div style="cursor: pointer">{{ record.description }}</div>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 重新上传 -->
|
||||||
|
<template v-if="state.optionType === 'upload'">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neQuickSetup.installUpload')"
|
||||||
|
name="upload"
|
||||||
|
:help="state.from.name"
|
||||||
|
>
|
||||||
|
<a-button type="primary" @click.prevent="fnModalOpen()">
|
||||||
|
<template #icon><UploadOutlined /></template>
|
||||||
|
{{ t('views.ne.neSoftware.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
</a-form>
|
||||||
|
|
||||||
|
<!-- 文件上传框 -->
|
||||||
|
<EditModal
|
||||||
|
v-model:visible="state.visibleByFile"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
></EditModal>
|
||||||
|
|
||||||
|
<div class="ne-oper">
|
||||||
|
<a-space direction="horizontal" :size="18">
|
||||||
|
<a-button @click="fnStepPrev()">
|
||||||
|
{{ t('views.ne.neQuickSetup.stepPrev') }}
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
ghost
|
||||||
|
:disabled="!state.from.version"
|
||||||
|
:loading="state.confirmLoading"
|
||||||
|
@click.prevent="fnRecordInstall()"
|
||||||
|
>
|
||||||
|
<template #icon><ThunderboltOutlined /></template>
|
||||||
|
{{ t('views.ne.neQuickSetup.installText') }}
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click="fnStepNext()"
|
||||||
|
:disabled="!state.stepNext"
|
||||||
|
>
|
||||||
|
{{ t('views.ne.neQuickSetup.stepNext') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.ne {
|
||||||
|
min-height: 400px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
& .ant-form {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-oper {
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Modal } from 'ant-design-vue/lib';
|
||||||
|
import { defineAsyncComponent, onMounted, onUnmounted, reactive } from 'vue';
|
||||||
|
import { fnRestStepState, stepState } from '../hooks/useStep';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { codeNeLicense, stateNeLicense } from '@/api/ne/neLicense';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const EditModal = defineAsyncComponent(
|
||||||
|
() => import('../../../ne/neLicense/components/EditModal.vue')
|
||||||
|
);
|
||||||
|
|
||||||
|
/**对象信息信息状态类型 */
|
||||||
|
type StateType = {
|
||||||
|
/**文件上传 */
|
||||||
|
visibleByFile: boolean;
|
||||||
|
/**授权信息数据 */
|
||||||
|
from: {
|
||||||
|
neType: string;
|
||||||
|
neId: string;
|
||||||
|
// 下面是状态检查结果
|
||||||
|
expire: string;
|
||||||
|
sn: string;
|
||||||
|
};
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
/**定时调度 */
|
||||||
|
timeInterval: any;
|
||||||
|
timeCount: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对象信息状态 */
|
||||||
|
let state: StateType = reactive({
|
||||||
|
visibleByFile: false,
|
||||||
|
from: {
|
||||||
|
neType: '',
|
||||||
|
neId: '',
|
||||||
|
expire: '',
|
||||||
|
sn: '',
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
timeInterval: null,
|
||||||
|
timeCount: 30,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框弹出确认执行函数*/
|
||||||
|
function fnModalOk(e: any) {
|
||||||
|
state.timeInterval = setInterval(() => {
|
||||||
|
if (state.timeCount <= 0) {
|
||||||
|
state.from.sn = '';
|
||||||
|
state.from.expire = '';
|
||||||
|
clearInterval(state.timeInterval);
|
||||||
|
state.timeInterval = null;
|
||||||
|
state.timeCount = 30;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state.timeCount % 5 === 0) {
|
||||||
|
stateNeLicense(e.neType, e.neId).then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
||||||
|
state.from.sn = res.data.sn;
|
||||||
|
state.from.expire = res.data.expire;
|
||||||
|
|
||||||
|
clearInterval(state.timeInterval);
|
||||||
|
state.timeInterval = null;
|
||||||
|
state.timeCount = 30;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
state.timeCount--;
|
||||||
|
}, 1_000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框弹出关闭执行函数*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
state.visibleByFile = false;
|
||||||
|
state.confirmLoading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**结束操作 */
|
||||||
|
function fnStepEnd() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neQuickSetup.licenseEndTip'),
|
||||||
|
onOk() {
|
||||||
|
fnRestStepState();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const { neType, neId } = stepState.neInfo;
|
||||||
|
if (neId) {
|
||||||
|
state.from.neType = neType;
|
||||||
|
state.from.neId = neId;
|
||||||
|
state.confirmLoading = true;
|
||||||
|
stateNeLicense(neType, neId)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
||||||
|
state.from.sn = res.data.sn;
|
||||||
|
state.from.expire = res.data.expire;
|
||||||
|
} else {
|
||||||
|
return codeNeLicense(neType, neId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
state.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(state.timeInterval);
|
||||||
|
state.timeInterval = null;
|
||||||
|
state.timeCount = 30;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-result
|
||||||
|
:status="!state.from.sn ? 'info' : 'success'"
|
||||||
|
:title="
|
||||||
|
t(
|
||||||
|
!state.from.sn
|
||||||
|
? 'views.ne.neQuickSetup.licenseResultTitle'
|
||||||
|
: 'views.ne.neQuickSetup.licenseResultTitleOk'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #extra>
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
:disabled="state.from.sn !== ''"
|
||||||
|
:loading="state.timeCount < 30 || state.confirmLoading"
|
||||||
|
@click="() => (state.visibleByFile = !state.visibleByFile)"
|
||||||
|
>
|
||||||
|
{{ t('views.ne.neQuickSetup.licenseUpload') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
type="default"
|
||||||
|
:disabled="state.timeCount < 30 || state.confirmLoading"
|
||||||
|
@click="fnStepEnd()"
|
||||||
|
>
|
||||||
|
{{ t('views.ne.neQuickSetup.licenseEnd') }}
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
state.timeInterval === null && state.timeCount === 30 && !state.from.sn
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<p>{{ t('views.ne.neQuickSetup.licenseTip1') }}</p>
|
||||||
|
<p>{{ t('views.ne.neQuickSetup.licenseTip2') }}</p>
|
||||||
|
</div>
|
||||||
|
<div v-if="state.timeInterval !== null">
|
||||||
|
<a-space direction="horizontal" :size="16">
|
||||||
|
<a-spin />
|
||||||
|
{{ t('views.ne.neQuickSetup.licenseCheack') }} {{ state.timeCount }}s
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
<div v-if="state.from.sn !== ''" style="font-size: 16px">
|
||||||
|
<p>{{ t('views.ne.common.neType') }}:{{ state.from.neType }}</p>
|
||||||
|
<p>{{ t('views.ne.common.neId') }}:{{ state.from.neId }}</p>
|
||||||
|
<p>{{ t('views.ne.common.serialNum') }}:{{ state.from.sn }}</p>
|
||||||
|
<p>{{ t('views.ne.common.expiryDate') }}:{{ state.from.expire }}</p>
|
||||||
|
</div>
|
||||||
|
</a-result>
|
||||||
|
|
||||||
|
<!-- 许可证上传框 -->
|
||||||
|
<EditModal
|
||||||
|
v-model:visible="state.visibleByFile"
|
||||||
|
:ne-type="state.from.neType"
|
||||||
|
:ne-id="state.from.neId"
|
||||||
|
:reload="true"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
></EditModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
+164
-114
@@ -3,9 +3,10 @@ import { reactive, onMounted, toRaw } from 'vue';
|
|||||||
import { message, Form, Modal } from 'ant-design-vue/lib';
|
import { message, Form, Modal } from 'ant-design-vue/lib';
|
||||||
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 { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
|
||||||
import { neHostAuthorizedRSA, neHostCheckInfo } from '@/api/ne/neHost';
|
import { neHostAuthorizedRSA, neHostCheckInfo } from '@/api/ne/neHost';
|
||||||
import useDictStore from '@/store/modules/dict';
|
import useDictStore from '@/store/modules/dict';
|
||||||
import { stepState } from '../hooks/useStep';
|
import { fnToStepName, stepState } from '../hooks/useStep';
|
||||||
const { getDict } = useDictStore();
|
const { getDict } = useDictStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -17,20 +18,22 @@ let dict: {
|
|||||||
neHostAuthMode: [],
|
neHostAuthMode: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
/**检查对象信息状态类型 */
|
/**对象信息状态类型 */
|
||||||
type CheckStateType = {
|
type StateType = {
|
||||||
/**服务器信息 */
|
/**服务器信息 */
|
||||||
info: Record<string, any>;
|
info: Record<string, any>;
|
||||||
/**表单数据 */
|
/**表单数据 */
|
||||||
from: Record<string, any>;
|
from: Record<string, any>;
|
||||||
|
/**是否可以下一步 */
|
||||||
|
stepNext: boolean;
|
||||||
/**确定按钮 loading */
|
/**确定按钮 loading */
|
||||||
confirmLoading: boolean;
|
confirmLoading: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**检查对象信息状态 */
|
/**对象信息状态 */
|
||||||
let checkState: CheckStateType = reactive({
|
let state: StateType = reactive({
|
||||||
info: {
|
info: {
|
||||||
addr: '未连接',
|
addr: '0.0.0.0',
|
||||||
kernelName: '-',
|
kernelName: '-',
|
||||||
kernelRelease: '-',
|
kernelRelease: '-',
|
||||||
machine: '-',
|
machine: '-',
|
||||||
@@ -44,28 +47,29 @@ let checkState: CheckStateType = reactive({
|
|||||||
hostType: 'ssh',
|
hostType: 'ssh',
|
||||||
groupId: '1',
|
groupId: '1',
|
||||||
title: 'SSH_NE_22',
|
title: 'SSH_NE_22',
|
||||||
addr: '192.168.5.57',
|
addr: '',
|
||||||
port: 22,
|
port: 22,
|
||||||
user: 'agtuser',
|
user: '',
|
||||||
authMode: '0',
|
authMode: '2',
|
||||||
password: 'QWERqwer',
|
password: '',
|
||||||
privateKey: '',
|
privateKey: '',
|
||||||
passPhrase: '',
|
passPhrase: '',
|
||||||
remark: '',
|
remark: '',
|
||||||
},
|
},
|
||||||
|
stepNext: false,
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**表单属性和校验规则 */
|
/**表单属性和校验规则 */
|
||||||
const checkStateFrom = Form.useForm(
|
const checkStateFrom = Form.useForm(
|
||||||
checkState.from,
|
state.from,
|
||||||
reactive({
|
reactive({
|
||||||
addr: [
|
addr: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 128,
|
max: 128,
|
||||||
message: t('views.ne.neHost.addrPlease'),
|
validator: modalStateFromEqualIPV4AndIPV6,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
port: [
|
port: [
|
||||||
@@ -94,31 +98,54 @@ const checkStateFrom = Form.useForm(
|
|||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 128,
|
max: 3000,
|
||||||
message: t('views.ne.neHost.privateKeyPlease'),
|
message: t('views.ne.neHost.privateKeyPlease'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**表单验证IP地址是否有效 */
|
||||||
|
function modalStateFromEqualIPV4AndIPV6(
|
||||||
|
rule: Record<string, any>,
|
||||||
|
value: string,
|
||||||
|
callback: (error?: string) => void
|
||||||
|
) {
|
||||||
|
if (!value) {
|
||||||
|
return Promise.reject(t('views.ne.common.ipAddrPlease'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.indexOf('.') === -1 && value.indexOf(':') === -1) {
|
||||||
|
return Promise.reject(t('valid.ipPlease'));
|
||||||
|
}
|
||||||
|
if (value.indexOf('.') !== -1 && !regExpIPv4.test(value)) {
|
||||||
|
return Promise.reject(t('valid.ipv4Reg'));
|
||||||
|
}
|
||||||
|
if (value.indexOf(':') !== -1 && !regExpIPv6.test(value)) {
|
||||||
|
return Promise.reject(t('valid.ipv6Reg'));
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
/**测试连接检查信息 */
|
/**测试连接检查信息 */
|
||||||
function fnCheckInfo() {
|
function fnCheckInfo() {
|
||||||
if (checkState.confirmLoading) return;
|
if (state.confirmLoading) return;
|
||||||
const form = toRaw(checkState.from);
|
const form = toRaw(state.from);
|
||||||
const validateArr = ['addr', 'port', 'user'];
|
const validateArr = ['addr', 'port', 'user'];
|
||||||
if (form.authMode === '0') {
|
if (form.authMode === '0') {
|
||||||
validateArr.push('password');
|
validateArr.push('password');
|
||||||
} else {
|
}
|
||||||
|
if (form.authMode === '1') {
|
||||||
validateArr.push('privateKey');
|
validateArr.push('privateKey');
|
||||||
}
|
}
|
||||||
|
|
||||||
checkState.confirmLoading = true;
|
state.confirmLoading = true;
|
||||||
const hide = message.loading(t('common.loading'), 0);
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
checkStateFrom
|
checkStateFrom
|
||||||
.validate(validateArr)
|
.validate(validateArr)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
Object.assign(checkState.info, {
|
Object.assign(state.info, {
|
||||||
addr: '未连接',
|
addr: '0.0.0.0',
|
||||||
kernelName: '-',
|
kernelName: '-',
|
||||||
kernelRelease: '-',
|
kernelRelease: '-',
|
||||||
machine: '-',
|
machine: '-',
|
||||||
@@ -127,36 +154,29 @@ function fnCheckInfo() {
|
|||||||
sshLink: false,
|
sshLink: false,
|
||||||
sudo: false,
|
sudo: false,
|
||||||
});
|
});
|
||||||
stepState.stepNext = false;
|
|
||||||
return neHostCheckInfo(form);
|
return neHostCheckInfo(form);
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
checkState.info = res.data;
|
state.info = res.data;
|
||||||
if (!res.data.sudo) {
|
if (!res.data.sudo) {
|
||||||
message.warning({
|
message.warning(t('views.ne.neQuickSetup.sudoErr'), 3);
|
||||||
content: `请配置服务器授予当前用户无密码 sudo 权限,确保有权限进行软件包安装`,
|
|
||||||
duration: 2,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!res.data.sshLink) {
|
|
||||||
message.warning({
|
|
||||||
content: `请配置服务器间免密信任关系,确保服务器间文件传输功能`,
|
|
||||||
duration: 2,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// if (!res.data.sshLink) {
|
||||||
|
// message.warning({
|
||||||
|
// content: `请配置服务器间免密信任关系,确保服务器间文件传输功能`,
|
||||||
|
// duration: 2,
|
||||||
|
// });
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
stepState.neHost = form; // 保存主机连接信息
|
||||||
|
state.stepNext = true; // 开启下一步
|
||||||
message.success({
|
message.success({
|
||||||
content: `${form.addr}:${form.port} ${t('views.ne.neHost.testOk')}`,
|
content: `${form.addr}:${form.port} ${t('views.ne.neHost.testOk')}`,
|
||||||
duration: 2,
|
duration: 2,
|
||||||
});
|
});
|
||||||
// 记录当前步骤状态信息
|
|
||||||
stepState.states[stepState.current] = {
|
|
||||||
info: checkState.info,
|
|
||||||
from: checkState.from,
|
|
||||||
};
|
|
||||||
stepState.stepNext = true;
|
|
||||||
} else {
|
} else {
|
||||||
message.error({
|
message.error({
|
||||||
content: `${form.addr}:${form.port} ${res.msg}`,
|
content: `${form.addr}:${form.port} ${res.msg}`,
|
||||||
@@ -169,41 +189,60 @@ function fnCheckInfo() {
|
|||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
hide();
|
hide();
|
||||||
checkState.confirmLoading = false;
|
state.confirmLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**测试连接检查信息表单重置 */
|
/**测试连接检查信息表单重置 */
|
||||||
function fnCheckInfoReset() {
|
function fnCheckInfoReset() {
|
||||||
|
Object.assign(state.info, {
|
||||||
|
addr: '0.0.0.0',
|
||||||
|
kernelName: '-',
|
||||||
|
kernelRelease: '-',
|
||||||
|
machine: '-',
|
||||||
|
nodename: '-',
|
||||||
|
prettyName: '-',
|
||||||
|
sshLink: false,
|
||||||
|
sudo: false,
|
||||||
|
});
|
||||||
|
state.stepNext = false;
|
||||||
checkStateFrom.resetFields();
|
checkStateFrom.resetFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**SSH连接-免密直连 */
|
/**测试主机连接-免密直连 */
|
||||||
function fnSSHLink() {
|
function fnHostAuthorized() {
|
||||||
if (checkState.info.sshLink) return;
|
if (state.confirmLoading) return;
|
||||||
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '提示',
|
title: t('common.tipTitle'),
|
||||||
content: '是否要配置免密直连?',
|
content: t('views.ne.neHost.authRSATip'),
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
const form = toRaw(checkState.from);
|
const form = toRaw(state.from);
|
||||||
|
state.confirmLoading = true;
|
||||||
neHostAuthorizedRSA(form).then(res => {
|
neHostAuthorizedRSA(form).then(res => {
|
||||||
|
state.confirmLoading = false;
|
||||||
if (res.code === RESULT_CODE_SUCCESS) {
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
message.success({
|
message.success(t('common.operateOk'), 3);
|
||||||
content: `操作成功`,
|
|
||||||
duration: 2,
|
|
||||||
});
|
|
||||||
checkState.info.sshLink = true;
|
|
||||||
} else {
|
} else {
|
||||||
message.error({
|
message.error(t('common.operateErr'), 3);
|
||||||
content: `操作失败`,
|
|
||||||
duration: 2,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**下一步操作 */
|
||||||
|
function fnStepNext() {
|
||||||
|
if (!state.stepNext) return;
|
||||||
|
Modal.confirm({
|
||||||
|
title: t('common.tipTitle'),
|
||||||
|
content: t('views.ne.neQuickSetup.startStepNext'),
|
||||||
|
onOk() {
|
||||||
|
fnToStepName('NeInfoConfig');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 初始字典数据
|
// 初始字典数据
|
||||||
Promise.allSettled([getDict('ne_host_authMode')]).then(resArr => {
|
Promise.allSettled([getDict('ne_host_authMode')]).then(resArr => {
|
||||||
@@ -211,75 +250,61 @@ onMounted(() => {
|
|||||||
dict.neHostAuthMode = resArr[0].value;
|
dict.neHostAuthMode = resArr[0].value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 状态还原
|
|
||||||
const state = stepState.states[stepState.current];
|
|
||||||
if (state) {
|
|
||||||
if (state.info) {
|
|
||||||
const info = toRaw(state.info);
|
|
||||||
Object.assign(checkState.info, info);
|
|
||||||
}
|
|
||||||
if (state.from) {
|
|
||||||
const from = toRaw(state.from);
|
|
||||||
Object.assign(checkState.from, from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-descriptions :column="{ lg: 3, md: 2, sm: 2, xs: 1 }" bordered>
|
<a-descriptions :column="{ lg: 3, md: 2, sm: 2, xs: 1 }" bordered>
|
||||||
<a-descriptions-item label="服务器IP" :span="3">
|
<a-descriptions-item :label="t('views.ne.neQuickSetup.addr')" :span="3">
|
||||||
{{ checkState.info.addr }}
|
{{ state.info.addr }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="系统">
|
<a-descriptions-item :label="t('views.ne.neQuickSetup.kernelName')">
|
||||||
{{ checkState.info.kernelName }}
|
{{ state.info.kernelName }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="架构">
|
<a-descriptions-item :label="t('views.ne.neQuickSetup.machine')">
|
||||||
{{ checkState.info.machine }}
|
{{ state.info.machine }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="内核">
|
<a-descriptions-item :label="t('views.ne.neQuickSetup.kernelRelease')">
|
||||||
{{ checkState.info.kernelRelease }}
|
{{ state.info.kernelRelease }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item>
|
<a-descriptions-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
平台
|
{{ t('views.ne.neQuickSetup.prettyName') }}
|
||||||
<a-tooltip placement="topLeft">
|
<a-tooltip placement="topLeft">
|
||||||
<template #title> 支持 Ubuntu、Ubuntu </template>
|
<template #title>
|
||||||
|
{{ t('views.ne.neQuickSetup.prettyNameTip') }}
|
||||||
|
</template>
|
||||||
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
<InfoCircleOutlined style="color: rgba(0, 0, 0, 0.45)" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</template>
|
</template>
|
||||||
{{ checkState.info.prettyName }}
|
{{ state.info.prettyName }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="主机名">
|
<a-descriptions-item :label="t('views.ne.neQuickSetup.nodename')">
|
||||||
{{ checkState.info.nodename }}
|
{{ state.info.nodename }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="授予权限">
|
<a-descriptions-item :label="t('views.ne.neQuickSetup.auth')">
|
||||||
<a-tag :color="checkState.info.sudo ? 'success' : 'error'">
|
<a-tag :color="state.info.sudo ? 'success' : 'error'">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<CheckCircleOutlined v-if="checkState.info.sudo" />
|
<CheckCircleOutlined v-if="state.info.sudo" />
|
||||||
<CloseCircleOutlined v-else />
|
<CloseCircleOutlined v-else />
|
||||||
</template>
|
</template>
|
||||||
可提权
|
{{ t('views.ne.neQuickSetup.sudo') }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
|
|
||||||
<a-tag
|
<a-tag :color="state.info.sshLink ? 'success' : 'error'">
|
||||||
:color="checkState.info.sshLink ? 'success' : 'error'"
|
|
||||||
style="cursor: pointer"
|
|
||||||
@click="fnSSHLink()"
|
|
||||||
>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<CheckCircleOutlined v-if="checkState.info.sshLink" />
|
<CheckCircleOutlined v-if="state.info.sshLink" />
|
||||||
<CloseCircleOutlined v-else />
|
<CloseCircleOutlined v-else />
|
||||||
</template>
|
</template>
|
||||||
可免密直连
|
{{ t('views.ne.neQuickSetup.sshLink') }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="连接检查" :span="2">
|
<a-descriptions-item :span="2">
|
||||||
<a-form
|
<a-form
|
||||||
name="checkStateFrom"
|
name="checkStateFrom"
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
:label-col="{ span: 6 }"
|
:label-col="{ span: 6 }"
|
||||||
:label-wrap="true"
|
:label-wrap="false"
|
||||||
>
|
>
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
@@ -289,7 +314,7 @@ onMounted(() => {
|
|||||||
v-bind="checkStateFrom.validateInfos.addr"
|
v-bind="checkStateFrom.validateInfos.addr"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
v-model:value="checkState.from.addr"
|
v-model:value="state.from.addr"
|
||||||
allow-clear
|
allow-clear
|
||||||
:maxlength="128"
|
:maxlength="128"
|
||||||
:placeholder="t('common.inputPlease')"
|
:placeholder="t('common.inputPlease')"
|
||||||
@@ -304,10 +329,11 @@ onMounted(() => {
|
|||||||
v-bind="checkStateFrom.validateInfos.port"
|
v-bind="checkStateFrom.validateInfos.port"
|
||||||
>
|
>
|
||||||
<a-input-number
|
<a-input-number
|
||||||
v-model:value="checkState.from.port"
|
v-model:value="state.from.port"
|
||||||
:min="10"
|
:min="10"
|
||||||
:max="65535"
|
:max="65535"
|
||||||
:step="1"
|
:step="1"
|
||||||
|
:maxlength="5"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
></a-input-number>
|
></a-input-number>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -322,9 +348,9 @@ onMounted(() => {
|
|||||||
v-bind="checkStateFrom.validateInfos.user"
|
v-bind="checkStateFrom.validateInfos.user"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
v-model:value="checkState.from.user"
|
v-model:value="state.from.user"
|
||||||
allow-clear
|
allow-clear
|
||||||
:maxlength="50"
|
:maxlength="32"
|
||||||
:placeholder="t('common.inputPlease')"
|
:placeholder="t('common.inputPlease')"
|
||||||
>
|
>
|
||||||
</a-input>
|
</a-input>
|
||||||
@@ -333,7 +359,7 @@ onMounted(() => {
|
|||||||
<a-col :lg="12" :md="12" :xs="24">
|
<a-col :lg="12" :md="12" :xs="24">
|
||||||
<a-form-item :label="t('views.ne.neHost.authMode')">
|
<a-form-item :label="t('views.ne.neHost.authMode')">
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="checkState.from.authMode"
|
v-model:value="state.from.authMode"
|
||||||
default-value="0"
|
default-value="0"
|
||||||
:options="dict.neHostAuthMode"
|
:options="dict.neHostAuthMode"
|
||||||
>
|
>
|
||||||
@@ -343,7 +369,7 @@ onMounted(() => {
|
|||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
<a-form-item
|
<a-form-item
|
||||||
v-if="checkState.from.authMode === '0'"
|
v-if="state.from.authMode === '0'"
|
||||||
:label="t('views.ne.neHost.password')"
|
:label="t('views.ne.neHost.password')"
|
||||||
:label-col="{ span: 3 }"
|
:label-col="{ span: 3 }"
|
||||||
:label-wrap="true"
|
:label-wrap="true"
|
||||||
@@ -351,14 +377,14 @@ onMounted(() => {
|
|||||||
v-bind="checkStateFrom.validateInfos.password"
|
v-bind="checkStateFrom.validateInfos.password"
|
||||||
>
|
>
|
||||||
<a-input-password
|
<a-input-password
|
||||||
v-model:value="checkState.from.password"
|
v-model:value="state.from.password"
|
||||||
:maxlength="128"
|
:maxlength="128"
|
||||||
:placeholder="t('common.inputPlease')"
|
:placeholder="t('common.inputPlease')"
|
||||||
>
|
>
|
||||||
</a-input-password>
|
</a-input-password>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<template v-if="checkState.from.authMode === '1'">
|
<template v-if="state.from.authMode === '1'">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="t('views.ne.neHost.privateKey')"
|
:label="t('views.ne.neHost.privateKey')"
|
||||||
:label-col="{ span: 3 }"
|
:label-col="{ span: 3 }"
|
||||||
@@ -367,7 +393,7 @@ onMounted(() => {
|
|||||||
v-bind="checkStateFrom.validateInfos.privateKey"
|
v-bind="checkStateFrom.validateInfos.privateKey"
|
||||||
>
|
>
|
||||||
<a-textarea
|
<a-textarea
|
||||||
v-model:value="checkState.from.privateKey"
|
v-model:value="state.from.privateKey"
|
||||||
:auto-size="{ minRows: 4, maxRows: 6 }"
|
:auto-size="{ minRows: 4, maxRows: 6 }"
|
||||||
:maxlength="3000"
|
:maxlength="3000"
|
||||||
:show-count="true"
|
:show-count="true"
|
||||||
@@ -381,7 +407,7 @@ onMounted(() => {
|
|||||||
:label-wrap="true"
|
:label-wrap="true"
|
||||||
>
|
>
|
||||||
<a-input-password
|
<a-input-password
|
||||||
v-model:value="checkState.from.passPhrase"
|
v-model:value="state.from.passPhrase"
|
||||||
:maxlength="128"
|
:maxlength="128"
|
||||||
:placeholder="t('common.inputPlease')"
|
:placeholder="t('common.inputPlease')"
|
||||||
>
|
>
|
||||||
@@ -389,18 +415,42 @@ onMounted(() => {
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<a-form-item :wrapper-col="{ span: 8, offset: 3 }">
|
<a-form-item :wrapper-col="{ span: 10, offset: 3 }">
|
||||||
<a-button
|
<a-space direction="horizontal" :size="18">
|
||||||
type="primary"
|
<a-button
|
||||||
html-type="submit"
|
type="primary"
|
||||||
@click="fnCheckInfo()"
|
ghost
|
||||||
:loading="checkState.confirmLoading"
|
html-type="submit"
|
||||||
>
|
@click="fnCheckInfo()"
|
||||||
进行连接
|
:loading="state.confirmLoading"
|
||||||
</a-button>
|
>
|
||||||
<a-button style="margin-left: 12px" @click="fnCheckInfoReset()">
|
{{ t('views.ne.neHost.test') }}
|
||||||
重置
|
</a-button>
|
||||||
</a-button>
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
@click="fnStepNext()"
|
||||||
|
:disabled="!state.stepNext"
|
||||||
|
>
|
||||||
|
{{ t('views.ne.neQuickSetup.stepNext') }}
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
type="dashed"
|
||||||
|
@click="fnHostAuthorized()"
|
||||||
|
:disabled="state.confirmLoading"
|
||||||
|
v-if="state.from.authMode !== '2'"
|
||||||
|
>
|
||||||
|
{{ t('views.ne.neHost.authRSA') }}
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
@click="fnCheckInfoReset()"
|
||||||
|
:disabled="state.confirmLoading"
|
||||||
|
>
|
||||||
|
{{ t('common.reset') }}
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import { reactive } from 'vue';
|
||||||
|
|
||||||
|
/**步骤信息状态类型 */
|
||||||
|
type StepStateType = {
|
||||||
|
/**步骤名称 */
|
||||||
|
stepName: string;
|
||||||
|
/**安装网元步骤信息 */
|
||||||
|
steps: any[];
|
||||||
|
/**安装网元步骤当前选中 */
|
||||||
|
current: number;
|
||||||
|
/**连接主机 */
|
||||||
|
neHost: Record<string, any>;
|
||||||
|
/**网元信息 */
|
||||||
|
neInfo: Record<string, any>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**步骤信息状态 */
|
||||||
|
export const stepState: StepStateType = reactive({
|
||||||
|
stepName: 'Start',
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
title: '服务器环境',
|
||||||
|
description: '服务端与网元服务',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '配置网元信息',
|
||||||
|
description: '网元信息设置',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '网元软件安装',
|
||||||
|
description: '软件安装到服务端',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '网元授权激活',
|
||||||
|
description: '网元服务授权激活',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
current: 0,
|
||||||
|
neHost: {},
|
||||||
|
neInfo: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**步骤信息状态复位 */
|
||||||
|
export function fnRestStepState(t?: any) {
|
||||||
|
stepState.stepName = 'Start';
|
||||||
|
stepState.current = 0;
|
||||||
|
stepState.neHost = {};
|
||||||
|
stepState.neInfo = {};
|
||||||
|
// 多语言翻译
|
||||||
|
if (t) {
|
||||||
|
stepState.steps = [
|
||||||
|
{
|
||||||
|
title: t('views.ne.neQuickSetup.startTitle'),
|
||||||
|
description: t('views.ne.neQuickSetup.startDesc'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.neQuickSetup.configTitle'),
|
||||||
|
description: t('views.ne.neQuickSetup.configDesc'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.neQuickSetup.installTitle'),
|
||||||
|
description: t('views.ne.neQuickSetup.installDesc'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: t('views.ne.neQuickSetup.licenseTitle'),
|
||||||
|
description: t('views.ne.neQuickSetup.licenseDesc'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**跳转步骤组件 */
|
||||||
|
export function fnToStepName(stepName: string) {
|
||||||
|
stepState.current = [
|
||||||
|
'Start',
|
||||||
|
'NeInfoConfig',
|
||||||
|
'NeInfoSoftwareInstall',
|
||||||
|
'NeInfoSoftwareLicense',
|
||||||
|
].indexOf(stepName);
|
||||||
|
|
||||||
|
stepState.stepName = stepName;
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
|
import { defineAsyncComponent, watch, shallowRef, onMounted } from 'vue';
|
||||||
|
import { stepState, fnRestStepState } from './hooks/useStep';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
// 异步加载组件
|
||||||
|
const Start = defineAsyncComponent(() => import('./components/Start.vue'));
|
||||||
|
|
||||||
|
// 当前组件
|
||||||
|
const currentComponent = shallowRef(Start);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => stepState.stepName,
|
||||||
|
v => {
|
||||||
|
const loadComponent = defineAsyncComponent(
|
||||||
|
() => import(`./components/${v}.vue`)
|
||||||
|
);
|
||||||
|
currentComponent.value = loadComponent;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fnRestStepState(t);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PageContainer>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<!-- 插槽-卡片左侧 -->
|
||||||
|
<template #title>
|
||||||
|
<!-- 步骤进度 -->
|
||||||
|
<a-steps :current="stepState.current" direction="horizontal">
|
||||||
|
<a-step
|
||||||
|
v-for="s in stepState.steps"
|
||||||
|
:key="s.title"
|
||||||
|
:title="s.title"
|
||||||
|
:description="s.description"
|
||||||
|
:disabled="true"
|
||||||
|
/>
|
||||||
|
</a-steps>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 步骤页面 -->
|
||||||
|
<component :is="currentComponent" />
|
||||||
|
</a-card>
|
||||||
|
</PageContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
@@ -0,0 +1,470 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, toRaw, watch } from 'vue';
|
||||||
|
import { message, Form, Upload, notification } from 'ant-design-vue/lib';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { NE_EXPAND_LIST, NE_TYPE_LIST } from '@/constants/ne-constants';
|
||||||
|
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||||
|
import {
|
||||||
|
addNeSoftware,
|
||||||
|
getNeSoftware,
|
||||||
|
updateNeSoftware,
|
||||||
|
} from '@/api/ne/neSoftware';
|
||||||
|
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||||
|
import { uploadFileChunk } from '@/api/tool/file';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
|
||||||
|
const props = defineProps({
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
editId: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
visibleByEdit: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: {
|
||||||
|
id: string;
|
||||||
|
neType: string;
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
version: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
/**上传文件 */
|
||||||
|
uploadFiles: any[];
|
||||||
|
/**上传文件-依赖包 */
|
||||||
|
uploadFilesDep: any[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
visibleByEdit: false,
|
||||||
|
title: '软件包文件',
|
||||||
|
from: {
|
||||||
|
id: '',
|
||||||
|
neType: '',
|
||||||
|
name: '',
|
||||||
|
path: '',
|
||||||
|
version: '',
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
confirmLoading: false,
|
||||||
|
uploadFiles: [],
|
||||||
|
uploadFilesDep: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**对话框内表单属性和校验规则 */
|
||||||
|
const modalStateFrom = Form.useForm(
|
||||||
|
modalState.from,
|
||||||
|
reactive({
|
||||||
|
neType: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
min: 1,
|
||||||
|
max: 32,
|
||||||
|
message: t('views.ne.common.neTypePlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
version: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
min: 1,
|
||||||
|
max: 64,
|
||||||
|
message: t('views.ne.neSoftware.versionPlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
path: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('views.ne.neSoftware.pathPlease'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalOk() {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
modalStateFrom
|
||||||
|
.validate()
|
||||||
|
.then(e => {
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
|
||||||
|
// 安装带依赖包
|
||||||
|
if (modalState.uploadFilesDep.length > 0) {
|
||||||
|
const depFiles = [];
|
||||||
|
for (const depFile of modalState.uploadFilesDep) {
|
||||||
|
if (depFile.status === 'done' && depFile.path) {
|
||||||
|
depFiles.push(depFile.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
depFiles.push(from.path);
|
||||||
|
from.path = depFiles.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
const software = from.id ? updateNeSoftware(from) : addNeSoftware(from);
|
||||||
|
software.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
message.success({
|
||||||
|
content: t('common.operateOk'),
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
// 返回无引用信息
|
||||||
|
emit('ok', JSON.parse(JSON.stringify(from)));
|
||||||
|
fnModalCancel();
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.visibleByEdit = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalStateFrom.resetFields();
|
||||||
|
modalState.uploadFiles = [];
|
||||||
|
modalState.uploadFilesDep = [];
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:visible', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩 */
|
||||||
|
function fnBeforeUploadFile(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
const fileName = file.name;
|
||||||
|
const suff = fileName.substring(fileName.lastIndexOf('.'));
|
||||||
|
if (!['.deb', '.rpm'].includes(suff)) {
|
||||||
|
message.error(
|
||||||
|
t('views.configManage.softwareManage.onlyAble', {
|
||||||
|
fileText: '(.deb、.rpm)',
|
||||||
|
}),
|
||||||
|
3
|
||||||
|
);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取网元类型判断是否支持
|
||||||
|
let neType = '';
|
||||||
|
const neTypeIndex = fileName.indexOf('-');
|
||||||
|
if (neTypeIndex !== -1) {
|
||||||
|
neType = fileName.substring(0, neTypeIndex).toUpperCase();
|
||||||
|
}
|
||||||
|
// 主包类型
|
||||||
|
if (!NE_TYPE_LIST.includes(neType)) {
|
||||||
|
notification.warning({
|
||||||
|
message: fileName,
|
||||||
|
description: t('views.ne.neSoftware.fileCheckType'),
|
||||||
|
});
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
modalState.from.neType = neType;
|
||||||
|
|
||||||
|
// 根据给定的软件名取版本号 ims-r2.2312.x-ub22.deb
|
||||||
|
const matches = fileName.match(/([0-9.]+[0-9x]+)/);
|
||||||
|
if (matches) {
|
||||||
|
modalState.from.version = matches[0];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件 */
|
||||||
|
function fnUploadFile(up: UploadRequestOption) {
|
||||||
|
const uploadFile = modalState.uploadFiles.find(
|
||||||
|
item => item.uid === (up.file as any).uid
|
||||||
|
);
|
||||||
|
if (!uploadFile) return;
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
uploadFileChunk(up.file as File, 5, 'software')
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// 改为完成状态
|
||||||
|
uploadFile.percent = 100;
|
||||||
|
uploadFile.status = 'done';
|
||||||
|
uploadFile.path = res.data.fileName;
|
||||||
|
// 预置到表单
|
||||||
|
const { fileName, originalFileName } = res.data;
|
||||||
|
modalState.from.name = originalFileName;
|
||||||
|
modalState.from.path = fileName;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
uploadFile.percent = 0;
|
||||||
|
uploadFile.status = 'error';
|
||||||
|
uploadFile.response = error.message;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩-依赖包 */
|
||||||
|
function fnBeforeUploadFileDep(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
const fileName = file.name;
|
||||||
|
const suff = fileName.substring(fileName.lastIndexOf('.'));
|
||||||
|
if (!['.deb', '.rpm'].includes(suff)) {
|
||||||
|
message.error(
|
||||||
|
t('views.configManage.softwareManage.onlyAble', {
|
||||||
|
fileText: '(.deb、.rpm)',
|
||||||
|
}),
|
||||||
|
3
|
||||||
|
);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已存在同名文件
|
||||||
|
const hasItem = modalState.uploadFilesDep.find(
|
||||||
|
item => item.name === fileName
|
||||||
|
);
|
||||||
|
if (hasItem) {
|
||||||
|
notification.warning({
|
||||||
|
message: fileName,
|
||||||
|
description: t('views.ne.neSoftware.fileNameExists'),
|
||||||
|
});
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取网元类型判断是否支持
|
||||||
|
let neType = '';
|
||||||
|
const neTypeIndex = fileName.indexOf('-');
|
||||||
|
if (neTypeIndex !== -1) {
|
||||||
|
neType = fileName.substring(0, neTypeIndex).toUpperCase();
|
||||||
|
}
|
||||||
|
// 依赖包类型
|
||||||
|
if (!NE_EXPAND_LIST.includes(neType)) {
|
||||||
|
notification.warning({
|
||||||
|
message: fileName,
|
||||||
|
description: t('views.ne.neSoftware.fileCheckTypeDep'),
|
||||||
|
});
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件-依赖包 */
|
||||||
|
function fnUploadFileDep(up: UploadRequestOption) {
|
||||||
|
const uploadFile = modalState.uploadFilesDep.find(
|
||||||
|
item => item.uid === (up.file as any).uid
|
||||||
|
);
|
||||||
|
if (!uploadFile) return;
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
uploadFileChunk(up.file as File, 5, 'software')
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// 改为完成状态
|
||||||
|
uploadFile.percent = 100;
|
||||||
|
uploadFile.status = 'done';
|
||||||
|
uploadFile.path = res.data.fileName;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
uploadFile.percent = 0;
|
||||||
|
uploadFile.status = 'error';
|
||||||
|
uploadFile.response = error.message;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出显示为 新增或者修改
|
||||||
|
* @param id id
|
||||||
|
*/
|
||||||
|
function fnModalVisibleByEdit(id?: string) {
|
||||||
|
if (id) {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
getNeSoftware(id)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
Object.assign(modalState.from, res.data);
|
||||||
|
modalState.title = t('views.ne.neSoftware.uploadTitle');
|
||||||
|
modalState.visibleByEdit = true;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
modalState.title = t('views.ne.neSoftware.uploadTitle');
|
||||||
|
modalState.visibleByEdit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
val => {
|
||||||
|
if (val) fnModalVisibleByEdit(props.editId);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
width="550px"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:visible="modalState.visibleByEdit"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:wrapper-col="{ span: 16 }"
|
||||||
|
:label-col="{ span: 8 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<template v-if="modalState.from.id === ''">
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neSoftware.path')"
|
||||||
|
:help="t('views.ne.neSoftware.uploadFileName')"
|
||||||
|
name="file"
|
||||||
|
v-bind="modalStateFrom.validateInfos.path"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFiles"
|
||||||
|
accept=".rpm,.deb"
|
||||||
|
list-type="text"
|
||||||
|
:max-count="1"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: false,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
:before-upload="fnBeforeUploadFile"
|
||||||
|
:custom-request="fnUploadFile"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neSoftware.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
name="dep"
|
||||||
|
:label="t('views.ne.neSoftware.dependFile')"
|
||||||
|
:help="t('views.ne.neSoftware.dependFileTip')"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFilesDep"
|
||||||
|
accept=".rpm,.deb"
|
||||||
|
list-type="text"
|
||||||
|
:multiple="true"
|
||||||
|
:max-count="5"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
:before-upload="fnBeforeUploadFileDep"
|
||||||
|
:custom-request="fnUploadFileDep"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="dashed">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neSoftware.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.common.neType')"
|
||||||
|
name="neType"
|
||||||
|
v-bind="modalStateFrom.validateInfos.neType"
|
||||||
|
>
|
||||||
|
<a-auto-complete
|
||||||
|
v-model:value="modalState.from.neType"
|
||||||
|
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
|
||||||
|
:disabled="modalState.from.id !== ''"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
:maxlength="32"
|
||||||
|
:disabled="modalState.from.id !== ''"
|
||||||
|
>
|
||||||
|
</a-input>
|
||||||
|
</a-auto-complete>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neSoftware.version')"
|
||||||
|
name="version"
|
||||||
|
v-bind="modalStateFrom.validateInfos.version"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model:value="modalState.from.version"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item :label="t('common.description')" name="description">
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="modalState.from.description"
|
||||||
|
:maxlength="500"
|
||||||
|
:show-count="true"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
@@ -0,0 +1,484 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, onMounted, toRaw, watch } from 'vue';
|
||||||
|
import { message, Upload, notification } from 'ant-design-vue/lib';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { NE_TYPE_LIST, NE_EXPAND_LIST } from '@/constants/ne-constants';
|
||||||
|
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||||
|
import { addNeSoftware } from '@/api/ne/neSoftware';
|
||||||
|
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||||
|
import { uploadFileChunk } from '@/api/tool/file';
|
||||||
|
const { t } = useI18n();
|
||||||
|
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
|
||||||
|
const props = defineProps({
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**网元类型,指定上传 */
|
||||||
|
neType: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**网元支持 */
|
||||||
|
const NE_TYPE_EXP = NE_EXPAND_LIST.concat(NE_TYPE_LIST);
|
||||||
|
|
||||||
|
/**对话框对象信息状态类型 */
|
||||||
|
type ModalStateType = {
|
||||||
|
/**新增框或修改框是否显示 */
|
||||||
|
visibleByMoreFile: boolean;
|
||||||
|
/**标题 */
|
||||||
|
title: string;
|
||||||
|
/**表单数据 */
|
||||||
|
from: {
|
||||||
|
neType: string;
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
version: string;
|
||||||
|
description: string;
|
||||||
|
}[];
|
||||||
|
/**确定按钮 loading */
|
||||||
|
confirmLoading: boolean;
|
||||||
|
/**上传文件 */
|
||||||
|
uploadFiles: any[];
|
||||||
|
/**上传文件-依赖包 */
|
||||||
|
uploadFilesDep: any[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**对话框对象信息状态 */
|
||||||
|
let modalState: ModalStateType = reactive({
|
||||||
|
visibleByMoreFile: false,
|
||||||
|
title: '软件包文件',
|
||||||
|
from: [],
|
||||||
|
confirmLoading: false,
|
||||||
|
uploadFiles: [],
|
||||||
|
uploadFilesDep: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出确认执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
async function fnModalOk() {
|
||||||
|
if (modalState.confirmLoading) return;
|
||||||
|
if (modalState.uploadFiles.length < 1) {
|
||||||
|
message.warning({
|
||||||
|
content: t('views.ne.neSoftware.uploadNotFile'),
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 处理上传文件过滤
|
||||||
|
const uploadFiles = toRaw(modalState.uploadFiles);
|
||||||
|
const from = toRaw(modalState.from);
|
||||||
|
const expandFile: Record<string, string> = {};
|
||||||
|
for (const item of uploadFiles) {
|
||||||
|
if (item.status !== 'done' || !item.path) continue;
|
||||||
|
const neSoftware = from.find(s => s.name === item.name);
|
||||||
|
if (neSoftware && NE_TYPE_LIST.includes(neSoftware.neType)) {
|
||||||
|
neSoftware.path = item.path;
|
||||||
|
}
|
||||||
|
if (neSoftware && NE_EXPAND_LIST.includes(neSoftware.neType)) {
|
||||||
|
expandFile[neSoftware.neType] = item.path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMS拼接拓展包
|
||||||
|
const ims = from.find(s => s.neType === 'IMS');
|
||||||
|
if (ims) {
|
||||||
|
const pkgArr = [];
|
||||||
|
if (expandFile['ADB']) {
|
||||||
|
pkgArr.push(expandFile['ADB']);
|
||||||
|
}
|
||||||
|
if (expandFile['RTPROXY']) {
|
||||||
|
pkgArr.push(expandFile['RTPROXY']);
|
||||||
|
}
|
||||||
|
if (expandFile['MF']) {
|
||||||
|
pkgArr.push(expandFile['MF']);
|
||||||
|
}
|
||||||
|
pkgArr.push(ims.path);
|
||||||
|
ims.path = pkgArr.join(',');
|
||||||
|
}
|
||||||
|
// UDM拼接拓展包
|
||||||
|
const udm = from.find(s => s.neType === 'UDM');
|
||||||
|
if (udm && expandFile['ADB']) {
|
||||||
|
udm.path = [expandFile['ADB'], udm.path].join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安装带依赖包-指定网元时
|
||||||
|
if (props.neType && modalState.uploadFilesDep.length > 0) {
|
||||||
|
const neInfo = from.find(s => s.neType === props.neType);
|
||||||
|
if (neInfo) {
|
||||||
|
const depFiles = [];
|
||||||
|
for (const depFile of modalState.uploadFilesDep) {
|
||||||
|
if (depFile.status === 'done' && depFile.path) {
|
||||||
|
depFiles.push(depFile.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
depFiles.push(neInfo.path);
|
||||||
|
neInfo.path = depFiles.join(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始添加到软件包数据
|
||||||
|
const rows: any[] = [];
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
for (const item of from.filter(s => NE_TYPE_LIST.includes(s.neType))) {
|
||||||
|
try {
|
||||||
|
const res = await addNeSoftware(item);
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
rows.push(item);
|
||||||
|
} else {
|
||||||
|
message.error({
|
||||||
|
content: `${item.neType} ${res.msg}`,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('ok', rows);
|
||||||
|
fnModalCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话框弹出关闭执行函数
|
||||||
|
* 进行表达规则校验
|
||||||
|
*/
|
||||||
|
function fnModalCancel() {
|
||||||
|
modalState.visibleByMoreFile = false;
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
modalState.from = [];
|
||||||
|
modalState.uploadFiles = [];
|
||||||
|
modalState.uploadFilesDep = [];
|
||||||
|
emit('cancel');
|
||||||
|
emit('update:visible', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩 */
|
||||||
|
function fnBeforeUploadFile(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
const fileName = file.name;
|
||||||
|
const suff = fileName.substring(fileName.lastIndexOf('.'));
|
||||||
|
if (!['.deb', '.rpm'].includes(suff)) {
|
||||||
|
message.error(
|
||||||
|
t('views.configManage.softwareManage.onlyAble', {
|
||||||
|
fileText: '(.deb、.rpm)',
|
||||||
|
}),
|
||||||
|
3
|
||||||
|
);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取网元类型判断是否支持
|
||||||
|
let neType = '';
|
||||||
|
const neTypeIndex = fileName.indexOf('-');
|
||||||
|
if (neTypeIndex !== -1) {
|
||||||
|
neType = fileName.substring(0, neTypeIndex).toUpperCase();
|
||||||
|
}
|
||||||
|
if (!NE_TYPE_EXP.includes(neType)) {
|
||||||
|
notification.warning({
|
||||||
|
message: fileName,
|
||||||
|
description: t('views.ne.neSoftware.fileCheckType'),
|
||||||
|
});
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
// 根据给定的软件名取版本号 amf-r2.2404.xx-ub22.deb
|
||||||
|
let version = '';
|
||||||
|
const matches = fileName.match(/([0-9.]+[0-9x]+)/);
|
||||||
|
if (matches) {
|
||||||
|
version = matches[0];
|
||||||
|
} else {
|
||||||
|
notification.warning({
|
||||||
|
message: fileName,
|
||||||
|
description: t('views.ne.neSoftware.fileCheckVer'),
|
||||||
|
});
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单网元上传
|
||||||
|
if (props.neType && props.neType !== neType) {
|
||||||
|
notification.warning({
|
||||||
|
message: fileName,
|
||||||
|
description: t('views.ne.neSoftware.fileTypeNotEq', {
|
||||||
|
txt: props.neType,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
} else {
|
||||||
|
// 多文件上传时检查是否有同类型网元包
|
||||||
|
const hasItem = modalState.from.find(item => item.neType === neType);
|
||||||
|
if (hasItem) {
|
||||||
|
notification.warning({
|
||||||
|
message: fileName,
|
||||||
|
description: t('views.ne.neSoftware.fileTypeExists'),
|
||||||
|
});
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modalState.from.push({
|
||||||
|
name: fileName,
|
||||||
|
neType: neType,
|
||||||
|
version: version,
|
||||||
|
path: '', // 上传完成后提交注入
|
||||||
|
description: '',
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件 */
|
||||||
|
function fnUploadFile(up: UploadRequestOption) {
|
||||||
|
const uploadFile = modalState.uploadFiles.find(
|
||||||
|
item => item.uid === (up.file as any).uid
|
||||||
|
);
|
||||||
|
if (!uploadFile) return;
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
uploadFileChunk(up.file as File, 5, 'software')
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// 改为完成状态
|
||||||
|
uploadFile.percent = 100;
|
||||||
|
uploadFile.status = 'done';
|
||||||
|
uploadFile.path = res.data.fileName;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
uploadFile.percent = 0;
|
||||||
|
uploadFile.status = 'error';
|
||||||
|
uploadFile.response = error.message;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传前检查或转换压缩-依赖包 */
|
||||||
|
function fnBeforeUploadFileDep(file: FileType) {
|
||||||
|
if (modalState.confirmLoading) return false;
|
||||||
|
const fileName = file.name;
|
||||||
|
const suff = fileName.substring(fileName.lastIndexOf('.'));
|
||||||
|
if (!['.deb', '.rpm'].includes(suff)) {
|
||||||
|
message.error(
|
||||||
|
t('views.configManage.softwareManage.onlyAble', {
|
||||||
|
fileText: '(.deb、.rpm)',
|
||||||
|
}),
|
||||||
|
3
|
||||||
|
);
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已存在同名文件
|
||||||
|
const hasItem = modalState.uploadFilesDep.find(
|
||||||
|
item => item.name === fileName
|
||||||
|
);
|
||||||
|
if (hasItem) {
|
||||||
|
notification.warning({
|
||||||
|
message: fileName,
|
||||||
|
description: t('views.ne.neSoftware.fileNameExists'),
|
||||||
|
});
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取网元类型判断是否支持
|
||||||
|
let neType = '';
|
||||||
|
const neTypeIndex = fileName.indexOf('-');
|
||||||
|
if (neTypeIndex !== -1) {
|
||||||
|
neType = fileName.substring(0, neTypeIndex).toUpperCase();
|
||||||
|
}
|
||||||
|
// 依赖包类型
|
||||||
|
if (!NE_EXPAND_LIST.includes(neType)) {
|
||||||
|
notification.warning({
|
||||||
|
message: fileName,
|
||||||
|
description: t('views.ne.neSoftware.fileCheckTypeDep'),
|
||||||
|
});
|
||||||
|
return Upload.LIST_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**表单上传文件-依赖包 */
|
||||||
|
function fnUploadFileDep(up: UploadRequestOption) {
|
||||||
|
const uploadFile = modalState.uploadFilesDep.find(
|
||||||
|
item => item.uid === (up.file as any).uid
|
||||||
|
);
|
||||||
|
if (!uploadFile) return;
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
uploadFileChunk(up.file as File, 5, 'software')
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === RESULT_CODE_SUCCESS) {
|
||||||
|
// 改为完成状态
|
||||||
|
uploadFile.percent = 100;
|
||||||
|
uploadFile.status = 'done';
|
||||||
|
uploadFile.path = res.data.fileName;
|
||||||
|
} else {
|
||||||
|
message.error(res.msg, 3);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
uploadFile.percent = 0;
|
||||||
|
uploadFile.status = 'error';
|
||||||
|
uploadFile.response = error.message;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**监听是否显示,初始数据 */
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
modalState.title = t('views.ne.neSoftware.uploadBatch');
|
||||||
|
modalState.visibleByMoreFile = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
width="800px"
|
||||||
|
:keyboard="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:visible="modalState.visibleByMoreFile"
|
||||||
|
:title="modalState.title"
|
||||||
|
:confirm-loading="modalState.confirmLoading"
|
||||||
|
@ok="fnModalOk"
|
||||||
|
@cancel="fnModalCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
name="modalStateFrom"
|
||||||
|
layout="horizontal"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:labelWrap="true"
|
||||||
|
>
|
||||||
|
<template v-if="props.neType">
|
||||||
|
<a-form-item :label="t('views.ne.common.neType')" name="type">
|
||||||
|
<a-tag color="processing">
|
||||||
|
{{ props.neType }}
|
||||||
|
</a-tag>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neSoftware.path')"
|
||||||
|
:help="t('views.ne.neSoftware.uploadFileName')"
|
||||||
|
:required="true"
|
||||||
|
:validate-on-rule-change="false"
|
||||||
|
:validateTrigger="[]"
|
||||||
|
name="file"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFiles"
|
||||||
|
accept=".rpm,.deb"
|
||||||
|
list-type="text"
|
||||||
|
:max-count="1"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: false,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
:before-upload="fnBeforeUploadFile"
|
||||||
|
:custom-request="fnUploadFile"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neSoftware.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item
|
||||||
|
name="dep"
|
||||||
|
:label="t('views.ne.neSoftware.dependFile')"
|
||||||
|
:help="t('views.ne.neSoftware.dependFileTip')"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFilesDep"
|
||||||
|
accept=".rpm,.deb"
|
||||||
|
list-type="text"
|
||||||
|
:multiple="true"
|
||||||
|
:max-count="5"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
:before-upload="fnBeforeUploadFileDep"
|
||||||
|
:custom-request="fnUploadFileDep"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="dashed">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neSoftware.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<a-form-item :label="t('common.description')">
|
||||||
|
{{
|
||||||
|
t('views.ne.neSoftware.uploadBatchMax', {
|
||||||
|
txt: NE_TYPE_EXP.length,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
<br />
|
||||||
|
{{ t('views.ne.neSoftware.uploadFileName') }}
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('views.ne.neSoftware.path')"
|
||||||
|
:required="true"
|
||||||
|
:validate-on-rule-change="false"
|
||||||
|
:validateTrigger="[]"
|
||||||
|
name="file"
|
||||||
|
>
|
||||||
|
<a-upload
|
||||||
|
name="file"
|
||||||
|
v-model:file-list="modalState.uploadFiles"
|
||||||
|
accept=".rpm,.deb"
|
||||||
|
list-type="text"
|
||||||
|
:multiple="true"
|
||||||
|
:max-count="NE_TYPE_EXP.length"
|
||||||
|
:show-upload-list="{
|
||||||
|
showPreviewIcon: false,
|
||||||
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: false,
|
||||||
|
}"
|
||||||
|
:before-upload="fnBeforeUploadFile"
|
||||||
|
:custom-request="fnUploadFile"
|
||||||
|
:disabled="modalState.confirmLoading"
|
||||||
|
>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<UploadOutlined />
|
||||||
|
</template>
|
||||||
|
{{ t('views.ne.neSoftware.upload') }}
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
||||||
Loaded 100 of 144 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user