Compare commits
79 Commits
2.231130.9
...
2.231214.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5124c0c04a | ||
|
|
d56c293ef5 | ||
|
|
e90bc539e9 | ||
|
|
7edcf1703e | ||
|
|
8ee0a4d191 | ||
|
|
bc1f897660 | ||
|
|
ba47d3a303 | ||
|
|
38e5e4a9e0 | ||
|
|
15d7d118c4 | ||
|
|
69d4348df7 | ||
|
|
fe81a2d924 | ||
|
|
cd53fab1f9 | ||
|
|
e6d62da386 | ||
|
|
752f8ccc70 | ||
|
|
3a0c85169e | ||
|
|
f845f3f4de | ||
|
|
63e3f352b2 | ||
|
|
d9ec9fd1e1 | ||
|
|
f198d2b9a2 | ||
|
|
1c3e6db4bc | ||
|
|
8199e16a17 | ||
|
|
0d736966dd | ||
|
|
fe5905ee35 | ||
|
|
9c27c32e26 | ||
|
|
4208ccc358 | ||
|
|
51a190771d | ||
|
|
3376d90b96 | ||
|
|
4105f4ef33 | ||
|
|
e6a4591fb6 | ||
|
|
fafe604323 | ||
|
|
f110d0e697 | ||
|
|
6210b87c84 | ||
|
|
5a761ece4e | ||
|
|
3fa2cffc82 | ||
|
|
e92004a69a | ||
|
|
a612d05429 | ||
|
|
c93dabc6cf | ||
|
|
5056de2c1a | ||
| 8725518450 | |||
| 596ee0bb8d | |||
|
|
d5f593647e | ||
| 37eb798c4a | |||
| 6536e8baba | |||
|
|
90a34302a8 | ||
| 84bbeda7fc | |||
| cbefc04ac9 | |||
|
|
7564d6c6ab | ||
|
|
36ac9d0a5f | ||
|
|
be6e91390e | ||
|
|
f9016492be | ||
|
|
dd8dc63eab | ||
|
|
6303aecb47 | ||
|
|
0216c253d8 | ||
| 1076663511 | |||
|
|
8495192b83 | ||
|
|
88840cf88e | ||
|
|
97e453d880 | ||
|
|
dfc4a849f6 | ||
|
|
20b6c5c10a | ||
|
|
ab2154003e | ||
|
|
b2b837623a | ||
|
|
fb45c3fc10 | ||
|
|
d64c0f9e5e | ||
|
|
27cc02e0d6 | ||
|
|
12643cac12 | ||
|
|
205e07af45 | ||
|
|
a1443ebb95 | ||
|
|
b6d22014ce | ||
|
|
9abeb7be97 | ||
|
|
96d6cfcfa2 | ||
| c16a1675f0 | |||
|
|
bddba89d1e | ||
|
|
eb49b4d29a | ||
|
|
9d0daca765 | ||
|
|
cc234ee081 | ||
|
|
e23438d910 | ||
|
|
4fccb85353 | ||
|
|
3a8f6964ae | ||
|
|
5f89732a61 |
@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network EMS"
|
||||
VITE_APP_CODE = "CN EMS"
|
||||
|
||||
# 应用版本
|
||||
VITE_APP_VERSION = "2.231128.8"
|
||||
VITE_APP_VERSION = "2.2312.9"
|
||||
|
||||
# 接口基础URL地址-不带/后缀
|
||||
VITE_API_BASE_URL = "/omc-api"
|
||||
|
||||
@@ -11,7 +11,7 @@ VITE_APP_NAME = "Core Network EMS"
|
||||
VITE_APP_CODE = "CN EMS"
|
||||
|
||||
# 应用版本
|
||||
VITE_APP_VERSION = "2.2311.8"
|
||||
VITE_APP_VERSION = "2.231211.9"
|
||||
|
||||
# 接口基础URL地址-不带/后缀
|
||||
VITE_API_BASE_URL = "/omc-api"
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
Jenkins: http://192.168.2.166:3185/
|
||||
Nginx: http://192.168.2.166:3188/#/index
|
||||
后端暴露端口: http://192.168.2.166:3186 \ http://192.168.2.166:3187
|
||||
|
||||
|
||||
新网管:192.168.5.13
|
||||
旧网管:192.168.5.14
|
||||
登录账户:manager/manager
|
||||
```
|
||||
|
||||
## 程序命令
|
||||
@@ -52,6 +57,6 @@ eyJhbGciOiJSUzI1NiIsImtpZCI6ImZFVUhIb1puLW04M1dfSUYyRU8zWlZueXBpNUh4T0hTRVlzU19j
|
||||
|
||||
```ssh
|
||||
sudo chmod 700 -/.ssh/
|
||||
sudochmod 700 /home/ubuntu #这个尤其容易忽视掉,我就是从这个坑里爬出来。有木有很高兴呀!
|
||||
3sudochmod 600 -/ssh/authorized keys
|
||||
sudo chmod 700 /home/mask/.ssh #这个尤其容易忽视掉,我就是从这个坑里爬出来。有木有很高兴呀!
|
||||
sudo chmod 600 ~/.ssh/authorized_keys
|
||||
```
|
||||
19
package.json
@@ -12,8 +12,8 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"antdv-pro-layout": "^3.2.6",
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"@antv/g6": "^5.0.0-beta.27",
|
||||
"@codemirror/lang-javascript": "^6.2.1",
|
||||
"@codemirror/merge": "^6.1.2",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
@@ -21,6 +21,7 @@
|
||||
"@vueuse/components": "^10.6.1",
|
||||
"@vueuse/core": "^10.6.1",
|
||||
"ant-design-vue": "^3.2.20",
|
||||
"antdv-pro-layout": "^3.2.6",
|
||||
"codemirror": "^6.0.1",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^5.4.2",
|
||||
@@ -29,24 +30,24 @@
|
||||
"js-cookie": "^3.0.5",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.7",
|
||||
"vue": "^3.3.6",
|
||||
"vue": "^3.3.10",
|
||||
"vue-codemirror": "^6.1.1",
|
||||
"vue-i18n": "^9.5.0",
|
||||
"vue-i18n": "^9.8.0",
|
||||
"vue-router": "^4.2.5",
|
||||
"vue3-smooth-dnd": "^0.0.6",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/file-saver": "^2.0.5",
|
||||
"@types/js-cookie": "^3.0.3",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@vitejs/plugin-vue": "^4.3.4",
|
||||
"@vitejs/plugin-vue": "^4.5.1",
|
||||
"less": "^4.2.0",
|
||||
"typescript": "^5.2.2",
|
||||
"unplugin-vue-components": "^0.25.2",
|
||||
"vite": "^4.5.0",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.0.5",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vue-tsc": "^1.8.19"
|
||||
"vue-tsc": "^1.8.25"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,25 +17,11 @@
|
||||
*
|
||||
*/
|
||||
(function () {
|
||||
// host = ip:prot
|
||||
const host = '192.168.2.166:3030';
|
||||
|
||||
const configs = {
|
||||
// internationalization 国际化禁用,默认语言选择
|
||||
i18nDisable: false,
|
||||
i18nDisableDefault: 'en_US',
|
||||
// Service Address 服务地址
|
||||
baseUrl: `http://${host}`,
|
||||
// websocket Address
|
||||
wsUrl: `ws://${host}`,
|
||||
};
|
||||
|
||||
if(!configs.i18nDisable){
|
||||
localStorage.setItem('cache:local:i18n', configs.i18nDisableDefault);
|
||||
}
|
||||
for (const key in configs) {
|
||||
console.log(key, `${configs[key]}`);
|
||||
sessionStorage.setItem(key, `${configs[key]}`);
|
||||
}
|
||||
// host = ip:port
|
||||
const host = '192.168.8.100:3030';
|
||||
|
||||
// Service Address 服务地址
|
||||
sessionStorage.setItem('baseUrl', `http://${host}`);
|
||||
// websocket Address
|
||||
sessionStorage.setItem('wsUrl', `ws://${host}`);
|
||||
})();
|
||||
|
||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 227 B |
@@ -155,15 +155,15 @@
|
||||
}
|
||||
</style>`;
|
||||
|
||||
// 根据浏览器选择语言
|
||||
const lang = localStorage.getItem('cache:local:i18n');
|
||||
if (!lang) {
|
||||
let preferredLanguage = navigator.language;
|
||||
if (preferredLanguage.indexOf('-')) {
|
||||
preferredLanguage = preferredLanguage.replace('-', '_');
|
||||
}
|
||||
localStorage.setItem('cache:local:i18n', preferredLanguage);
|
||||
}
|
||||
// 根据浏览器选择语言
|
||||
// if (!lang) {
|
||||
// let preferredLanguage = navigator.language;
|
||||
// if (preferredLanguage.indexOf('-')) {
|
||||
// preferredLanguage = preferredLanguage.replace('-', '_');
|
||||
// }
|
||||
// localStorage.setItem('cache:local:i18n', preferredLanguage);
|
||||
// }
|
||||
|
||||
let loadInfo = {
|
||||
title: '正在加载资源',
|
||||
|
||||
43
src/App.vue
@@ -92,4 +92,47 @@ body .ant-pro-basicLayout {
|
||||
.ant-table.ant-table-small .ant-table-thead > tr > th {
|
||||
padding: 6px !important;
|
||||
}
|
||||
|
||||
/** ==== 表格头按钮区域 S === **/
|
||||
/* 默认 */
|
||||
.button-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button-container > button {
|
||||
margin-right: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.button-container > button:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
/* 平板端 */
|
||||
@media (max-width: 992px) {
|
||||
.button-container {
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
align-items: left;
|
||||
}
|
||||
.button-container > button {
|
||||
margin-right: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
/* 手机端 */
|
||||
@media (max-width: 576px) {
|
||||
.button-container {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
align-items: left;
|
||||
}
|
||||
.button-container > button {
|
||||
margin-right: 0px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
/** ==== 表格头按钮区域 E === **/
|
||||
</style>
|
||||
|
||||
@@ -11,6 +11,24 @@ export async function listNeInfo(query: Record<string, any>) {
|
||||
let totalSQL = 'select count(*) as total from ne_info where status=0 ';
|
||||
let rowsSQL = 'select * from ne_info where status=0 ';
|
||||
|
||||
// 系统特定顺序
|
||||
const specificOrder = [
|
||||
'OMC',
|
||||
'MME',
|
||||
'AMF',
|
||||
'AUSF',
|
||||
'UDM',
|
||||
'SMF',
|
||||
'PCF',
|
||||
'UPF',
|
||||
'NRF',
|
||||
'NSSF',
|
||||
'IMS',
|
||||
'N3IWF',
|
||||
'NEF',
|
||||
'LMF',
|
||||
];
|
||||
|
||||
// 查询
|
||||
let querySQL = '';
|
||||
if (query.neType) {
|
||||
@@ -46,6 +64,14 @@ export async function listNeInfo(query: Record<string, any>) {
|
||||
data.total = itemData[0]['total'];
|
||||
} else {
|
||||
data.rows = itemData.map(v => parseObjLineToHump(v));
|
||||
//通过sort进行冒泡排序
|
||||
data.rows.sort((a: any, b: any) => {
|
||||
const typeA = specificOrder.indexOf(a.neType);
|
||||
const typeB = specificOrder.indexOf(b.neType);
|
||||
if (typeA === -1) return 1; // 如果不在特定顺序中,排到后面
|
||||
if (typeB === -1) return -1; // 如果不在特定顺序中,排到后面
|
||||
return typeA - typeB;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -115,6 +141,7 @@ export async function delNeInfo(data: Record<string, any>) {
|
||||
return request({
|
||||
url: `/api/rest/systemManagement/v1/elementType/${data.neType}/objectType/neInfo?ne_id=${data.neId}`,
|
||||
method: 'delete',
|
||||
timeout:60*1000,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -123,6 +150,23 @@ export async function delNeInfo(data: Record<string, any>) {
|
||||
* @returns object
|
||||
*/
|
||||
export async function getNelistAll() {
|
||||
// 系统特定顺序
|
||||
const specificOrder = [
|
||||
'OMC',
|
||||
'MME',
|
||||
'AMF',
|
||||
'AUSF',
|
||||
'UDM',
|
||||
'SMF',
|
||||
'PCF',
|
||||
'UPF',
|
||||
'NRF',
|
||||
'NSSF',
|
||||
'IMS',
|
||||
'N3IWF',
|
||||
'NEF',
|
||||
'LMF',
|
||||
];
|
||||
// 发起请求
|
||||
const result = await request({
|
||||
url: `/api/rest/databaseManagement/v1/elementType/omc_db/objectType/ne_info`,
|
||||
@@ -134,6 +178,14 @@ export async function getNelistAll() {
|
||||
// 解析数据
|
||||
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
|
||||
let data = result.data.data[0];
|
||||
//通过sort进行冒泡排序
|
||||
data['ne_info'].sort((a: any, b: any) => {
|
||||
const typeA = specificOrder.indexOf(a.ne_type);
|
||||
const typeB = specificOrder.indexOf(b.ne_type);
|
||||
if (typeA === -1) return 1;
|
||||
if (typeB === -1) return -1;
|
||||
return typeA - typeB;
|
||||
});
|
||||
return Object.assign(result, {
|
||||
data: parseObjLineToHump(data['ne_info']),
|
||||
});
|
||||
|
||||
@@ -169,7 +169,7 @@ export function showPass(data: Record<string, any>) {
|
||||
let querySQL = '';
|
||||
querySQL += data.alarm_code ? ` and alarm_code != ${data.alarm_code} ` : '';
|
||||
querySQL += data.alarm_type
|
||||
? ` and alarm_type !=\\' ${data.alarm_type} \\'`
|
||||
? ` and alarm_type !=\\'${data.alarm_type}\\'`
|
||||
: '';
|
||||
querySQL += data.pv_flag ? ` and pv_flag !=\\'${data.pv_flag} \\'` : '';
|
||||
querySQL += data.orig_severity
|
||||
|
||||
@@ -7,6 +7,23 @@ import { parseDateToStr } from '@/utils/date-utils';
|
||||
* @returns object
|
||||
*/
|
||||
export async function listMain() {
|
||||
// 系统特定顺序
|
||||
const specificOrder = [
|
||||
'OMC',
|
||||
'MME',
|
||||
'AMF',
|
||||
'AUSF',
|
||||
'UDM',
|
||||
'SMF',
|
||||
'PCF',
|
||||
'UPF',
|
||||
'NRF',
|
||||
'NSSF',
|
||||
'IMS',
|
||||
'N3IWF',
|
||||
'NEF',
|
||||
'LMF',
|
||||
];
|
||||
const result = await request({
|
||||
url: '/api/rest/systemManagement/v1/elementType/all/objectType/systemState',
|
||||
method: 'get',
|
||||
@@ -43,8 +60,16 @@ export async function listMain() {
|
||||
return mergedObj;
|
||||
});
|
||||
|
||||
// console.log(mergedData);
|
||||
// console.log(rowArr)
|
||||
//通过sort进行冒泡排序
|
||||
mergedData.sort((a: any, b: any) => {
|
||||
const typeA = specificOrder.indexOf(a.name.split('_')[0]);
|
||||
const typeB = specificOrder.indexOf(b.name.split('_')[0]);
|
||||
if (typeA === -1) return 1; // 如果不在特定顺序中,排到后面
|
||||
if (typeB === -1) return -1; // 如果不在特定顺序中,排到后面
|
||||
return typeA - typeB;
|
||||
});
|
||||
//console.log(mergedData);
|
||||
|
||||
return mergedData;
|
||||
}
|
||||
|
||||
@@ -77,15 +102,3 @@ export function getSysConf() {
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 转存帮助文档
|
||||
* @returns object
|
||||
*/
|
||||
export function transferHelpDoc(data: Record<string, any>) {
|
||||
return request({
|
||||
url: `/helpDoc`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@ import { request } from '@/plugins/http-fetch';
|
||||
import { parseObjLineToHump } from '@/utils/parse-utils';
|
||||
|
||||
/**
|
||||
* 签约规则导出
|
||||
* 规则导出
|
||||
* @param data 表单数据对象
|
||||
* @returns bolb
|
||||
*/
|
||||
export function exportRule(data: Record<string, any>) {
|
||||
return request({
|
||||
url: '/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/file/export',
|
||||
method: 'post',
|
||||
data: data,
|
||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/file/export`,
|
||||
method: 'get',
|
||||
params: data,
|
||||
responseType: 'blob',
|
||||
timeout: 180_000,
|
||||
});
|
||||
@@ -22,14 +22,13 @@ export function exportRule(data: Record<string, any>) {
|
||||
|
||||
/**
|
||||
* 导入规则数据
|
||||
* @param neId 网元ID
|
||||
* @param data 表单数据对象
|
||||
* @returns object
|
||||
*/
|
||||
export function importRuleData(data: Record<string, any>) {
|
||||
return request({
|
||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/file/import`,
|
||||
method: 'post',
|
||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/file/import?neId=${data.neId}&filePath=${data.filePath}&fileType=${data.fileType}`,
|
||||
method: 'put',
|
||||
data,
|
||||
timeout: 60_000,
|
||||
});
|
||||
@@ -52,28 +51,38 @@ export async function listRules(query: Record<string, any>) {
|
||||
code: result.code,
|
||||
msg: result.msg,
|
||||
};
|
||||
|
||||
// 解析数据
|
||||
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
|
||||
const rows = parseObjLineToHump(result.data.data);
|
||||
data.total = rows.length;
|
||||
data.rows = rows;
|
||||
if (result.code === RESULT_CODE_SUCCESS) {
|
||||
if (result.data?.status) {
|
||||
return {
|
||||
code: RESULT_CODE_ERROR,
|
||||
msg: result.data?.cause,
|
||||
rows: result.data,
|
||||
};
|
||||
}
|
||||
if (Array.isArray(result.data.data)) {
|
||||
const rows = parseObjLineToHump(result.data.data);
|
||||
data.total = rows.length;
|
||||
data.rows = rows;
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟数据
|
||||
// data.rows = [
|
||||
// {
|
||||
// msisdn: '12307550237',
|
||||
// pccRules: 'internet',
|
||||
// rfsp: 0,
|
||||
// sessRules: 'internet',
|
||||
// },
|
||||
// {
|
||||
// msisdn: '12307550238',
|
||||
// pccRules: 'internet|ims_sig',
|
||||
// rfsp: 0,
|
||||
// sessRules: 'internet|ims_sig',
|
||||
// },
|
||||
// ];
|
||||
// {
|
||||
// "hdrEnrich": "dnn",
|
||||
// "imsi": "160990100000003",
|
||||
// "msisdn": "86755900011",
|
||||
// "pccRules": "internet|ims_sig",
|
||||
// "qosAudio": "qos_audio",
|
||||
// "qosVideo": "qos_video",
|
||||
// "rfsp": 0,
|
||||
// "sar": "def_sar",
|
||||
// "sessRules": "internet|ims_sig",
|
||||
// "uePolicy": "uep_001"
|
||||
// }
|
||||
// ]
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -124,7 +133,7 @@ export async function updateRule(data: Record<string, any>) {
|
||||
*/
|
||||
export async function batchUpdateRule(data: Record<string, any>) {
|
||||
const result = await request({
|
||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/${data.num}?neId=${data.neId}`,
|
||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
|
||||
method: 'put',
|
||||
data: data,
|
||||
});
|
||||
@@ -168,7 +177,7 @@ export async function addRule(data: Record<string, any>) {
|
||||
*/
|
||||
export async function batchAddRule(data: Record<string, any>) {
|
||||
const result = await request({
|
||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/${data.num}?neId=${data.neId}`,
|
||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
@@ -202,7 +211,7 @@ export function delRule(neId: string, data: Record<string, any>) {
|
||||
*/
|
||||
export async function batchDelRule(data: Record<string, any>) {
|
||||
return request({
|
||||
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/${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',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import { parseObjLineToHump } from '@/utils/parse-utils';
|
||||
* @returns object
|
||||
*/
|
||||
export async function listgoldData(query: Record<string, any>) {
|
||||
console.log(query);
|
||||
let totalSQL = 'select count(*) as total from gold_kpi where 1=1 ';
|
||||
let rowsSQL =
|
||||
'SELECT gold_kpi.*,kpi_title.en_title FROM gold_kpi LEFT JOIN kpi_title on gold_kpi.kpi_id=kpi_title.kpi_id where 1=1 ';
|
||||
@@ -29,10 +28,10 @@ export async function listgoldData(query: Record<string, any>) {
|
||||
let sortSql = ' order by ';
|
||||
if (query.sortField) {
|
||||
sortSql += ` ${query.sortField} `;
|
||||
}else{
|
||||
} else {
|
||||
sortSql += ` start_time `;
|
||||
}
|
||||
|
||||
|
||||
if (query.sortOrder === 'asc') {
|
||||
sortSql += ' asc ';
|
||||
} else {
|
||||
@@ -76,3 +75,41 @@ export async function listgoldData(query: Record<string, any>) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询黄金指标数据
|
||||
* @param query 查询参数
|
||||
* @returns object
|
||||
*/
|
||||
export async function goldData(query: Record<string, any>) {
|
||||
const result = await request({
|
||||
url: `/ne/kpi/data`,
|
||||
method: 'get',
|
||||
params: {
|
||||
neType: query.neType[0],
|
||||
neId: query.neType[1],
|
||||
startTime: query.beginTime,
|
||||
endTime: query.endTime,
|
||||
interval: query.particle,
|
||||
},
|
||||
timeout: 60_000,
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询网元可用黄金指标
|
||||
* @param neType 网元类型
|
||||
* @returns object
|
||||
*/
|
||||
export async function getGoldTitleByNE(neType: string) {
|
||||
// 发起请求
|
||||
const result = await request({
|
||||
url: `/ne/kpi/title`,
|
||||
method: 'get',
|
||||
params: { neType },
|
||||
});
|
||||
// 解析数据
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -199,6 +199,18 @@ export function chunkUpload(data: FormData) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 转存上传文件到静态资源
|
||||
* @returns object
|
||||
*/
|
||||
export function transferStaticFile(data: Record<string, any>) {
|
||||
return request({
|
||||
url: `/file/transferStaticFile`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传切片文件并发送文件到网元端
|
||||
* @param neType 网元类型, UPF
|
||||
|
||||
29
src/api/tool/neFile.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { request } from '@/plugins/http-fetch';
|
||||
|
||||
/**
|
||||
* 查询文件列表列表
|
||||
* @param query 查询参数
|
||||
* @returns object
|
||||
*/
|
||||
export function listNeFiles(query: Record<string, any>) {
|
||||
return request({
|
||||
url: '/ne/action/files',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件
|
||||
* @param query 查询参数
|
||||
* @returns object
|
||||
*/
|
||||
export function getNeFile(query: Record<string, any>) {
|
||||
return request({
|
||||
url: '/ne/action/pullFile',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob',
|
||||
timeout: 180_000,
|
||||
});
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Ant-Design-Pro</title>
|
||||
<desc>mask-and-vue3 By TsMask</desc>
|
||||
<defs></defs>
|
||||
<g id="Ant-Design-Pro" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="mask-and-vue3" transform="translate(-79.000000, -82.000000)">
|
||||
<g id="Group-21" transform="translate(77.000000, 73.000000)">
|
||||
<g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
|
||||
<ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse>
|
||||
<ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse>
|
||||
<path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path>
|
||||
<path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6">
|
||||
<ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse>
|
||||
<path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse>
|
||||
<ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse>
|
||||
<path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path>
|
||||
<g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6">
|
||||
<ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse>
|
||||
<path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path>
|
||||
</g>
|
||||
<ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse>
|
||||
<path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path>
|
||||
</g>
|
||||
<g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
|
||||
<ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse>
|
||||
<g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
|
||||
<ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse>
|
||||
<path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path>
|
||||
</g>
|
||||
<path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
<ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse>
|
||||
<ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse>
|
||||
<path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
</g>
|
||||
<g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
|
||||
<g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9">
|
||||
<circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle>
|
||||
<path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path>
|
||||
</g>
|
||||
<circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle>
|
||||
<path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline>
|
||||
<path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path>
|
||||
<path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path>
|
||||
<circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle>
|
||||
<circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle>
|
||||
<circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 127 KiB |
775
src/components/ChartGraphG6/index.vue
Normal file
@@ -0,0 +1,775 @@
|
||||
<template>
|
||||
<div>
|
||||
<div ref="g6Dom" :style="{ height: height, width: width }"></div>
|
||||
<button @click="actions['Enable/Disable Node States'].Breathing()">
|
||||
Breathing()
|
||||
</button>
|
||||
<button @click="actions['Enable/Disable Node States'].Scaling()">
|
||||
Scaling()
|
||||
</button>
|
||||
|
||||
<button @click="actions['Enable/Disable Edge States'].Growing()">
|
||||
Growing()
|
||||
</button>
|
||||
<button @click="actions['Enable/Disable Edge States'].Running()">
|
||||
Running()
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, watch, onMounted, onBeforeUnmount, ref } from 'vue';
|
||||
import { Graph, extend, Extensions } from '@antv/g6';
|
||||
|
||||
const props = defineProps({
|
||||
/**
|
||||
* 图表主题
|
||||
*
|
||||
* 'dark' | 'light'
|
||||
*/
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'light', // 'dark' | 'light'
|
||||
},
|
||||
/**宽度,默认100% */
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%',
|
||||
},
|
||||
/**高度 */
|
||||
height: {
|
||||
type: String,
|
||||
default: '500px',
|
||||
},
|
||||
});
|
||||
|
||||
const g6Dom = ref<HTMLElement | undefined>(undefined);
|
||||
|
||||
const ExtGraph = extend(Graph, {
|
||||
layouts: {},
|
||||
edges: {
|
||||
'polyline-edge': Extensions.PolylineEdge,
|
||||
'cubic-edge': Extensions.CubicEdge,
|
||||
// 'custom-edge': Extensions.CubicEdge,
|
||||
},
|
||||
});
|
||||
|
||||
const data = {
|
||||
nodes: [
|
||||
// 0 基站
|
||||
{
|
||||
id: '0',
|
||||
data: {
|
||||
x: 80,
|
||||
y: 150,
|
||||
type: 'circle-node',
|
||||
color: '#fffff',
|
||||
keyShape: {
|
||||
r: 24,
|
||||
width: 48,
|
||||
height: 48,
|
||||
fill: '#9EC9FF',
|
||||
stroke: '#5B8FF9',
|
||||
lineWidth: 2,
|
||||
},
|
||||
labelShape: {
|
||||
text: '基站',
|
||||
position: 'bottom',
|
||||
maxWidth: '200%',
|
||||
offsetY: 10,
|
||||
},
|
||||
labelBackgroundShape: {},
|
||||
iconShape: {
|
||||
img: 'https://gw.alipayobjects.com/zos/basement_prod/012bcf4f-423b-4922-8c24-32a89f8c41ce.svg',
|
||||
width: 24,
|
||||
height: 24,
|
||||
},
|
||||
},
|
||||
},
|
||||
// 1 DM
|
||||
{
|
||||
id: '1',
|
||||
data: {
|
||||
label: 'DM',
|
||||
x: 600,
|
||||
y: 350,
|
||||
},
|
||||
},
|
||||
// 2 O&M
|
||||
{
|
||||
id: '2',
|
||||
data: {
|
||||
label: 'O&M',
|
||||
x: 900,
|
||||
y: 100,
|
||||
},
|
||||
},
|
||||
// 5GC控制面
|
||||
{
|
||||
id: '170',
|
||||
data: {
|
||||
label: 'NSSF',
|
||||
parentId: 'combo-5gc',
|
||||
x: 300,
|
||||
y: 50,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '130',
|
||||
data: {
|
||||
label: 'AUSF',
|
||||
parentId: 'combo-5gc',
|
||||
x: 400,
|
||||
y: 50,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '140',
|
||||
data: {
|
||||
label: 'UDM',
|
||||
parentId: 'combo-5gc',
|
||||
x: 500,
|
||||
y: 50,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '120',
|
||||
data: {
|
||||
label: 'AMF',
|
||||
parentId: 'combo-5gc',
|
||||
x: 300,
|
||||
y: 150,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '180',
|
||||
data: {
|
||||
label: 'NRF',
|
||||
parentId: 'combo-5gc',
|
||||
x: 400,
|
||||
y: 150,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '150',
|
||||
data: {
|
||||
label: 'SMF',
|
||||
parentId: 'combo-5gc',
|
||||
x: 500,
|
||||
y: 250,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '160',
|
||||
data: {
|
||||
label: 'PCF',
|
||||
parentId: 'combo-5gc',
|
||||
x: 600,
|
||||
y: 250,
|
||||
},
|
||||
},
|
||||
// 5GC用户面
|
||||
{
|
||||
id: '190',
|
||||
data: {
|
||||
label: 'UPF',
|
||||
parentId: 'combo-upf',
|
||||
x: 300,
|
||||
y: 350,
|
||||
},
|
||||
},
|
||||
// EP-IMS
|
||||
{
|
||||
id: '110',
|
||||
data: {
|
||||
label: 'I/S-CSCF',
|
||||
parentId: 'combo-ims',
|
||||
x: 800,
|
||||
y: 350,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '111',
|
||||
data: {
|
||||
label: 'P-CSCF',
|
||||
parentId: 'combo-ims',
|
||||
x: 800,
|
||||
y: 400,
|
||||
},
|
||||
},
|
||||
// O&M
|
||||
{
|
||||
id: '100',
|
||||
data: {
|
||||
label: 'EMS',
|
||||
parentId: 'combo-ems',
|
||||
x: 800,
|
||||
y: 100,
|
||||
},
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
id: '0-5gc',
|
||||
source: '0',
|
||||
target: 'combo-5gc',
|
||||
data: {
|
||||
type: 'cubic-edge',
|
||||
animates: {
|
||||
update: [
|
||||
{
|
||||
// 在 selected 和 active 状态变化导致的 haloShape opacity 变化时,使 opacity 带动画地更新
|
||||
fields: ['opacity'],
|
||||
shapeId: 'haloShape',
|
||||
states: ['selected', 'active'],
|
||||
duration: 500,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '5gc-ems',
|
||||
source: 'combo-5gc',
|
||||
target: 'combo-ems',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: 'upf-ems',
|
||||
source: 'combo-upf',
|
||||
target: 'combo-ems',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: 'ims-ems',
|
||||
source: 'combo-ims',
|
||||
target: 'combo-ems',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: 'ems-2',
|
||||
source: 'combo-ems',
|
||||
target: '2',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '170-120',
|
||||
source: '170',
|
||||
target: '120',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '130-120',
|
||||
source: '130',
|
||||
target: '120',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '140-120',
|
||||
source: '140',
|
||||
target: '120',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '140-180',
|
||||
source: '140',
|
||||
target: '180',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '120-180',
|
||||
source: '120',
|
||||
target: '180',
|
||||
data: {
|
||||
type: 'polyline-edge',
|
||||
keyShape: {
|
||||
endArrow: true,
|
||||
routeCfg: {
|
||||
/**
|
||||
* 目前支持正交路由 'orth' 和地铁路由 'er'
|
||||
*/
|
||||
// name: 'er',
|
||||
/**
|
||||
* 是否开启自动避障,默认为 false
|
||||
* Whether to enable automatic obstacle avoidance, default is false
|
||||
*/
|
||||
enableObstacleAvoidance: true,
|
||||
},
|
||||
/**
|
||||
* 拐弯处的圆角弧度,默认为直角,值为 0
|
||||
* The radius of the corner rounding, defaults to a right angle
|
||||
*/
|
||||
// radius: 20,
|
||||
/**
|
||||
* 拐弯处距离节点最小距离, 默认为 2
|
||||
* Minimum distance from the node at the corner, default is 5.
|
||||
*/
|
||||
// offset: 0,
|
||||
/**
|
||||
* 控制点数组,不指定时根据 A* 算法自动生成折线。若指定了,则按照 controlPoints 指定的位置进行弯折
|
||||
* An array of control points that, when not specified, automatically generates the bends according to the A* algorithm. If specified, bends are made at the position specified by controlPoints.
|
||||
*/
|
||||
// controlPoints: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '130-180',
|
||||
source: '130',
|
||||
target: '180',
|
||||
data: {
|
||||
type: 'polyline-edge',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '140-150',
|
||||
source: '140',
|
||||
target: '150',
|
||||
data: {
|
||||
type: 'polyline-edge',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '140-110',
|
||||
source: '140',
|
||||
target: '110',
|
||||
data: {
|
||||
type: 'polyline-edge',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '120-150',
|
||||
source: '120',
|
||||
target: '150',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '150-180',
|
||||
source: '150',
|
||||
target: '180',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '150-160',
|
||||
source: '150',
|
||||
target: '160',
|
||||
data: { type: 'polyline-edge' },
|
||||
},
|
||||
{
|
||||
id: '160-120',
|
||||
source: '160',
|
||||
target: '120',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '160-180',
|
||||
source: '160',
|
||||
target: '180',
|
||||
data: {
|
||||
keyShape: {
|
||||
endArrow: true,
|
||||
},
|
||||
labelShape: {
|
||||
text: 'asdf-arrow',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '160-111',
|
||||
source: '160',
|
||||
target: '111',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '0-upf',
|
||||
source: '0',
|
||||
target: 'combo-upf',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: '150-190',
|
||||
source: '150',
|
||||
target: '190',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: 'upf-1',
|
||||
source: 'combo-upf',
|
||||
target: '1',
|
||||
data: {},
|
||||
},
|
||||
{
|
||||
id: 'upf-ims',
|
||||
source: 'combo-upf',
|
||||
target: 'combo-ims',
|
||||
data: {},
|
||||
},
|
||||
],
|
||||
combos: [
|
||||
{
|
||||
id: 'combo-5gc',
|
||||
data: {
|
||||
text: '5GC控制面',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'combo-upf',
|
||||
data: {
|
||||
label: '5GC用户面',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'combo-ims',
|
||||
data: {
|
||||
label: 'EP-IMS用户面',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'combo-ems',
|
||||
data: {
|
||||
label: 'EMS',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
let graph: any = null;
|
||||
/**初始化渲染图表 */
|
||||
function initChart() {
|
||||
if (!g6Dom.value) return;
|
||||
graph = new ExtGraph({
|
||||
container: g6Dom.value,
|
||||
height: 500,
|
||||
modes: {
|
||||
default: [
|
||||
{
|
||||
type: 'drag-node',
|
||||
enableTransient: false,
|
||||
updateComboStructure: false,
|
||||
},
|
||||
{
|
||||
type: 'click-select',
|
||||
itemTypes: ['node', 'edge', 'combo'],
|
||||
},
|
||||
{
|
||||
type: 'drag-combo',
|
||||
enableTransient: true,
|
||||
updateComboStructure: true,
|
||||
},
|
||||
// 'drag-combo',
|
||||
'drag-canvas',
|
||||
// 'click-select',
|
||||
'zoom-canvas',
|
||||
] as any,
|
||||
},
|
||||
// 布局 力向吸引
|
||||
layout: {
|
||||
type: 'force',
|
||||
animated: true,
|
||||
linkDistance: 280,
|
||||
maxSpeed: 100,
|
||||
clustering: true,
|
||||
nodeClusterBy: 'parentId',
|
||||
clusterNodeStrength: 80,
|
||||
},
|
||||
// 主题
|
||||
theme: {
|
||||
type: 'spec',
|
||||
base: 'light',
|
||||
specification: {
|
||||
node: {
|
||||
dataTypeField: 'parentId',
|
||||
},
|
||||
},
|
||||
} as any,
|
||||
// 插件
|
||||
plugins: [
|
||||
{
|
||||
// 避免文本过于密集导致的视觉混乱
|
||||
type: 'lod-controller',
|
||||
disableLod: true,
|
||||
},
|
||||
] as any,
|
||||
// 全局节点 矩形
|
||||
node: model => {
|
||||
const { id, data } = model;
|
||||
return {
|
||||
id,
|
||||
data: {
|
||||
type: 'rect-node',
|
||||
keyShape: {
|
||||
width: 80,
|
||||
height: 40,
|
||||
radius: 8,
|
||||
},
|
||||
labelShape: {
|
||||
position: 'center',
|
||||
text: data.label,
|
||||
},
|
||||
animates: {
|
||||
update: [
|
||||
{
|
||||
fields: ['opacity'],
|
||||
shapeId: 'haloShape',
|
||||
states: ['breathing'],
|
||||
iterations: Infinity,
|
||||
direction: 'alternate',
|
||||
duration: 500,
|
||||
},
|
||||
{
|
||||
fields: ['lineWidth'],
|
||||
shapeId: 'keyShape',
|
||||
states: ['breathing'],
|
||||
iterations: Infinity,
|
||||
direction: 'alternate',
|
||||
duration: 500,
|
||||
},
|
||||
{
|
||||
fields: ['height', 'width'],
|
||||
shapeId: 'keyShape',
|
||||
states: ['scaling'],
|
||||
iterations: Infinity,
|
||||
direction: 'alternate',
|
||||
duration: 500,
|
||||
},
|
||||
],
|
||||
},
|
||||
...data,
|
||||
},
|
||||
};
|
||||
},
|
||||
// 全局边 三次贝塞尔曲线
|
||||
edge: model => {
|
||||
const { id, source, target, data } = model;
|
||||
return {
|
||||
id,
|
||||
source,
|
||||
target,
|
||||
data: {
|
||||
type: 'cubic-edge',
|
||||
animates: {
|
||||
update: [
|
||||
{
|
||||
fields: ['lineDash'],
|
||||
shapeId: 'keyShape',
|
||||
states: ['growing', 'running'],
|
||||
iterations: Infinity,
|
||||
duration: 2000,
|
||||
},
|
||||
{
|
||||
fields: ['offsetDistance'],
|
||||
shapeId: 'buShape',
|
||||
states: ['circleRunning'],
|
||||
iterations: Infinity,
|
||||
duration: 2000,
|
||||
},
|
||||
],
|
||||
},
|
||||
...data,
|
||||
},
|
||||
};
|
||||
},
|
||||
// 全局框节点 矩形
|
||||
combo: model => {
|
||||
const { id, data } = model;
|
||||
return {
|
||||
id,
|
||||
data: {
|
||||
type: 'rect-combo',
|
||||
keyShape: {
|
||||
opacity: 0.8,
|
||||
padding: [20, 20, 20, 20],
|
||||
radius: 8,
|
||||
},
|
||||
labelShape: {
|
||||
text: data.label,
|
||||
offsetY: 8,
|
||||
},
|
||||
labelBackgroundShape: {},
|
||||
buildIn: [
|
||||
{
|
||||
fields: ['opacity'],
|
||||
duration: 500,
|
||||
delay: 500 + Math.random() * 500,
|
||||
},
|
||||
],
|
||||
buildOut: [
|
||||
{
|
||||
fields: ['opacity'],
|
||||
duration: 200,
|
||||
},
|
||||
],
|
||||
animates: {
|
||||
update: [
|
||||
{
|
||||
fields: ['width', 'height', 'x', 'y'],
|
||||
shapeId: 'keyShape',
|
||||
},
|
||||
],
|
||||
},
|
||||
...data,
|
||||
},
|
||||
};
|
||||
},
|
||||
// 节点状态
|
||||
nodeState: {
|
||||
breathing: {
|
||||
haloShape: {
|
||||
opacity: 0.25,
|
||||
lineWidth: 20,
|
||||
visible: true,
|
||||
},
|
||||
keyShape: {
|
||||
radius: 4,
|
||||
},
|
||||
},
|
||||
scaling: {
|
||||
keyShape: {
|
||||
width: 100,
|
||||
height: 60,
|
||||
},
|
||||
},
|
||||
} as any,
|
||||
edgeState: {
|
||||
growing: {
|
||||
keyShape: {
|
||||
lineWidth: 2,
|
||||
lineDash: ['100%', 0],
|
||||
},
|
||||
},
|
||||
running: {
|
||||
keyShape: {
|
||||
lineWidth: 2,
|
||||
lineDash: [2, 2],
|
||||
// TODO: lineDashOffset
|
||||
},
|
||||
},
|
||||
},
|
||||
data,
|
||||
});
|
||||
|
||||
graph.on('node:click', (e: any) => {
|
||||
const s = graph.getItemState(e.itemId);
|
||||
console.log(s);
|
||||
// graph.updateData('node', {
|
||||
// id: e.itemId,
|
||||
// data: {
|
||||
// cluster: Math.random(),
|
||||
// keyShape: {
|
||||
// r: 32 + Math.random() * 10 - 5,
|
||||
// lineWidth: 6 + Math.random() * 6 - 3,
|
||||
// stroke: '#000',
|
||||
// },
|
||||
// labelShape: {
|
||||
// fontWeight: 700,
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
});
|
||||
|
||||
graph.on('node:pointerenter', (e: any) => {
|
||||
const { itemId } = e;
|
||||
if (graph.getItemState(itemId, 'breathing')) {
|
||||
graph.setItemState(itemId, 'breathing', false);
|
||||
} else {
|
||||
graph.setItemState(itemId, 'scaling', false);
|
||||
graph.setItemState(itemId, 'breathing', true);
|
||||
}
|
||||
// graph.updateData('node', {
|
||||
// id: itemId,
|
||||
// data: {
|
||||
// label: `after been hovered ${itemId}`,
|
||||
// labelShape: {
|
||||
// fill: '#0f0',
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
});
|
||||
|
||||
graph.on('node:pointerleave', (e: any) => {
|
||||
const { itemId } = e;
|
||||
if (graph.getItemState(itemId, 'breathing')) {
|
||||
graph.setItemState(itemId, 'breathing', false);
|
||||
} else {
|
||||
graph.setItemState(itemId, 'scaling', false);
|
||||
graph.setItemState(itemId, 'breathing', true);
|
||||
}
|
||||
// graph.updateData('node', {
|
||||
// id: itemId,
|
||||
// data: {
|
||||
// label: 'label before been hovered',
|
||||
// labelShape: {
|
||||
// fill: '#000',
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
||||
const actions = {
|
||||
'Enable/Disable Node States': {
|
||||
Breathing: () => {
|
||||
graph.getAllNodesData().forEach((node: any) => {
|
||||
if (graph.getItemState(node.id, 'breathing')) {
|
||||
graph.setItemState(node.id, 'breathing', false);
|
||||
} else {
|
||||
graph.setItemState(node.id, 'scaling', false);
|
||||
graph.setItemState(node.id, 'breathing', true);
|
||||
}
|
||||
});
|
||||
},
|
||||
Scaling: () => {
|
||||
graph.getAllNodesData().forEach((node: any) => {
|
||||
if (graph.getItemState(node.id, 'scaling')) {
|
||||
graph.setItemState(node.id, 'scaling', false);
|
||||
} else {
|
||||
graph.setItemState(node.id, 'breathing', false);
|
||||
graph.setItemState(node.id, 'scaling', true);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
'Enable/Disable Edge States': {
|
||||
Growing: () => {
|
||||
graph.getAllEdgesData().forEach((edge: any) => {
|
||||
if (graph.getItemState(edge.id, 'growing')) {
|
||||
graph.setItemState(edge.id, 'growing', false);
|
||||
} else {
|
||||
graph.setItemState(edge.id, 'running', false);
|
||||
graph.setItemState(edge.id, 'growing', true);
|
||||
}
|
||||
});
|
||||
},
|
||||
Running: () => {
|
||||
graph.getAllEdgesData().forEach((edge: any) => {
|
||||
if (graph.getItemState(edge.id, 'running')) {
|
||||
graph.setItemState(edge.id, 'running', false);
|
||||
} else {
|
||||
graph.setItemState(edge.id, 'growing', false);
|
||||
graph.setItemState(edge.id, 'running', true);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// watch(
|
||||
// () => props.option,
|
||||
// val => {
|
||||
// if (val) {
|
||||
// nextTick(() => {
|
||||
// initChart();
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
initChart();
|
||||
});
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -69,7 +69,7 @@ const props = defineProps({
|
||||
const seriesStyle = [
|
||||
{
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(22, 119, 255, .5)',
|
||||
},
|
||||
@@ -203,7 +203,7 @@ function initChart() {
|
||||
},
|
||||
},
|
||||
grid: props.option.grid || { left: '8%', right: '8%', bottom: '20%' },
|
||||
legend: {
|
||||
legend: props.option.legend || {
|
||||
right: 10,
|
||||
itemWidth: 8,
|
||||
textStyle: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { computed } from 'vue';
|
||||
import { computed, onBeforeMount } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { localSet } from '@/utils/cache-local-utils';
|
||||
import { localGet, localSet } from '@/utils/cache-local-utils';
|
||||
import { CACHE_LOCAL_I18N } from '@/constants/cache-keys-constants';
|
||||
|
||||
export default function useLocale() {
|
||||
@@ -20,7 +20,7 @@ export default function useLocale() {
|
||||
};
|
||||
|
||||
// 可选的语言
|
||||
const optionsLocale= [
|
||||
const optionsLocale = [
|
||||
{
|
||||
value: 'zh_CN',
|
||||
label: '中文',
|
||||
@@ -31,6 +31,14 @@ export default function useLocale() {
|
||||
},
|
||||
];
|
||||
|
||||
// 挂载前根据默认语言在设置一次
|
||||
onBeforeMount(() => {
|
||||
const localI18n = localGet(CACHE_LOCAL_I18N);
|
||||
if (localI18n) {
|
||||
i18n.locale.value = localI18n;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
optionsLocale,
|
||||
currentLocale,
|
||||
|
||||
@@ -376,7 +376,7 @@ export default {
|
||||
fileName: 'File Name',
|
||||
version: 'Version',
|
||||
versionPlease: 'Version number cannot be empty',
|
||||
updateTime: 'Uploaded',
|
||||
updateTime: 'Uploaded Time',
|
||||
description: 'Description',
|
||||
deleteTip: 'Are you sure to delete the data item with software [{fileName}]?',
|
||||
downloadTip: 'Are you sure to download the data item with software [{fileName}]?',
|
||||
@@ -407,7 +407,7 @@ export default {
|
||||
neTypePlease: 'Select network element type',
|
||||
neType: 'NE Type',
|
||||
fileName: 'File Name',
|
||||
createTime: 'Uploaded',
|
||||
createTime: 'Uploaded Time',
|
||||
comment: 'File Description',
|
||||
updateComment: 'License Description',
|
||||
updateCommentPlease: 'Please enter a license description',
|
||||
@@ -455,7 +455,7 @@ export default {
|
||||
addItemOk: "Add Index as {num} Record Succeeded",
|
||||
addItemErr: "Record addition failure",
|
||||
requireUn: "{display} input value is of unknown type",
|
||||
requireString: "The {display} parameter value does not make sense.",
|
||||
requireString: "The {display} parameter value is invalid.",
|
||||
requireInt: "{display} Parameter value not in reasonable range {filter}",
|
||||
requireIpv4: "{display} not a legitimate IPV4 address",
|
||||
requireIpv6: "{display} Not a legitimate IPV6 address.",
|
||||
@@ -477,7 +477,7 @@ export default {
|
||||
import: 'Import',
|
||||
loadDataConfirm: 'Are you sure you want to reload the data?',
|
||||
loadData: 'Load Data',
|
||||
loadDataTip: 'Successfully fetched updated 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. You can click reset to refresh the data list after the loading is finished, please don it repeat click to get update!!!!',
|
||||
startIMSI: 'Start IMSI',
|
||||
batchAddText: 'Batch Add',
|
||||
batchDelText: 'Batch Delete',
|
||||
@@ -500,8 +500,8 @@ export default {
|
||||
exportConfirm: 'Are you sure to export all signed user data?',
|
||||
import: 'Import',
|
||||
loadDataConfirm: 'Are you sure you want to reload the data?',
|
||||
loadData: 'Updated Data',
|
||||
loadDataTip: 'Successfully fetched updated 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!!!!',
|
||||
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!!!!',
|
||||
numAdd: 'Number of releases',
|
||||
numDel: 'Number of deleted',
|
||||
batchAddText: 'Batch Add',
|
||||
@@ -536,15 +536,16 @@ export default {
|
||||
addTitle: 'Adding Policy Control Information',
|
||||
updateTitle: '{imsi} Policy control information',
|
||||
startIMSI: 'Start IMSI',
|
||||
batchAddText: 'Batch Addition',
|
||||
batchDelText: 'Batch Deletion',
|
||||
batchUpdateText: 'Batch Update',
|
||||
batchAddText: 'Batch Add',
|
||||
batchDelText: 'Batch Delete',
|
||||
batchUpdateText: 'Batch Modify',
|
||||
batchNum: 'Number of batches',
|
||||
imsiTip: 'IMSI=MCC+MNC+MSIN',
|
||||
imsiTip1: 'MCC=Mobile Country Code, consisting of three digits.',
|
||||
imsiTip2: 'MNC = Mobile Network Number, consisting of two digits',
|
||||
imsiTip3: 'MSIN = Mobile Subscriber Identification Number, consisting of 10 equal digits.',
|
||||
delSure:'Are you sure you want to delete the user with IMSI number: {imsi}?',
|
||||
uploadFileErr: 'File Upload Failed',
|
||||
},
|
||||
base5G: {
|
||||
neType: 'AMF Object',
|
||||
@@ -628,6 +629,13 @@ export default {
|
||||
value:'Value',
|
||||
startTime:'Start Time',
|
||||
endTime:'End Time',
|
||||
particle: 'Particle Ssize',
|
||||
timeFrame: 'Time Range',
|
||||
nullTip:'There are no statistical data within this time range',
|
||||
kpiTitle:'KPI Statistics Chart',
|
||||
allData:'Complete Data',
|
||||
makeLine:'Statistical Chart',
|
||||
time:'Time',
|
||||
}
|
||||
},
|
||||
traceManage: {
|
||||
@@ -670,7 +678,7 @@ export default {
|
||||
execTimeout: 'Execution timeout',
|
||||
execSuccess: 'Execution completed',
|
||||
execFailed: 'Execution failed',
|
||||
execBreak: 'break execution',
|
||||
execBreak: 'Break Execution',
|
||||
noFileName: 'Invalid file name',
|
||||
execUPFStartA: 'Executed, please stop capturing packets according to the situation',
|
||||
execUPFStart: 'Execution successful, please stop capturing packets according to the situation',
|
||||
@@ -739,7 +747,7 @@ export default {
|
||||
alarmTitle:'Title',
|
||||
clearUser:'Clear User',
|
||||
clearType:'Clear Type',
|
||||
ackState: 'Ack Status',
|
||||
ackState: 'Alarm Status',
|
||||
ackUser:'Ack User',
|
||||
alarmSeq:'Sequence Number',
|
||||
objectName:'Object Name',
|
||||
@@ -808,7 +816,21 @@ export default {
|
||||
alarmInfo:'Alarm Content',
|
||||
eventTime:'Generation Time',
|
||||
logTime:'Record Time'
|
||||
}
|
||||
},
|
||||
neFile: {
|
||||
neType:'NE Type',
|
||||
neTypePlease:'Please select NE Type',
|
||||
nePath: "Directory Path",
|
||||
fileMode: "File Mode",
|
||||
owner: "Owner",
|
||||
group: "Group",
|
||||
size: "Size",
|
||||
modifiedTime: "Modified Time",
|
||||
fileName: "File Name",
|
||||
downTip: "Confirm the download file name is [{fileName}] File?",
|
||||
downTipErr: "Failed to get file",
|
||||
dirCd: "Enter Dir",
|
||||
},
|
||||
},
|
||||
monitor: {
|
||||
session: {
|
||||
@@ -1107,6 +1129,10 @@ export default {
|
||||
sysOfficialUrlOpen: 'Open the official website.',
|
||||
sysOfficialUrlInstruction: 'Official website link address',
|
||||
sysOfficialUrlInstruction1: 'start, if you need to hide do not jump to fill in the',
|
||||
i18n: "Internationalization Switch",
|
||||
i18nOpen: "Display Switch",
|
||||
i18nDefault: "Default Languages",
|
||||
i18nInstruction: 'Whether to display the internationalization switch and set the system default language',
|
||||
},
|
||||
role:{
|
||||
allScopeOptions:'All data permissions',
|
||||
@@ -1309,7 +1335,7 @@ export default {
|
||||
cmdNoTip: "{num} no optional command operation",
|
||||
require: "Mandatory parameter: {num}",
|
||||
requireUn: "{display} input value is of unknown type",
|
||||
requireString: "The {display} parameter value does not make sense.",
|
||||
requireString: "The {display} parameter value is invalid.",
|
||||
requireInt: "{display} Parameter value not in reasonable range {filter}",
|
||||
requireIpv4: "{display} not a legitimate IPV4 address",
|
||||
requireIpv6: "{display} Not a legitimate IPV6 address.",
|
||||
@@ -1323,6 +1349,7 @@ export default {
|
||||
cmdAwait: "Waiting for a command to be sent",
|
||||
uploadFileTip: 'Are you sure you want to upload the file?',
|
||||
uploadFileOk: 'File Upload Successful',
|
||||
uploadFileErr: 'File Upload Failed',
|
||||
omcOperate:{
|
||||
noOMC: "No OMC network elements",
|
||||
},
|
||||
|
||||
@@ -476,8 +476,8 @@ export default {
|
||||
exportConfirm: '确认导出全部鉴权用户数据吗?',
|
||||
import: '导入',
|
||||
loadDataConfirm: '确认要重新加载数据吗?',
|
||||
loadData: '更新数据',
|
||||
loadDataTip: '成功获取更新数据:{num}条,系统内部正在进行数据更新。加载结束后可点击重置刷新数据列表,请勿重复点击获取更新!!!',
|
||||
loadData: '加载数据',
|
||||
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新。加载结束后可点击重置刷新数据列表,请勿重复点击获取更新!!!',
|
||||
startIMSI: '起始IMSI',
|
||||
batchAddText: '批量新增',
|
||||
batchDelText: '批量删除',
|
||||
@@ -500,8 +500,8 @@ export default {
|
||||
exportConfirm: '确认导出全部签约用户数据吗?',
|
||||
import: '导入',
|
||||
loadDataConfirm: '确认要重新加载数据吗?',
|
||||
loadData: '更新数据',
|
||||
loadDataTip: '成功获取更新数据:{num}条,系统内部正在进行数据更新。加载结束后可点击重置刷新数据列表,请勿重复点击获取更新!!!',
|
||||
loadData: '加载数据',
|
||||
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新。加载结束后可点击重置刷新数据列表,请勿重复点击获取更新!!!',
|
||||
numAdd: '放号个数',
|
||||
numDel: '删除个数',
|
||||
batchAddText: '批量新增',
|
||||
@@ -545,6 +545,7 @@ export default {
|
||||
imsiTip2: 'MNC=移动网络号,由两位数字组成',
|
||||
imsiTip3: 'MSIN=移动客户识别码,采用等长10位数字构成',
|
||||
delSure:'确认删除IMSI编号为: {imsi} 的用户吗?',
|
||||
uploadFileErr: '文件上传失败',
|
||||
},
|
||||
base5G: {
|
||||
neType: 'AMF网元对象',
|
||||
@@ -627,7 +628,14 @@ export default {
|
||||
enTitle:'黄金指标项',
|
||||
value:'值',
|
||||
startTime:'开始时间',
|
||||
endTime:'结束时间'
|
||||
endTime:'结束时间',
|
||||
particle:'颗粒度',
|
||||
timeFrame:'时间范围',
|
||||
nullTip:'此时间范围内没有统计数据',
|
||||
kpiTitle:'KPI统计图表',
|
||||
allData:'完整统计数据',
|
||||
makeLine:'统计图',
|
||||
time:'时间',
|
||||
}
|
||||
},
|
||||
traceManage: {
|
||||
@@ -808,7 +816,21 @@ export default {
|
||||
alarmInfo:'告警内容',
|
||||
eventTime:'告警产生时间',
|
||||
logTime:'记录时间'
|
||||
}
|
||||
},
|
||||
neFile: {
|
||||
neType:'网元',
|
||||
neTypePlease:'请选择网元',
|
||||
nePath: "目录路径",
|
||||
fileMode: "文件权限",
|
||||
owner: "所属用户",
|
||||
group: "所属组",
|
||||
size: "文件大小",
|
||||
modifiedTime: "修改时间",
|
||||
fileName: "文件名称",
|
||||
downTip: "确认下载文件名为 【{fileName}】 文件?",
|
||||
downTipErr: "文件获取失败",
|
||||
dirCd: "进入目录",
|
||||
},
|
||||
},
|
||||
monitor: {
|
||||
session: {
|
||||
@@ -1107,6 +1129,10 @@ export default {
|
||||
sysOfficialUrlOpen: '打开官网',
|
||||
sysOfficialUrlInstruction: '官网链接地址',
|
||||
sysOfficialUrlInstruction1: '开头,如需隐藏不跳转填写',
|
||||
i18n: "国际化切换",
|
||||
i18nOpen: "显示切换",
|
||||
i18nDefault: "默认语言",
|
||||
i18nInstruction: '是否显示国际化切换,设置系统默认语言',
|
||||
},
|
||||
role:{
|
||||
allScopeOptions:'全部数据权限',
|
||||
@@ -1323,6 +1349,7 @@ export default {
|
||||
cmdAwait: "等待发送命令",
|
||||
uploadFileTip: '确认要上传文件吗?',
|
||||
uploadFileOk: '文件上传成功',
|
||||
uploadFileErr: '文件上传失败',
|
||||
omcOperate:{
|
||||
noOMC: "暂无OMC网元",
|
||||
},
|
||||
|
||||
@@ -23,7 +23,8 @@ import { getServerTime } from '@/api';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { onMounted } from 'vue';
|
||||
import { parseDateToStr } from '@/utils/date-utils';
|
||||
const { t } = useI18n();
|
||||
import { parseUrlPath } from '@/plugins/file-static-url';
|
||||
const { t, currentLocale } = useI18n();
|
||||
const routerStore = useRouterStore();
|
||||
const tabsStore = useTabsStore();
|
||||
const appStore = useAppStore();
|
||||
@@ -121,6 +122,35 @@ function fnComponentSetName(component: any, to: any) {
|
||||
// 清空导航栏标签
|
||||
tabsStore.clear();
|
||||
|
||||
// LOGO地址
|
||||
const logoUrl = computed(() => {
|
||||
let url =
|
||||
appStore.logoType === 'brand'
|
||||
? parseUrlPath(appStore.filePathBrand)
|
||||
: parseUrlPath(appStore.filePathIcon);
|
||||
|
||||
if (url.indexOf('{language}') === -1) {
|
||||
return url;
|
||||
}
|
||||
// 语言参数替换
|
||||
const local = currentLocale.value;
|
||||
const lang = local.split('_')[0];
|
||||
return url.replace('{language}', lang);
|
||||
});
|
||||
|
||||
// 系统使用手册地址
|
||||
const helpDocUrl = computed(() => {
|
||||
let url = parseUrlPath(appStore.helpDoc);
|
||||
|
||||
if (url.indexOf('{language}') === -1) {
|
||||
return url;
|
||||
}
|
||||
// 语言参数替换
|
||||
const local = currentLocale.value;
|
||||
const lang = local.split('_')[0];
|
||||
return url.replace('{language}', lang);
|
||||
});
|
||||
|
||||
/**系统使用手册跳转 */
|
||||
function fnClickHelpDoc(language?: string) {
|
||||
const routeData = router.resolve({ name: 'HelpDoc' });
|
||||
@@ -220,7 +250,7 @@ document.addEventListener('visibilitychange', function () {
|
||||
>
|
||||
<img
|
||||
class="logo-icon"
|
||||
:src="appStore.getLOGOIcon"
|
||||
:src="logoUrl"
|
||||
:alt="appStore.appName"
|
||||
:title="appStore.appName"
|
||||
/>
|
||||
@@ -231,7 +261,7 @@ document.addEventListener('visibilitychange', function () {
|
||||
<template v-if="appStore.logoType === 'brand'">
|
||||
<img
|
||||
class="logo-brand"
|
||||
:src="appStore.getLOGOBrand"
|
||||
:src="logoUrl"
|
||||
:alt="appStore.appName"
|
||||
:title="appStore.appName"
|
||||
/>
|
||||
@@ -282,7 +312,7 @@ document.addEventListener('visibilitychange', function () {
|
||||
<template #footerRender="{ width }">
|
||||
<footer class="footer">
|
||||
<div class="footer-fixed" :style="{ width }">
|
||||
<div>
|
||||
<div style="flex: 1;">
|
||||
<span>{{ appStore.copyright }}</span>
|
||||
</div>
|
||||
<a-space direction="horizontal" :size="8">
|
||||
@@ -296,12 +326,7 @@ document.addEventListener('visibilitychange', function () {
|
||||
>
|
||||
{{ t('loayouts.basic.officialUrl') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
type="link"
|
||||
size="small"
|
||||
@click="fnClickHelpDoc()"
|
||||
v-if="appStore.getHelpDoc !== '#'"
|
||||
>
|
||||
<a-button type="link" size="small" @click="fnClickHelpDoc()">
|
||||
{{ t('loayouts.basic.helpDoc') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
@@ -339,7 +364,7 @@ document.addEventListener('visibilitychange', function () {
|
||||
.footer {
|
||||
z-index: 16;
|
||||
margin: 0px;
|
||||
width: auto;
|
||||
width: auto;
|
||||
margin-top: 52px;
|
||||
&-fixed {
|
||||
position: fixed;
|
||||
@@ -354,6 +379,7 @@ document.addEventListener('visibilitychange', function () {
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 4px #0015291f;
|
||||
transition: background 0.3s, width 0.2s;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
& #serverTimeDom {
|
||||
|
||||
@@ -6,7 +6,6 @@ import useI18n from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import useAlarmStore from '@/store/modules/alarm';
|
||||
import { sessionGet } from '@/utils/cache-session-utils';
|
||||
const { isFullscreen, toggle } = useFullscreen();
|
||||
const { t, changeLocale, optionsLocale } = useI18n();
|
||||
const userStore = useUserStore();
|
||||
@@ -43,9 +42,6 @@ function fnClickHelpDoc(language?: string) {
|
||||
window.open(href, '_blank');
|
||||
}
|
||||
|
||||
// 兼容旧前端可改配置文件
|
||||
const i18nDisable = sessionGet('i18nDisable') === 'false';
|
||||
|
||||
/**改变多语言 */
|
||||
function fnChangeLocale(e: any) {
|
||||
changeLocale(e.key);
|
||||
@@ -66,7 +62,7 @@ function fnChangeLocale(e: any) {
|
||||
</template>
|
||||
</a-button>
|
||||
|
||||
<a-tooltip placement="bottom" v-if="appStore.getHelpDoc !== '#'">
|
||||
<a-tooltip placement="bottom">
|
||||
<template #title>{{ t('loayouts.rightContent.helpDoc') }}</template>
|
||||
<a-button type="text" @click="fnClickHelpDoc()">
|
||||
<template #icon>
|
||||
@@ -88,7 +84,7 @@ function fnChangeLocale(e: any) {
|
||||
<a-dropdown
|
||||
placement="bottom"
|
||||
:trigger="['click', 'hover']"
|
||||
v-if="!i18nDisable"
|
||||
v-if="appStore.i18nOpen"
|
||||
>
|
||||
<a-button size="small" type="default">
|
||||
{{ t('i18n') }}
|
||||
|
||||
21
src/plugins/file-static-url.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { sessionGet } from '@/utils/cache-session-utils';
|
||||
import { validHttp } from '@/utils/regular-utils';
|
||||
|
||||
/**
|
||||
* 解析资源文件绝对路径 http
|
||||
* @param path 服务端资源文件
|
||||
* @returns
|
||||
*/
|
||||
export function parseUrlPath(path: string) {
|
||||
if (!path || path === '#') {
|
||||
return '#';
|
||||
}
|
||||
if (validHttp(path)) {
|
||||
return path;
|
||||
}
|
||||
// 兼容旧前端可改配置文件
|
||||
const baseUrl = import.meta.env.PROD
|
||||
? sessionGet('baseUrl') || import.meta.env.VITE_API_BASE_URL
|
||||
: import.meta.env.VITE_API_BASE_URL;
|
||||
return `${baseUrl}${path}?r=${Math.random().toFixed(2)}`;
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import { getSysConf } from '@/api';
|
||||
import defaultLOGOIcon from '@/assets/logo_icon.png';
|
||||
import defaultLOGOBrand from '@/assets/logo_brand.png';
|
||||
import { CACHE_LOCAL_I18N } from '@/constants/cache-keys-constants';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { validHttp } from '@/utils/regular-utils';
|
||||
import { parseUrlPath } from '@/plugins/file-static-url';
|
||||
import { localGet, localSet } from '@/utils/cache-local-utils';
|
||||
import { defineStore } from 'pinia';
|
||||
import { sessionGet } from '@/utils/cache-session-utils';
|
||||
|
||||
/**应用参数类型 */
|
||||
type AppStore = {
|
||||
@@ -14,6 +13,7 @@ type AppStore = {
|
||||
appCode: string;
|
||||
/**应用版本 */
|
||||
appVersion: string;
|
||||
|
||||
/**应用版权声明 */
|
||||
copyright: string;
|
||||
/**LOGO显示类型 */
|
||||
@@ -29,6 +29,10 @@ type AppStore = {
|
||||
helpDoc: string;
|
||||
/**官方网址 */
|
||||
officialUrl: string;
|
||||
/**国际化切换 */
|
||||
i18nOpen: boolean;
|
||||
/**国际化默认语言 */
|
||||
i18nDefault: string;
|
||||
};
|
||||
|
||||
const useAppStore = defineStore('app', {
|
||||
@@ -36,6 +40,7 @@ const useAppStore = defineStore('app', {
|
||||
appName: import.meta.env.VITE_APP_NAME,
|
||||
appCode: import.meta.env.VITE_APP_CODE,
|
||||
appVersion: import.meta.env.VITE_APP_VERSION,
|
||||
|
||||
copyright: `Copyright ©2023 For ${import.meta.env.VITE_APP_NAME}`,
|
||||
logoType: 'icon',
|
||||
filePathIcon: '',
|
||||
@@ -44,85 +49,10 @@ const useAppStore = defineStore('app', {
|
||||
loginBackground: '',
|
||||
helpDoc: '',
|
||||
officialUrl: '',
|
||||
i18nOpen: true,
|
||||
i18nDefault: 'en_US',
|
||||
}),
|
||||
getters: {
|
||||
/**
|
||||
* 获取正确LOGO地址-icon
|
||||
* @param state 内部属性不用传入
|
||||
* @returns LOGO地址url
|
||||
*/
|
||||
getLOGOIcon(state) {
|
||||
const path = state.filePathIcon;
|
||||
if (!path || path === '#') {
|
||||
return defaultLOGOIcon;
|
||||
}
|
||||
if (validHttp(path)) {
|
||||
return path;
|
||||
}
|
||||
// 兼容旧前端可改配置文件
|
||||
const baseUrl = import.meta.env.PROD
|
||||
? sessionGet('baseUrl') || import.meta.env.VITE_API_BASE_URL
|
||||
: import.meta.env.VITE_API_BASE_URL;
|
||||
return `${baseUrl}${path}`;
|
||||
},
|
||||
/**
|
||||
* 获取正确LOGO地址-brand
|
||||
* @param state 内部属性不用传入
|
||||
* @returns LOGO地址url
|
||||
*/
|
||||
getLOGOBrand(state) {
|
||||
const path = state.filePathBrand;
|
||||
if (!path || path === '#') {
|
||||
return defaultLOGOBrand;
|
||||
}
|
||||
if (validHttp(path)) {
|
||||
return path;
|
||||
}
|
||||
// 兼容旧前端可改配置文件
|
||||
const baseUrl = import.meta.env.PROD
|
||||
? sessionGet('baseUrl') || import.meta.env.VITE_API_BASE_URL
|
||||
: import.meta.env.VITE_API_BASE_URL;
|
||||
return `${baseUrl}${path}`;
|
||||
},
|
||||
/**
|
||||
* 获取正确登录背景地址
|
||||
* @param state 内部属性不用传入
|
||||
* @returns 背景地址url
|
||||
*/
|
||||
getLoginBackground(state) {
|
||||
const path = state.loginBackground;
|
||||
if (!path || path === '#') {
|
||||
return '#';
|
||||
}
|
||||
if (validHttp(path)) {
|
||||
return path;
|
||||
}
|
||||
// 兼容旧前端可改配置文件
|
||||
const baseUrl = import.meta.env.PROD
|
||||
? sessionGet('baseUrl') || import.meta.env.VITE_API_BASE_URL
|
||||
: import.meta.env.VITE_API_BASE_URL;
|
||||
return `${baseUrl}${path}`;
|
||||
},
|
||||
/**
|
||||
* 获取正确使用手册地址
|
||||
* @param state 内部属性不用传入
|
||||
* @returns 手册地址url
|
||||
*/
|
||||
getHelpDoc(state) {
|
||||
const path = state.helpDoc;
|
||||
if (!path || path === '#') {
|
||||
return '#';
|
||||
}
|
||||
if (validHttp(path)) {
|
||||
return path;
|
||||
}
|
||||
// 兼容旧前端可改配置文件
|
||||
const baseUrl = import.meta.env.PROD
|
||||
? sessionGet('baseUrl') || import.meta.env.VITE_API_BASE_URL
|
||||
: import.meta.env.VITE_API_BASE_URL;
|
||||
return `${baseUrl}${path}`;
|
||||
},
|
||||
},
|
||||
getters: {},
|
||||
actions: {
|
||||
/**设置网页标题 */
|
||||
setTitle(title?: string) {
|
||||
@@ -136,16 +66,6 @@ const useAppStore = defineStore('app', {
|
||||
setCopyright(text: string) {
|
||||
this.copyright = text;
|
||||
},
|
||||
/**设置LOGO */
|
||||
setLOGO(type: 'brand' | 'icon', filePath: string) {
|
||||
this.logoType = type;
|
||||
if (type === 'brand') {
|
||||
this.filePathBrand = filePath;
|
||||
}
|
||||
if (type === 'icon') {
|
||||
this.filePathIcon = filePath;
|
||||
}
|
||||
},
|
||||
// 获取系统配置信息
|
||||
async fnSysConf() {
|
||||
const res = await getSysConf();
|
||||
@@ -156,16 +76,30 @@ const useAppStore = defineStore('app', {
|
||||
this.filePathIcon = res.data.filePathIcon;
|
||||
this.filePathBrand = res.data.filePathBrand;
|
||||
// 修改html内容-小图当作favicon.ico
|
||||
if (this.logoType) {
|
||||
if (this.logoType) {
|
||||
const iconDom = document.querySelector("link[rel~='icon']");
|
||||
if (iconDom) {
|
||||
iconDom.setAttribute('href', this.getLOGOIcon);
|
||||
let url = parseUrlPath(this.filePathIcon);
|
||||
// 语言参数替换
|
||||
if (url.indexOf('{language}') !== -1) {
|
||||
const local = localGet(CACHE_LOCAL_I18N) || 'en_US';
|
||||
const lang = local.split('_')[0];
|
||||
url = url.replace('{language}', lang);
|
||||
}
|
||||
iconDom.setAttribute('href', url);
|
||||
}
|
||||
}
|
||||
this.registerUser = res.data.registerUser === 'true';
|
||||
this.loginBackground = res.data.loginBackground;
|
||||
this.helpDoc = res.data.helpDoc;
|
||||
this.officialUrl = res.data.officialUrl;
|
||||
this.i18nOpen = res.data.i18nOpen === 'true';
|
||||
this.i18nDefault = res.data.i18nDefault;
|
||||
// 切换禁用时,设置默认语言
|
||||
const localI18n = localGet(CACHE_LOCAL_I18N);
|
||||
if (localI18n == null || (!this.i18nOpen && this.i18nDefault)) {
|
||||
localSet(CACHE_LOCAL_I18N, this.i18nDefault);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@ type NeInfo = {
|
||||
/**网元列表 */
|
||||
neList: Record<string, any>[];
|
||||
/**级联options树结构 */
|
||||
neCascaderOtions: Record<string, any>[];
|
||||
neCascaderOptions: Record<string, any>[];
|
||||
/**选择器单级父类型 */
|
||||
neSelectOtions: Record<string, any>[];
|
||||
/**跟踪接口列表 */
|
||||
@@ -22,7 +22,7 @@ type NeInfo = {
|
||||
const useNeInfoStore = defineStore('neinfo', {
|
||||
state: (): NeInfo => ({
|
||||
neList: [],
|
||||
neCascaderOtions: [],
|
||||
neCascaderOptions: [],
|
||||
neSelectOtions: [],
|
||||
traceInterfaceList: [],
|
||||
perMeasurementList: [],
|
||||
@@ -33,8 +33,8 @@ const useNeInfoStore = defineStore('neinfo', {
|
||||
* @param state 内部属性不用传入
|
||||
* @returns 级联options
|
||||
*/
|
||||
getNeCascaderOtions(state) {
|
||||
return state.neCascaderOtions;
|
||||
getNeCascaderOptions(state) {
|
||||
return state.neCascaderOptions;
|
||||
},
|
||||
/**
|
||||
* 选择器单级父类型
|
||||
@@ -70,7 +70,7 @@ const useNeInfoStore = defineStore('neinfo', {
|
||||
'neName',
|
||||
'neId'
|
||||
);
|
||||
this.neCascaderOtions = options;
|
||||
this.neCascaderOptions = options;
|
||||
|
||||
// 转选择器单级父类型
|
||||
this.neSelectOtions = options.map(item => item);
|
||||
|
||||
@@ -20,7 +20,7 @@ import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
|
||||
const { t } = useI18n();
|
||||
|
||||
/**网元参数 */
|
||||
let neCascaderOtions = ref<Record<string, any>[]>([]);
|
||||
let neCascaderOptions = ref<Record<string, any>[]>([]);
|
||||
|
||||
/**网元类型选择 type,id */
|
||||
let neTypeSelect = ref<string[]>(['', '']);
|
||||
@@ -1068,18 +1068,25 @@ onMounted(() => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
neCascaderOtions.value = useNeInfoStore().getNeCascaderOtions.filter(
|
||||
neCascaderOptions.value = useNeInfoStore().getNeCascaderOptions.filter(
|
||||
(item: any) => {
|
||||
return !['OMC'].includes(item.value);
|
||||
}
|
||||
);
|
||||
if (neCascaderOptions.value.length === 0) {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOtions.value.find(s => s.value === 'AMF');
|
||||
const item = neCascaderOptions.value.find(s => s.value === 'AMF');
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
} else {
|
||||
const info = neCascaderOtions.value[0].children[0];
|
||||
const info = neCascaderOptions.value[0]?.children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
}
|
||||
fnGetParamConfigTopTab();
|
||||
@@ -1110,7 +1117,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-cascader
|
||||
v-model:value="neTypeSelect"
|
||||
:options="neCascaderOtions"
|
||||
:options="neCascaderOptions"
|
||||
:allow-clear="false"
|
||||
@change="fnGetParamConfigTopTab"
|
||||
/>
|
||||
|
||||
@@ -19,7 +19,7 @@ import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||
const { t } = useI18n();
|
||||
|
||||
/**网元参数 */
|
||||
let neCascaderOtions = ref<Record<string, any>[]>([]);
|
||||
let neCascaderOptions = ref<Record<string, any>[]>([]);
|
||||
|
||||
/**网元类型选择 type,id */
|
||||
let neTypeSelect = ref<string[]>(['', '']);
|
||||
@@ -989,18 +989,25 @@ onMounted(() => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
neCascaderOtions.value = useNeInfoStore().getNeCascaderOtions.filter(
|
||||
neCascaderOptions.value = useNeInfoStore().getNeCascaderOptions.filter(
|
||||
(item: any) => {
|
||||
return !['OMC'].includes(item.value);
|
||||
}
|
||||
);
|
||||
if (neCascaderOptions.value.length === 0) {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOtions.value.find(s => s.value === 'AMF');
|
||||
const item = neCascaderOptions.value.find(s => s.value === 'AMF');
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
} else {
|
||||
const info = neCascaderOtions.value[0].children[0];
|
||||
const info = neCascaderOptions.value[0].children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
}
|
||||
fnGetParamConfigTopTab();
|
||||
@@ -1035,7 +1042,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-cascader
|
||||
v-model:value="neTypeSelect"
|
||||
:options="neCascaderOtions"
|
||||
:options="neCascaderOptions"
|
||||
:allow-clear="false"
|
||||
@change="fnGetParamConfigTopTab"
|
||||
/>
|
||||
|
||||
@@ -16,10 +16,11 @@ import { toRaw } from 'vue';
|
||||
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
|
||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||
import { DataNode } from 'ant-design-vue/lib/tree';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
/**网元参数 */
|
||||
let neCascaderOtions = ref<Record<string, any>[]>([]);
|
||||
let neCascaderOptions = ref<Record<string, any>[]>([]);
|
||||
|
||||
/**网元类型选择 type,id */
|
||||
let neTypeSelect = ref<string[]>(['', '']);
|
||||
@@ -1011,35 +1012,40 @@ function fnModalCancel() {
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
useNeInfoStore()
|
||||
.fnNelist()
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
neCascaderOtions.value = useNeInfoStore().getNeCascaderOtions.filter(
|
||||
(item: any) => {
|
||||
return !['OMC'].includes(item.value);
|
||||
}
|
||||
);
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOtions.value.find(s => s.value === 'AMF');
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
} else {
|
||||
const info = neCascaderOtions.value[0].children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
neInfoStore.fnNelist().then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
neCascaderOptions.value = neInfoStore.getNeCascaderOptions.filter(
|
||||
(item: any) => {
|
||||
return !['OMC'].includes(item.value);
|
||||
}
|
||||
fnGetParamConfigTopTab();
|
||||
);
|
||||
if (neCascaderOptions.value.length === 0) {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOptions.value.find(s => s.value === 'AMF');
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
} else {
|
||||
const info = neCascaderOptions.value[0].children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
}
|
||||
fnGetParamConfigTopTab();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1058,7 +1064,7 @@ onMounted(() => {
|
||||
<a-form-item name="neId ">
|
||||
<a-cascader
|
||||
v-model:value="neTypeSelect"
|
||||
:options="neCascaderOtions"
|
||||
:options="neCascaderOptions"
|
||||
:allow-clear="false"
|
||||
@change="fnGetParamConfigTopTab"
|
||||
/>
|
||||
|
||||
@@ -16,10 +16,11 @@ import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import { regExpIPv4, regExpIPv6 } from '@/utils/regular-utils';
|
||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||
import { DataNode } from 'ant-design-vue/lib/tree';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
/**网元参数 */
|
||||
let neCascaderOtions = ref<Record<string, any>[]>([]);
|
||||
let neCascaderOptions = ref<Record<string, any>[]>([]);
|
||||
|
||||
/**网元类型选择 type,id */
|
||||
let neTypeSelect = ref<string[]>(['', '']);
|
||||
@@ -315,17 +316,21 @@ watch(
|
||||
function arrayEdit(rowIndex: Record<string, any>) {
|
||||
const item = arrayState.data.find((s: any) => s.key === rowIndex.value);
|
||||
if (!item) return;
|
||||
|
||||
const from = arrayEditInit(item, arrayState.dataRule);
|
||||
// 处理信息
|
||||
const row: Record<string, any> = {};
|
||||
for (const v of item.record) {
|
||||
for (const v of from.record) {
|
||||
if (Array.isArray(v.array)) {
|
||||
continue;
|
||||
}
|
||||
row[v.name] = Object.assign({}, v);
|
||||
}
|
||||
|
||||
modalState.from = row;
|
||||
modalState.type = 'arrayEdit';
|
||||
modalState.title = `${treeState.selectNode.topDisplay} ${item.title}`;
|
||||
modalState.key = item.key;
|
||||
modalState.data = item.record.filter((v: any) => !Array.isArray(v.array));
|
||||
modalState.title = `${treeState.selectNode.topDisplay} ${from.title}`;
|
||||
modalState.key = from.key;
|
||||
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
|
||||
modalState.visible = true;
|
||||
|
||||
// 关闭嵌套
|
||||
@@ -636,17 +641,21 @@ function arrayChildExpandClose() {
|
||||
function arrayChildEdit(rowIndex: Record<string, any>) {
|
||||
const item = arrayChildState.data.find((s: any) => s.key === rowIndex.value);
|
||||
if (!item) return;
|
||||
|
||||
const from = arrayEditInit(item, arrayChildState.dataRule);
|
||||
// 处理信息
|
||||
const row: Record<string, any> = {};
|
||||
for (const v of item.record) {
|
||||
for (const v of from.record) {
|
||||
if (Array.isArray(v.array)) {
|
||||
continue;
|
||||
}
|
||||
row[v.name] = Object.assign({}, v);
|
||||
}
|
||||
|
||||
modalState.from = row;
|
||||
modalState.type = 'arrayChildEdit';
|
||||
modalState.title = `${arrayChildState.title} ${item.title}`;
|
||||
modalState.key = item.key;
|
||||
modalState.data = item.record.filter((v: any) => !Array.isArray(v.array));
|
||||
modalState.title = `${arrayChildState.title} ${from.title}`;
|
||||
modalState.key = from.key;
|
||||
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
|
||||
modalState.visible = true;
|
||||
}
|
||||
|
||||
@@ -813,87 +822,74 @@ function arrayChildAddOk(from: Record<string, any>) {
|
||||
});
|
||||
}
|
||||
|
||||
/**多列表编辑行数据初始化 */
|
||||
function arrayEditInit(data: Record<string, any>, dataRule: any) {
|
||||
const dataFrom = data.record;
|
||||
const ruleFrom = Object.assign({}, JSON.parse(JSON.stringify(dataRule)));
|
||||
for (const row of ruleFrom.record) {
|
||||
// 子嵌套的不初始
|
||||
if (row.array) {
|
||||
row.value = [];
|
||||
continue;
|
||||
}
|
||||
// 查找项的值
|
||||
const item = dataFrom.find((s: any) => s.name === row.name);
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
// 根据规则类型转值
|
||||
if (['enum', 'int'].includes(row.type)) {
|
||||
row.value = Number(item.value);
|
||||
} else if ('bool' === row.type) {
|
||||
row.value = Boolean(item.value);
|
||||
} else {
|
||||
row.value = item.value;
|
||||
}
|
||||
}
|
||||
ruleFrom.key = data.key;
|
||||
ruleFrom.title = data.title;
|
||||
return ruleFrom;
|
||||
}
|
||||
|
||||
/**多列表新增行数据初始化 */
|
||||
function arrayAddInit(data: any[], dataRule: any) {
|
||||
const len = data.length;
|
||||
let lastItme: Record<string, any> = {};
|
||||
let newIndex = 0;
|
||||
// 无数据时生成临时记录
|
||||
if (len === 0) {
|
||||
lastItme = dataRule;
|
||||
} else {
|
||||
lastItme = data[len - 1];
|
||||
// 有数据时取得最后的index
|
||||
let dataLastIndex = 0;
|
||||
if (data.length !== 0) {
|
||||
const lastFrom = Object.assign({}, JSON.parse(JSON.stringify(data.at(-1))));
|
||||
if (lastFrom.record.length > 0) {
|
||||
dataLastIndex = parseInt(lastFrom.key);
|
||||
dataLastIndex += 1;
|
||||
}
|
||||
}
|
||||
const from = Object.assign({}, JSON.parse(JSON.stringify(lastItme)));
|
||||
for (const row of from.record) {
|
||||
const value = row.value;
|
||||
|
||||
const ruleFrom = Object.assign({}, JSON.parse(JSON.stringify(dataRule)));
|
||||
for (const row of ruleFrom.record) {
|
||||
// 子嵌套的不初始
|
||||
if (row.array) {
|
||||
row.value = [];
|
||||
continue;
|
||||
}
|
||||
// index值
|
||||
if (row.name === 'index') {
|
||||
if (value !== '') {
|
||||
newIndex = parseInt(value) + 1;
|
||||
}
|
||||
let newIndex = dataLastIndex !== 0 ? dataLastIndex : parseInt(row.value);
|
||||
if (isNaN(newIndex)) {
|
||||
newIndex = 0;
|
||||
}
|
||||
row.value = newIndex;
|
||||
from.key = newIndex;
|
||||
from.title = `Index-${newIndex}`;
|
||||
ruleFrom.key = newIndex;
|
||||
ruleFrom.title = `Index-${newIndex}`;
|
||||
continue;
|
||||
}
|
||||
// 子嵌套的不初始
|
||||
if (row.array) {
|
||||
row.value = null;
|
||||
continue;
|
||||
// 根据规则类型转值
|
||||
if (['enum', 'int'].includes(row.type)) {
|
||||
row.value = Number(row.value);
|
||||
}
|
||||
const type = row.type;
|
||||
const filter = row.filter;
|
||||
switch (type) {
|
||||
case 'int':
|
||||
if (filter && filter.indexOf('~') !== -1) {
|
||||
const filterArr = filter.split('~');
|
||||
const minInt = parseInt(filterArr[0]);
|
||||
row.value = minInt;
|
||||
} else {
|
||||
row.value = 0;
|
||||
}
|
||||
break;
|
||||
case 'enum':
|
||||
if (filter && filter.indexOf('{') === 0) {
|
||||
let filterJson: Record<string, any> = {};
|
||||
try {
|
||||
filterJson = JSON.parse(filter); //string---json
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
row.value = Object.keys(filterJson)[0];
|
||||
} else {
|
||||
row.value = '0';
|
||||
}
|
||||
break;
|
||||
case 'bool':
|
||||
if (filter && filter.indexOf('{') === 0) {
|
||||
let filterJson: Record<string, any> = {};
|
||||
try {
|
||||
filterJson = JSON.parse(filter); //string---json
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
row.value = Object.keys(filterJson)[0];
|
||||
} else {
|
||||
row.value = false;
|
||||
}
|
||||
break;
|
||||
case 'ipv4':
|
||||
case 'ipv6':
|
||||
case 'regex':
|
||||
default:
|
||||
row.value = '';
|
||||
break;
|
||||
if ('bool' === row.type) {
|
||||
row.value = Boolean(row.value);
|
||||
}
|
||||
}
|
||||
|
||||
return from;
|
||||
return ruleFrom;
|
||||
}
|
||||
|
||||
/**规则校验 */
|
||||
@@ -1093,42 +1089,47 @@ function fnModalCancel() {
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
useNeInfoStore()
|
||||
.fnNelist()
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
neCascaderOtions.value = useNeInfoStore().getNeCascaderOtions.filter(
|
||||
(item: any) => {
|
||||
return !['OMC'].includes(item.value);
|
||||
}
|
||||
);
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOtions.value.find(s => s.value === 'UPF');
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
} else {
|
||||
const info = neCascaderOtions.value[0].children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
neInfoStore.fnNelist().then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
neCascaderOptions.value = neInfoStore.getNeCascaderOptions.filter(
|
||||
(item: any) => {
|
||||
return !['OMC'].includes(item.value);
|
||||
}
|
||||
fnGetParamConfigTopTab();
|
||||
);
|
||||
if (neCascaderOptions.value.length === 0) {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOptions.value.find(s => s.value === 'UPF');
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
} else {
|
||||
const info = neCascaderOptions.value[0].children[0];
|
||||
neTypeSelect.value = [info.neType, info.neId];
|
||||
}
|
||||
fnGetParamConfigTopTab();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageContainer>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="6">
|
||||
<a-col :lg="6" :md="6" :xs="24" style="margin-bottom: 24px">
|
||||
<!-- 网元类型 -->
|
||||
<a-card
|
||||
size="small"
|
||||
@@ -1140,7 +1141,7 @@ onMounted(() => {
|
||||
<a-form-item name="neId ">
|
||||
<a-cascader
|
||||
v-model:value="neTypeSelect"
|
||||
:options="neCascaderOtions"
|
||||
:options="neCascaderOptions"
|
||||
:allow-clear="false"
|
||||
@change="fnGetParamConfigTopTab"
|
||||
/>
|
||||
@@ -1156,7 +1157,7 @@ onMounted(() => {
|
||||
</a-form>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="18">
|
||||
<a-col :lg="18" :md="18" :xs="24">
|
||||
<a-card
|
||||
size="small"
|
||||
:bordered="false"
|
||||
@@ -1309,19 +1310,20 @@ onMounted(() => {
|
||||
v-model:expanded-row-keys="arrayState.arrayChildExpandKeys"
|
||||
>
|
||||
<!-- 多列新增操作 -->
|
||||
<template #title v-if="treeState.selectNode.method !== 'get'">
|
||||
<template #title>
|
||||
<a-space :size="16" align="center">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="arrayAdd()"
|
||||
size="small"
|
||||
v-if="treeState.selectNode.method !== 'get'"
|
||||
>
|
||||
<template #icon> <PlusOutlined /> </template>
|
||||
{{ t('common.addText') }}
|
||||
</a-button>
|
||||
<TableColumnsDnd
|
||||
type="ghost"
|
||||
:columns="[...arrayState.columns]"
|
||||
:columns="treeState.selectNode.method === 'get' ? [...arrayState.columns.filter((s:any)=>s.key !== 'index')] : arrayState.columns"
|
||||
v-model:columns-dnd="arrayState.columnsDnd"
|
||||
></TableColumnsDnd>
|
||||
</a-space>
|
||||
@@ -1366,7 +1368,7 @@ onMounted(() => {
|
||||
</a-button>
|
||||
<!--特殊字段拓展显示-->
|
||||
<span v-if="text.name === 'dnnList'">
|
||||
({{ text.value.map((s: any) => s.dnn).join() }})
|
||||
({{ text.value?.map((s: any) => s.dnn).join() }})
|
||||
</span>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import useI18n from '@/hooks/useI18n';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
/**查询参数 */
|
||||
@@ -129,7 +130,7 @@ function fnTableSize({ key }: MenuInfo) {
|
||||
function fnGetList(pageNum?: number) {
|
||||
if (tableState.loading) return;
|
||||
tableState.loading = true;
|
||||
if(pageNum){
|
||||
if (pageNum) {
|
||||
queryParams.pageNum = pageNum;
|
||||
}
|
||||
listLicense(toRaw(queryParams)).then(res => {
|
||||
@@ -267,7 +268,10 @@ function fnBeforeUploadFile(file: FileType) {
|
||||
const fileName = file.name;
|
||||
const suff = fileName.substring(fileName.lastIndexOf('.'));
|
||||
if (!['.ini'].includes(suff)) {
|
||||
message.error(t('views.configManage.softwareManage.onlyAble',{fileText:'(.ini)'}), 3);
|
||||
message.error(
|
||||
t('views.configManage.softwareManage.onlyAble', { fileText: '(.ini)' }),
|
||||
3
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -287,19 +291,17 @@ function fnUploadFile(up: UploadRequestOption) {
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
useNeInfoStore()
|
||||
.fnNelist()
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
// 获取列表数据
|
||||
fnGetList();
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('views.configManage.softwareManage.nullData'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
});
|
||||
neInfoStore.fnNelist().then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
// 获取列表数据
|
||||
fnGetList();
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('views.configManage.softwareManage.nullData'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -320,7 +322,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-auto-complete
|
||||
v-model:value="queryParams.neType"
|
||||
:options="useNeInfoStore().getNeSelectOtions"
|
||||
:options="neInfoStore.getNeSelectOtions"
|
||||
allow-clear
|
||||
:placeholder="t('views.configManage.license.neTypePlease')"
|
||||
/>
|
||||
@@ -425,10 +427,7 @@ onMounted(() => {
|
||||
@ok="fnModalOk"
|
||||
@cancel="fnModalCancel"
|
||||
>
|
||||
<a-form
|
||||
name="modalStateFrom"
|
||||
layout="horizontal"
|
||||
>
|
||||
<a-form name="modalStateFrom" layout="horizontal">
|
||||
<a-form-item
|
||||
:label="t('views.configManage.license.neType')"
|
||||
name="neType"
|
||||
@@ -436,7 +435,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-cascader
|
||||
v-model:value="modalState.from.neType"
|
||||
:options="useNeInfoStore().getNeCascaderOtions"
|
||||
:options="useNeInfoStore().getNeCascaderOptions"
|
||||
:allow-clear="false"
|
||||
:placeholder="t('views.configManage.license.neTypePlease')"
|
||||
/>
|
||||
|
||||
@@ -448,7 +448,7 @@ const modalStateFrom = Form.useForm(
|
||||
],
|
||||
comment: [
|
||||
{
|
||||
required: true,
|
||||
required: false,
|
||||
message: t('views.configManage.softwareManage.updateCommentPlease'),
|
||||
},
|
||||
],
|
||||
@@ -529,10 +529,19 @@ function fnBeforeUploadFile(file: FileType) {
|
||||
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);
|
||||
|
||||
message.error(
|
||||
t('views.configManage.softwareManage.onlyAble', {
|
||||
fileText: '(.deb、.rpm)',
|
||||
}),
|
||||
3
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// 根据给定的软件名取版本号 ims-r2.2312.8_u18.deb
|
||||
const nameArr = fileName.split('.')
|
||||
if(nameArr.length > 3) {
|
||||
modalState.from.version = nameArr[1]
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -552,7 +561,10 @@ function fnBeforeUploadCms(file: FileType) {
|
||||
const fileName = file.name;
|
||||
const suff = fileName.substring(fileName.lastIndexOf('.'));
|
||||
if (!['.cms'].includes(suff)) {
|
||||
message.error(t('views.configManage.softwareManage.onlyAble',{fileText:'(.cms)'}), 3);
|
||||
message.error(
|
||||
t('views.configManage.softwareManage.onlyAble', { fileText: '(.cms)' }),
|
||||
3
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -18,11 +18,12 @@ import {
|
||||
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();
|
||||
const { t, currentLocale } = useI18n();
|
||||
|
||||
/**字典数据 */
|
||||
let dict: {
|
||||
@@ -41,6 +42,9 @@ let dict: {
|
||||
activeAlarmSeverity: [],
|
||||
});
|
||||
|
||||
/**表格字段列排序 */
|
||||
let tableColumnsDnd = ref<ColumnsType>([]);
|
||||
|
||||
/**记录开始结束时间 */
|
||||
let queryRangePicker = ref<[string, string]>(['', '']);
|
||||
|
||||
@@ -233,9 +237,6 @@ let tableColumns: ColumnsType = [
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
/**帮助文档表格字段列 */
|
||||
let alarmTableColumns: ColumnsType = [
|
||||
{
|
||||
@@ -246,19 +247,19 @@ let alarmTableColumns: ColumnsType = [
|
||||
},
|
||||
{
|
||||
title: t('views.faultManage.activeAlarm.locationInfo'),
|
||||
dataIndex: 'alarmInfo',
|
||||
dataIndex: 'alarmInfo',
|
||||
align: 'center',
|
||||
width: 5,
|
||||
},
|
||||
{
|
||||
title: t('views.faultManage.activeAlarm.addInfo'),
|
||||
dataIndex:'helpInfo',
|
||||
dataIndex: 'helpInfo',
|
||||
align: 'center',
|
||||
width: 8,
|
||||
},
|
||||
{
|
||||
title: t('views.faultManage.activeAlarm.alarmType'),
|
||||
dataIndex: 'alarmType',
|
||||
dataIndex: 'alarmType',
|
||||
align: 'center',
|
||||
width: 5,
|
||||
},
|
||||
@@ -294,7 +295,7 @@ let alarmTableColumns: ColumnsType = [
|
||||
},
|
||||
{
|
||||
title: t('views.faultManage.activeAlarm.objectNf'),
|
||||
dataIndex:'objNf',
|
||||
dataIndex: 'objNf',
|
||||
align: 'center',
|
||||
width: 2,
|
||||
},
|
||||
@@ -416,14 +417,12 @@ function fnModalVisibleByVive(row: Record<string, any>) {
|
||||
modalState.visibleByView = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** 告警帮助文档详细信息 */
|
||||
function fnModalVisibleBy(code: string) {
|
||||
modalState.helpShowView = false;
|
||||
const lang=currentLocale.value.split('_')[0];
|
||||
modalState.title=t('views.faultManage.activeAlarm.helpFile');
|
||||
readLoalXlsx(lang,code)
|
||||
const lang = currentLocale.value.split('_')[0];
|
||||
modalState.title = t('views.faultManage.activeAlarm.helpFile');
|
||||
readLoalXlsx(lang, code)
|
||||
.then(res => {
|
||||
alarmTableState.data = res;
|
||||
modalState.helpShowView = true;
|
||||
@@ -438,7 +437,7 @@ function fnModalVisibleBy(code: string) {
|
||||
function fnModalOk() {
|
||||
modalState.confirmLoading = true;
|
||||
const from = toRaw(modalState.from);
|
||||
if (from.ackState) {
|
||||
if (from.ackState === '1') {
|
||||
message.error({
|
||||
content: t('views.faultManage.activeAlarm.ackError'),
|
||||
duration: 3,
|
||||
@@ -661,7 +660,7 @@ function fnModalCancel() {
|
||||
modalState.visibleByEdit = false;
|
||||
modalState.visibleByView = false;
|
||||
modalState.visibleByShowSet = false;
|
||||
modalState.helpShowView=false;
|
||||
modalState.helpShowView = false;
|
||||
}
|
||||
|
||||
/**查询列表, pageNum初始页数 */
|
||||
@@ -850,7 +849,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="fnCancelConfirm()"
|
||||
@@ -890,12 +889,12 @@ onMounted(() => {
|
||||
<template #icon> <export-outlined /> </template>
|
||||
{{ t('views.faultManage.activeAlarm.exportAll') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -935,14 +934,18 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
<TableColumnsDnd
|
||||
:columns="tableColumns"
|
||||
v-model:columns-dnd="tableColumnsDnd"
|
||||
></TableColumnsDnd>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
<a-table
|
||||
class="table"
|
||||
row-key="id"
|
||||
:columns="tableColumns"
|
||||
:columns="tableColumnsDnd"
|
||||
:loading="tableState.loading"
|
||||
:data-source="tableState.data"
|
||||
:size="tableState.size"
|
||||
@@ -1006,7 +1009,6 @@ onMounted(() => {
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
|
||||
<!-- 帮助文档 -->
|
||||
<a-modal
|
||||
width="100%"
|
||||
@@ -1027,7 +1029,7 @@ onMounted(() => {
|
||||
:data-source="alarmTableState.data"
|
||||
:size="alarmTableState.size"
|
||||
:pagination="false"
|
||||
:scroll="{ x: 1700, y: 560 }"
|
||||
:scroll="{ x: 1700, y: 560 }"
|
||||
>
|
||||
</a-table>
|
||||
</a-modal>
|
||||
|
||||
@@ -14,6 +14,8 @@ import { PieChart } from 'echarts/charts';
|
||||
import { LabelLayout } from 'echarts/features';
|
||||
import { useRoute } from 'vue-router';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useDictStore from '@/store/modules/dict';
|
||||
const { getDict } = useDictStore();
|
||||
const appStore = useAppStore();
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
@@ -28,6 +30,13 @@ echarts.use([
|
||||
LabelLayout,
|
||||
]);
|
||||
|
||||
/**字典数据 */
|
||||
/**用户性别字典 */
|
||||
let indexColor = ref<DictType[]>([
|
||||
{ label: 'normal', value: 'normal', elTagType: '', elTagClass: '#91cc75' },
|
||||
{ label: 'abnormal', value: 'abnormal', elTagType: '', elTagClass: '#ee6666' },
|
||||
]);
|
||||
|
||||
/**表格字段列 */
|
||||
//customRender(){} ----单元格处理
|
||||
let tableColumns: ColumnsType = [
|
||||
@@ -92,7 +101,7 @@ let tableState: TabeStateType = reactive({
|
||||
/**表格状态 */
|
||||
let nfInfo: any = reactive({
|
||||
obj: 'OMC',
|
||||
version: '2.2311.8',
|
||||
version: '2.2312.8',
|
||||
status: t('views.index.normal'),
|
||||
number: '',
|
||||
outTimeDate: '',
|
||||
@@ -141,9 +150,9 @@ let pronInfo: nfStateType = reactive({
|
||||
});
|
||||
|
||||
/**查询网元状态列表 */
|
||||
function fnGetList() {
|
||||
function fnGetList(one: boolean) {
|
||||
if (tableState.loading) return;
|
||||
tableState.loading = true;
|
||||
one && (tableState.loading = true);
|
||||
listMain().then(res => {
|
||||
tableState.data = res;
|
||||
tableState.loading = false;
|
||||
@@ -174,6 +183,10 @@ function fnGetList() {
|
||||
orient: 'vertical',
|
||||
left: 'left',
|
||||
},
|
||||
color: [
|
||||
'' + indexColor.value[0]['elTagClass'],
|
||||
'' + indexColor.value[1]['elTagClass'],
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: t('views.index.realNeStatus'),
|
||||
@@ -392,9 +405,15 @@ function fnLocale() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getDict('index_status').then(res => {
|
||||
if (res.length > 0) {
|
||||
indexColor.value = res;
|
||||
}
|
||||
});
|
||||
//console.log(indexColor)
|
||||
fnLocale();
|
||||
fnGetList();
|
||||
timer = setInterval(fnGetList, 10000); // 每隔10秒执行一次
|
||||
fnGetList(true);
|
||||
timer = setInterval(() => fnGetList(false), 10000); // 每隔10秒执行一次
|
||||
});
|
||||
|
||||
// 在组件卸载之前清除定时器
|
||||
|
||||
346
src/views/logManage/neFile/index.vue
Normal file
@@ -0,0 +1,346 @@
|
||||
<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 { ColumnsType } from 'ant-design-vue/lib/table';
|
||||
import { parseDateToStr } from '@/utils/date-utils';
|
||||
import { getNeFile, listNeFiles } from '@/api/tool/neFile';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { Modal, message } from 'ant-design-vue/lib';
|
||||
import saveAs from 'file-saver';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
/**网元参数 */
|
||||
let neType = ref([]);
|
||||
/**下载触发等待 */
|
||||
let loading = ref(false);
|
||||
/**访问路径 */
|
||||
let nePathArr = ref<string[]>([]);
|
||||
|
||||
/**查询参数 */
|
||||
let queryParams = reactive({
|
||||
/**网元类型 */
|
||||
neType: '',
|
||||
neId: '',
|
||||
/**读取路径 */
|
||||
path: '',
|
||||
/**前缀过滤 */
|
||||
search: '',
|
||||
/**当前页数 */
|
||||
pageNum: 1,
|
||||
/**每页条数 */
|
||||
pageSize: 20,
|
||||
});
|
||||
|
||||
/**表格状态类型 */
|
||||
type TabeStateType = {
|
||||
/**加载等待 */
|
||||
loading: boolean;
|
||||
/**紧凑型 */
|
||||
size: SizeType;
|
||||
/**记录数据 */
|
||||
data: object[];
|
||||
};
|
||||
|
||||
/**表格状态 */
|
||||
let tableState: TabeStateType = reactive({
|
||||
loading: false,
|
||||
size: 'small',
|
||||
data: [],
|
||||
});
|
||||
|
||||
/**表格字段列 */
|
||||
let tableColumns: ColumnsType = [
|
||||
{
|
||||
title: t('views.logManage.neFile.fileMode'),
|
||||
dataIndex: 'fileMode',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: t('views.logManage.neFile.owner'),
|
||||
dataIndex: 'owner',
|
||||
align: 'left',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: t('views.logManage.neFile.group'),
|
||||
dataIndex: 'group',
|
||||
align: 'left',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: t('views.logManage.neFile.size'),
|
||||
dataIndex: 'size',
|
||||
align: 'left',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: t('views.logManage.neFile.modifiedTime'),
|
||||
dataIndex: 'modifiedTime',
|
||||
align: 'left',
|
||||
customRender(opt) {
|
||||
if (!opt.value) return '';
|
||||
return parseDateToStr(opt.value * 1000);
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: t('views.logManage.neFile.fileName'),
|
||||
dataIndex: 'fileName',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('common.operate'),
|
||||
key: 'fileName',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
},
|
||||
];
|
||||
|
||||
/**表格分页器参数 */
|
||||
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 fnDownloadFile(row: Record<string, any>) {
|
||||
if (loading.value) return;
|
||||
Modal.confirm({
|
||||
title: t('common.tipTitle'),
|
||||
content: t('views.logManage.neFile.downTip', { fileName: row.fileName }),
|
||||
onOk() {
|
||||
loading.value = true;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
getNeFile({
|
||||
neType: queryParams.neType,
|
||||
neId: queryParams.neId,
|
||||
path: queryParams.path,
|
||||
fileName: row.fileName,
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success({
|
||||
content: t('common.msgSuccess', {
|
||||
msg: t('common.downloadText'),
|
||||
}),
|
||||
duration: 2,
|
||||
});
|
||||
saveAs(res.data, `${row.fileName}`);
|
||||
} else {
|
||||
message.error({
|
||||
content: t('views.logManage.neFile.downTipErr'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
loading.value = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**进入目录 */
|
||||
function fnDirCD(dir: string, index?: number) {
|
||||
if (index === undefined) {
|
||||
nePathArr.value.push(dir);
|
||||
queryParams.search = '';
|
||||
fnGetList(1);
|
||||
return;
|
||||
}
|
||||
if (index === 0) {
|
||||
const neType = queryParams.neType;
|
||||
if (neType === 'IMS') {
|
||||
nePathArr.value = ['/var/log/ims'];
|
||||
queryParams.search = '';
|
||||
} else {
|
||||
nePathArr.value = ['/var/log'];
|
||||
queryParams.search = neType.toLowerCase();
|
||||
}
|
||||
fnGetList(1);
|
||||
} else {
|
||||
nePathArr.value = nePathArr.value.slice(0, index + 1);
|
||||
queryParams.search = '';
|
||||
fnGetList(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**网元类型选择对应修改 */
|
||||
function fnNeChange(keys: any, _: any) {
|
||||
// 不是同类型时需要重新加载
|
||||
if (Array.isArray(keys) && queryParams.neType !== keys[0]) {
|
||||
const neType = keys[0];
|
||||
queryParams.neType = neType;
|
||||
queryParams.neId = keys[1];
|
||||
if (neType === 'IMS') {
|
||||
nePathArr.value = ['/var/log/ims'];
|
||||
} else {
|
||||
nePathArr.value = ['/var/log'];
|
||||
queryParams.search = neType.toLowerCase();
|
||||
}
|
||||
fnGetList(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**查询备份信息列表, pageNum初始页数 */
|
||||
function fnGetList(pageNum?: number) {
|
||||
if (queryParams.neId === '') {
|
||||
message.warning({
|
||||
content: t('views.logManage.neFile.neTypePlease'),
|
||||
duration: 2,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (tableState.loading) return;
|
||||
tableState.loading = true;
|
||||
if (pageNum) {
|
||||
queryParams.pageNum = pageNum;
|
||||
}
|
||||
queryParams.path = nePathArr.value.join('/');
|
||||
listNeFiles(toRaw(queryParams)).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
||||
tablePagination.total = res.total;
|
||||
tableState.data = res.rows;
|
||||
}
|
||||
tableState.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
neInfoStore.fnNelist().then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length === 0) {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageContainer>
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="8" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.logManage.neFile.neType')"
|
||||
name="neType"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<a-cascader
|
||||
v-model:value="neType"
|
||||
:options="neInfoStore.getNeCascaderOptions"
|
||||
@change="fnNeChange"
|
||||
:allow-clear="false"
|
||||
:placeholder="t('views.logManage.neFile.neTypePlease')"
|
||||
:disabled="loading || tableState.loading"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="16" :md="18" :xs="24" v-if="nePathArr.length > 0">
|
||||
<a-form-item
|
||||
:label="t('views.logManage.neFile.nePath')"
|
||||
name="configName"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<a-breadcrumb>
|
||||
<a-breadcrumb-item
|
||||
v-for="(path, index) in nePathArr"
|
||||
:key="path"
|
||||
@click="fnDirCD(path, index)"
|
||||
>
|
||||
{{ path }}
|
||||
</a-breadcrumb-item>
|
||||
</a-breadcrumb>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.reloadText') }}</template>
|
||||
<a-button type="text" @click.prevent="fnGetList()">
|
||||
<template #icon><ReloadOutlined /></template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
<a-table
|
||||
class="table"
|
||||
row-key="fileName"
|
||||
:columns="tableColumns"
|
||||
:loading="tableState.loading"
|
||||
:data-source="tableState.data"
|
||||
:size="tableState.size"
|
||||
:pagination="tablePagination"
|
||||
:scroll="{ x: 800 }"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'fileName'">
|
||||
<a-space :size="8" align="center">
|
||||
<a-button
|
||||
type="link"
|
||||
@click.prevent="fnDownloadFile(record)"
|
||||
v-if="record.fileType === 'file'"
|
||||
>
|
||||
<template #icon><DownloadOutlined /></template>
|
||||
{{ t('common.downloadText') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
type="link"
|
||||
@click.prevent="fnDirCD(record.fileName)"
|
||||
v-if="record.fileType === 'dir'"
|
||||
>
|
||||
<template #icon><FolderOutlined /></template>
|
||||
{{ t('views.logManage.neFile.dirCd') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -8,8 +8,8 @@ import { useRouter, useRoute } from 'vue-router';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { toRaw } from 'vue';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { sessionGet } from '@/utils/cache-session-utils';
|
||||
const { t, changeLocale, optionsLocale } = useI18n();
|
||||
import { parseUrlPath } from '@/plugins/file-static-url';
|
||||
const { t, changeLocale, optionsLocale, currentLocale } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
@@ -87,9 +87,25 @@ function fnGetCaptcha() {
|
||||
});
|
||||
}
|
||||
|
||||
// LOGO地址
|
||||
const logoUrl = computed(() => {
|
||||
let url =
|
||||
appStore.logoType === 'brand'
|
||||
? parseUrlPath(appStore.filePathBrand)
|
||||
: parseUrlPath(appStore.filePathIcon);
|
||||
|
||||
if (url.indexOf('{language}') === -1) {
|
||||
return url;
|
||||
}
|
||||
// 语言参数替换
|
||||
const local = currentLocale.value;
|
||||
const lang = local.split('_')[0];
|
||||
return url.replace('{language}', lang);
|
||||
});
|
||||
|
||||
// 判断是否有背景地址
|
||||
const calcBG = computed(() => {
|
||||
const bgURL = appStore.getLoginBackground;
|
||||
const bgURL = parseUrlPath(appStore.loginBackground);
|
||||
if (bgURL && bgURL !== '#') {
|
||||
return {
|
||||
backgroundImage: `url(${bgURL})`,
|
||||
@@ -116,9 +132,6 @@ onMounted(() => {
|
||||
fnGetCaptcha();
|
||||
});
|
||||
|
||||
// 兼容旧前端可改配置文件
|
||||
const i18nDisable = sessionGet('i18nDisable') === 'false';
|
||||
|
||||
/**改变多语言 */
|
||||
function fnChangeLocale(e: any) {
|
||||
changeLocale(e.key);
|
||||
@@ -137,19 +150,11 @@ function fnChangeLocale(e: any) {
|
||||
|
||||
<header class="header">
|
||||
<template v-if="appStore.logoType === 'icon'">
|
||||
<img
|
||||
:src="appStore.getLOGOIcon"
|
||||
class="logo-icon"
|
||||
:alt="appStore.appName"
|
||||
/>
|
||||
<img :src="logoUrl" class="logo-icon" :alt="appStore.appName" />
|
||||
<span class="title">{{ appStore.appName }}</span>
|
||||
</template>
|
||||
<template v-if="appStore.logoType === 'brand'">
|
||||
<img
|
||||
:src="appStore.getLOGOBrand"
|
||||
class="logo-brand"
|
||||
:alt="appStore.appName"
|
||||
/>
|
||||
<img :src="logoUrl" class="logo-brand" :alt="appStore.appName" />
|
||||
</template>
|
||||
</header>
|
||||
|
||||
@@ -274,7 +279,7 @@ function fnChangeLocale(e: any) {
|
||||
justify="space-between"
|
||||
align="middle"
|
||||
style="margin-top: 18px"
|
||||
v-if="!i18nDisable"
|
||||
v-if="appStore.i18nOpen"
|
||||
>
|
||||
<a-col :offset="18" :span="6">
|
||||
<a-dropdown :trigger="['click', 'hover']">
|
||||
@@ -374,6 +379,7 @@ function fnChangeLocale(e: any) {
|
||||
}
|
||||
.logo-brand {
|
||||
height: 48px;
|
||||
width: 174px;
|
||||
vertical-align: top;
|
||||
border-style: none;
|
||||
border-radius: 2px;
|
||||
|
||||
@@ -10,6 +10,7 @@ import useI18n from '@/hooks/useI18n';
|
||||
import { getMMLByNE, sendMMlByNE } from '@/api/mmlManage/neOperate';
|
||||
import { uploadFileToNE } from '@/api/tool/file';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
/**网元参数 */
|
||||
@@ -63,9 +64,30 @@ let state: StateType = reactive({
|
||||
function fnTreeSelect(_: any, info: any) {
|
||||
state.mmlSelect = info.node.dataRef;
|
||||
state.from = {};
|
||||
// 遍历判断是否有初始value
|
||||
if (Array.isArray(state.mmlSelect.param)) {
|
||||
for (const param of state.mmlSelect.param) {
|
||||
if (typeof param.value !== 'undefined' && param.value != '') {
|
||||
const valueType = param.type;
|
||||
if (['enum', 'int'].includes(valueType)) {
|
||||
state.from[param.name] = Number(param.value);
|
||||
} else if (valueType === 'bool') {
|
||||
state.from[param.name] = Boolean(param.value);
|
||||
} else {
|
||||
state.from[param.name] = param.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.autoCompleteValue =
|
||||
`${state.mmlSelect.operation} ${state.mmlSelect.object}`.trim();
|
||||
// state.mmlCmdLog = '';
|
||||
// 回到顶部
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth', // 平滑滚动到顶部,如果不需要平滑效果可以将此行代码删除
|
||||
});
|
||||
}
|
||||
|
||||
/**清空控制台日志 */
|
||||
@@ -151,16 +173,17 @@ function fnSendMML() {
|
||||
}
|
||||
|
||||
// 发送
|
||||
state.mmlCmdLog += `${cmdArr.join('\n')}\n`;
|
||||
state.from.sendLoading = true;
|
||||
const [neType, neId] = state.neType;
|
||||
sendMMlByNE(neType, neId, cmdArr).then(res => {
|
||||
state.from.sendLoading = false;
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
let resultArr = res.data;
|
||||
for (const str of resultArr) {
|
||||
for (let i = 0; i < resultArr.length; i++) {
|
||||
const str = resultArr[i];
|
||||
const logStr = str.replace(/(\r\n|\n)/g, '\n');
|
||||
state.mmlCmdLog += `${logStr}\n`;
|
||||
const cmdStr = cmdArr[i];
|
||||
state.mmlCmdLog += `${cmdStr}\n${logStr}\n`;
|
||||
}
|
||||
} else {
|
||||
state.mmlCmdLog += `${res.msg}\n`;
|
||||
@@ -184,7 +207,7 @@ function fnUpload(up: UploadRequestOption, name: string) {
|
||||
message.success(t('views.mmlManage.uploadFileOk'), 3);
|
||||
state.from[name] = res.data;
|
||||
} else {
|
||||
message.error(res.msg, 3);
|
||||
message.error(t('views.mmlManage.uploadFileErr'), 3);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -454,42 +477,47 @@ function fnAutoCompleteChange(value: any, _: any) {
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
useNeInfoStore()
|
||||
.fnNelist()
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
neCascaderOptions.value = useNeInfoStore().getNeCascaderOtions.filter(
|
||||
(item: any) => {
|
||||
return !['OMC'].includes(item.value);
|
||||
}
|
||||
);
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOptions.value.find(s => s.value === 'AMF');
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
state.neType = [info.neType, info.neId];
|
||||
} else {
|
||||
const info = neCascaderOptions.value[0].children[0];
|
||||
state.neType = [info.neType, info.neId];
|
||||
neInfoStore.fnNelist().then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
neCascaderOptions.value = neInfoStore.getNeCascaderOptions.filter(
|
||||
(item: any) => {
|
||||
return !['OMC'].includes(item.value);
|
||||
}
|
||||
fnGetList();
|
||||
);
|
||||
if (neCascaderOptions.value.length === 0) {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOptions.value.find(s => s.value === 'AMF');
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
state.neType = [info.neType, info.neId];
|
||||
} else {
|
||||
const info = neCascaderOptions.value[0].children[0];
|
||||
state.neType = [info.neType, info.neId];
|
||||
}
|
||||
fnGetList();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageContainer>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="6">
|
||||
<a-col :lg="6" :md="6" :xs="24" style="margin-bottom: 24px">
|
||||
<!-- 命令导航 -->
|
||||
<a-card
|
||||
size="small"
|
||||
@@ -517,7 +545,7 @@ onMounted(() => {
|
||||
</a-form>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="18">
|
||||
<a-col :lg="18" :md="18" :xs="24">
|
||||
<!-- 命令参数输入 -->
|
||||
<a-card size="small" :bordered="false">
|
||||
<template #title>
|
||||
@@ -557,7 +585,7 @@ onMounted(() => {
|
||||
</template>
|
||||
|
||||
<a-form
|
||||
layout="vertical"
|
||||
layout="horizontal"
|
||||
autocomplete="off"
|
||||
:validate-on-rule-change="false"
|
||||
:validateTrigger="[]"
|
||||
@@ -575,8 +603,15 @@ onMounted(() => {
|
||||
<a-textarea :placeholder="t('common.ipnutPlease')" auto-size />
|
||||
</a-auto-complete>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<template v-if="state.mmlSelect.operation && state.mmlSelect.param">
|
||||
<template v-if="state.mmlSelect.operation && state.mmlSelect.param">
|
||||
<a-form
|
||||
layout="vertical"
|
||||
autocomplete="off"
|
||||
:validate-on-rule-change="false"
|
||||
:validateTrigger="[]"
|
||||
>
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.mmlManage.cmdParamPanel') }}
|
||||
</a-divider>
|
||||
@@ -652,8 +687,8 @@ onMounted(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-form>
|
||||
</a-form>
|
||||
</template>
|
||||
</a-card>
|
||||
|
||||
<!-- 命令展示 -->
|
||||
|
||||
@@ -60,9 +60,30 @@ let state: StateType = reactive({
|
||||
function fnTreeSelect(_: any, info: any) {
|
||||
state.mmlSelect = info.node.dataRef;
|
||||
state.from = {};
|
||||
// 遍历判断是否有初始value
|
||||
if (Array.isArray(state.mmlSelect.param)) {
|
||||
for (const param of state.mmlSelect.param) {
|
||||
if (typeof param.value !== 'undefined' && param.value != '') {
|
||||
const valueType = param.type;
|
||||
if (['enum', 'int'].includes(valueType)) {
|
||||
state.from[param.name] = Number(param.value);
|
||||
} else if (valueType === 'bool') {
|
||||
state.from[param.name] = Boolean(param.value);
|
||||
} else {
|
||||
state.from[param.name] = param.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.autoCompleteValue =
|
||||
`${state.mmlSelect.operation} ${state.mmlSelect.object}`.trim();
|
||||
// state.mmlCmdLog = '';
|
||||
// 回到顶部
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth', // 平滑滚动到顶部,如果不需要平滑效果可以将此行代码删除
|
||||
});
|
||||
}
|
||||
|
||||
/**清空控制台日志 */
|
||||
@@ -148,15 +169,16 @@ function fnSendMML() {
|
||||
}
|
||||
|
||||
// 发送
|
||||
state.mmlCmdLog += `${cmdArr.join('\n')}\n`;
|
||||
state.from.sendLoading = true;
|
||||
sendMMlByOMC(state.neId, cmdArr).then(res => {
|
||||
state.from.sendLoading = false;
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
let resultArr = res.data;
|
||||
for (const str of resultArr) {
|
||||
for (let i = 0; i < resultArr.length; i++) {
|
||||
const str = resultArr[i];
|
||||
const logStr = str.replace(/(\r\n|\n)/g, '\n');
|
||||
state.mmlCmdLog += `${logStr}\n`;
|
||||
const cmdStr = cmdArr[i];
|
||||
state.mmlCmdLog += `${cmdStr}\n${logStr}\n`;
|
||||
}
|
||||
} else {
|
||||
state.mmlCmdLog += `${res.msg}\n`;
|
||||
@@ -179,7 +201,7 @@ function fnUpload(up: UploadRequestOption, name: string) {
|
||||
message.success(t('views.mmlManage.uploadFileOk'), 3);
|
||||
state.from[name] = res.data;
|
||||
} else {
|
||||
message.error(res.msg, 3);
|
||||
message.error(t('views.mmlManage.uploadFileErr'), 3);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -465,7 +487,7 @@ onMounted(() => {
|
||||
<template>
|
||||
<PageContainer>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="6">
|
||||
<a-col :lg="6" :md="6" :xs="24" style="margin-bottom: 24px">
|
||||
<!-- 命令导航 -->
|
||||
<a-card
|
||||
size="small"
|
||||
@@ -491,7 +513,7 @@ onMounted(() => {
|
||||
</a-form>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="18">
|
||||
<a-col :lg="18" :md="18" :xs="24">
|
||||
<!-- 命令参数输入 -->
|
||||
<a-card size="small" :bordered="false">
|
||||
<template #title>
|
||||
@@ -531,7 +553,7 @@ onMounted(() => {
|
||||
</template>
|
||||
|
||||
<a-form
|
||||
layout="vertical"
|
||||
layout="horizontal"
|
||||
autocomplete="off"
|
||||
:validate-on-rule-change="false"
|
||||
:validateTrigger="[]"
|
||||
@@ -549,8 +571,15 @@ onMounted(() => {
|
||||
<a-textarea :placeholder="t('common.ipnutPlease')" auto-size />
|
||||
</a-auto-complete>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<template v-if="state.mmlSelect.operation && state.mmlSelect.param">
|
||||
<template v-if="state.mmlSelect.operation && state.mmlSelect.param">
|
||||
<a-form
|
||||
layout="vertical"
|
||||
autocomplete="off"
|
||||
:validate-on-rule-change="false"
|
||||
:validateTrigger="[]"
|
||||
>
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.mmlManage.cmdParamPanel') }}
|
||||
</a-divider>
|
||||
@@ -626,8 +655,8 @@ onMounted(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-form>
|
||||
</a-form>
|
||||
</template>
|
||||
</a-card>
|
||||
|
||||
<!-- 命令展示 -->
|
||||
|
||||
@@ -60,9 +60,30 @@ let state: StateType = reactive({
|
||||
function fnTreeSelect(_: any, info: any) {
|
||||
state.mmlSelect = info.node.dataRef;
|
||||
state.from = {};
|
||||
// 遍历判断是否有初始value
|
||||
if (Array.isArray(state.mmlSelect.param)) {
|
||||
for (const param of state.mmlSelect.param) {
|
||||
if (typeof param.value !== 'undefined' && param.value != '') {
|
||||
const valueType = param.type;
|
||||
if (['enum', 'int'].includes(valueType)) {
|
||||
state.from[param.name] = Number(param.value);
|
||||
} else if (valueType === 'bool') {
|
||||
state.from[param.name] = Boolean(param.value);
|
||||
} else {
|
||||
state.from[param.name] = param.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.autoCompleteValue =
|
||||
`${state.mmlSelect.operation} ${state.mmlSelect.object}`.trim();
|
||||
// state.mmlCmdLog = '';
|
||||
// 回到顶部
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth', // 平滑滚动到顶部,如果不需要平滑效果可以将此行代码删除
|
||||
});
|
||||
}
|
||||
|
||||
/**清空控制台日志 */
|
||||
@@ -148,15 +169,16 @@ function fnSendMML() {
|
||||
}
|
||||
|
||||
// 发送
|
||||
state.mmlCmdLog += `${cmdArr.join('\n')}\n`;
|
||||
state.from.sendLoading = true;
|
||||
sendMMlByUDM(state.neId, cmdArr).then(res => {
|
||||
state.from.sendLoading = false;
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
let resultArr = res.data;
|
||||
for (const str of resultArr) {
|
||||
for (let i = 0; i < resultArr.length; i++) {
|
||||
const str = resultArr[i];
|
||||
const logStr = str.replace(/(\r\n|\n)/g, '\n');
|
||||
state.mmlCmdLog += `${logStr}\n`;
|
||||
const cmdStr = cmdArr[i];
|
||||
state.mmlCmdLog += `${cmdStr}\n${logStr}\n`;
|
||||
}
|
||||
} else {
|
||||
state.mmlCmdLog += `${res.msg}\n`;
|
||||
@@ -179,7 +201,7 @@ function fnUpload(up: UploadRequestOption, name: string) {
|
||||
message.success(t('views.mmlManage.uploadFileOk'), 3);
|
||||
state.from[name] = res.data;
|
||||
} else {
|
||||
message.error(res.msg, 3);
|
||||
message.error(t('views.mmlManage.uploadFileErr'), 3);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -445,6 +467,11 @@ onMounted(() => {
|
||||
state.neId = arr[0].value;
|
||||
// 获取列表数据
|
||||
fnGetList();
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('views.mmlManage.udmOpesrate.noUDM'),
|
||||
duration: 5,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
message.warning({
|
||||
@@ -465,7 +492,7 @@ onMounted(() => {
|
||||
<template>
|
||||
<PageContainer>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="6">
|
||||
<a-col :lg="6" :md="6" :xs="24" style="margin-bottom: 24px">
|
||||
<!-- 命令导航 -->
|
||||
<a-card
|
||||
size="small"
|
||||
@@ -491,7 +518,7 @@ onMounted(() => {
|
||||
</a-form>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="18">
|
||||
<a-col :lg="18" :md="18" :xs="24">
|
||||
<!-- 命令参数输入 -->
|
||||
<a-card size="small" :bordered="false">
|
||||
<template #title>
|
||||
@@ -531,7 +558,7 @@ onMounted(() => {
|
||||
</template>
|
||||
|
||||
<a-form
|
||||
layout="vertical"
|
||||
layout="horizontal"
|
||||
autocomplete="off"
|
||||
:validate-on-rule-change="false"
|
||||
:validateTrigger="[]"
|
||||
@@ -549,8 +576,15 @@ onMounted(() => {
|
||||
<a-textarea :placeholder="t('common.ipnutPlease')" auto-size />
|
||||
</a-auto-complete>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<template v-if="state.mmlSelect.operation && state.mmlSelect.param">
|
||||
<template v-if="state.mmlSelect.operation && state.mmlSelect.param">
|
||||
<a-form
|
||||
layout="vertical"
|
||||
autocomplete="off"
|
||||
:validate-on-rule-change="false"
|
||||
:validateTrigger="[]"
|
||||
>
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.mmlManage.cmdParamPanel') }}
|
||||
</a-divider>
|
||||
@@ -626,8 +660,8 @@ onMounted(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-form>
|
||||
</a-form>
|
||||
</template>
|
||||
</a-card>
|
||||
|
||||
<!-- 命令展示 -->
|
||||
|
||||
@@ -645,7 +645,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="fnModalVisibleByEdit()"
|
||||
@@ -689,12 +689,12 @@ onMounted(() => {
|
||||
<template #icon><SyncOutlined /></template>
|
||||
{{ t('views.monitor.job.resetQueue') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -743,7 +743,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
@@ -866,7 +866,8 @@ onMounted(() => {
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.monitor.job.status')" name="status">
|
||||
{{
|
||||
dict.sysJobStatus.find(s => s.value === modalState.from.status)?.label
|
||||
dict.sysJobStatus.find(s => s.value === modalState.from.status)
|
||||
?.label
|
||||
}}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
@@ -491,7 +491,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button type="default" @click.prevent="fnClose()">
|
||||
<template #icon><CloseOutlined /></template>
|
||||
{{ t('common.close') }}
|
||||
@@ -523,12 +523,12 @@ onMounted(() => {
|
||||
<template #icon><ExportOutlined /></template>
|
||||
{{ t('common.export') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -577,7 +577,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
|
||||
@@ -118,7 +118,7 @@ let tablePagination = {
|
||||
showSizeChanger: true,
|
||||
/**数据总数 */
|
||||
total: 0,
|
||||
showTotal: (total: number) => `总共 ${total} 条`,
|
||||
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
|
||||
onChange: (page: number, pageSize: number) => {
|
||||
tablePagination.current = page;
|
||||
tablePagination.pageSize = pageSize;
|
||||
|
||||
68
src/views/monitor/topology/index.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted } from 'vue';
|
||||
import { PageContainer } from 'antdv-pro-layout';
|
||||
import ChartGraphG6 from '@/components/ChartGraphG6/index.vue';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
const { t } = useI18n();
|
||||
|
||||
/**查询全部网元数据列表 */
|
||||
function fnGetList() {}
|
||||
|
||||
onMounted(() => {});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageContainer>
|
||||
<a-card
|
||||
:bordered="false"
|
||||
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
||||
>
|
||||
<!-- 表格搜索栏 -->
|
||||
<a-form name="queryParams" layout="horizontal">
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="10" :md="10" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.monitor.monitor.filter')"
|
||||
name="neTypeSelect"
|
||||
>
|
||||
ssdf
|
||||
</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()">
|
||||
<template #icon><SearchOutlined /></template>
|
||||
{{ t('common.search') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-card>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-card :bordered="false" :body-style="{ marginBottom: '24px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>asdf</template>
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra> adf </template>
|
||||
|
||||
<div class="chart">
|
||||
<ChartGraphG6 :option="{}"></ChartGraphG6>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
background-color: rgb(238, 237, 237);
|
||||
}
|
||||
</style>
|
||||
@@ -728,7 +728,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button type="primary" @click.prevent="fnModalVisibleByEdit()">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
@@ -790,12 +790,12 @@ onMounted(() => {
|
||||
{{ t('views.neUser.auth.export') }}
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -848,7 +848,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
|
||||
@@ -72,12 +72,14 @@ let tableColumns: ColumnsType = [
|
||||
{
|
||||
title: 'IMSI',
|
||||
dataIndex: 'imsi',
|
||||
sorter: (a: any, b: any) => Number(a.imsi) - Number(b.imsi),
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'MSISDN',
|
||||
dataIndex: 'msisdn',
|
||||
sorter: (a: any, b: any) => Number(a.msisdn) - Number(b.msisdn),
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
|
||||
@@ -61,20 +61,21 @@ let tableColumns: ColumnsType = [
|
||||
{
|
||||
title: 'IMSI',
|
||||
dataIndex: 'imsi',
|
||||
sorter: (a: any, b: any) => Number(a.imsi) - Number(b.imsi),
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'ActiveTime',
|
||||
title: 'Active Time',
|
||||
dataIndex: 'activeTime',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'RegState',
|
||||
title: 'Registration State ',
|
||||
dataIndex: 'regState',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'Network Access Identity',
|
||||
|
||||
@@ -82,6 +82,7 @@ let tableColumns: ColumnsType = [
|
||||
{
|
||||
title: 'MSISDN',
|
||||
dataIndex: 'msisdn',
|
||||
sorter: (a: any, b: any) => Number(a.msisdn) - Number(b.msisdn),
|
||||
align: 'center',
|
||||
width: 150,
|
||||
},
|
||||
@@ -382,7 +383,7 @@ function fnExportList(type: string) {
|
||||
message.loading({ content: t('common.loading'), key });
|
||||
exportRule({
|
||||
neId: neID,
|
||||
type: type,
|
||||
fileType: type,
|
||||
}).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success({
|
||||
@@ -408,6 +409,8 @@ function fnGetList() {
|
||||
listRules(toRaw(queryParams)).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
||||
tableState.data = res.rows;
|
||||
} else {
|
||||
tableState.data = [];
|
||||
}
|
||||
tableState.loading = false;
|
||||
});
|
||||
@@ -458,15 +461,19 @@ function fnModalUploadImportUpload(file: File) {
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
return importRuleData({
|
||||
type: 'txt',
|
||||
neId: neID,
|
||||
filePath: res.data,
|
||||
fileType: 'txt',
|
||||
});
|
||||
}
|
||||
return res;
|
||||
})
|
||||
.then(res => {
|
||||
uploadImportState.msg = res.msg;
|
||||
if (res.code === RESULT_CODE_SUCCESS && res.data?.detail) {
|
||||
uploadImportState.msg = res.data?.detail;
|
||||
} else {
|
||||
uploadImportState.msg = t('views.neUser.pcf.uploadFileErr');
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
hide();
|
||||
@@ -560,7 +567,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button type="primary" @click.prevent="fnModalVisibleByEdit()">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
@@ -584,7 +591,7 @@ onMounted(() => {
|
||||
@click.prevent="fnModalVisibleByBatch('update')"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
<FormOutlined />
|
||||
</template>
|
||||
{{ t('views.neUser.pcf.batchUpdateText') }}
|
||||
</a-button>
|
||||
@@ -618,12 +625,12 @@ onMounted(() => {
|
||||
{{ t('views.neUser.pcf.export') }}
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
{{
|
||||
@@ -684,7 +691,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
|
||||
@@ -454,6 +454,7 @@ const modalStateFrom = Form.useForm(
|
||||
modalState.from,
|
||||
reactive({
|
||||
imsi: [{ required: true, message: 'IMSI' + t('common.unableNull') }],
|
||||
msisdn: [{ required: true, message: 'MSISDN' + t('common.unableNull') }],
|
||||
staticIp: [
|
||||
{ required: true, message: 'static ip' + t('common.unableNull') },
|
||||
],
|
||||
@@ -473,7 +474,7 @@ const modalStateFrom = Form.useForm(
|
||||
function fnModalOk() {
|
||||
const from = Object.assign({}, toRaw(modalState.from));
|
||||
|
||||
let validateNames = ['imsi', 'staticIp'];
|
||||
let validateNames = ['imsi', 'msisdn', 'staticIp'];
|
||||
|
||||
if (from.id === '') {
|
||||
validateNames.push('smData');
|
||||
@@ -573,7 +574,7 @@ function fnBatchModalOk() {
|
||||
modalState.confirmLoading = true;
|
||||
let ardArr = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
let hplmnArr = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
let odbArr = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
let odbArr = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
from.ard.forEach((item: any) => {
|
||||
ardArr[item] = 1;
|
||||
@@ -962,7 +963,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button type="primary" @click.prevent="fnModalVisibleByEdit()">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
@@ -1030,12 +1031,12 @@ onMounted(() => {
|
||||
{{ t('views.neUser.sub.export') }}
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -1088,7 +1089,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
|
||||
@@ -73,6 +73,7 @@ let tableColumns: ColumnsType = [
|
||||
title: 'IMSI',
|
||||
dataIndex: 'imsi',
|
||||
align: 'center',
|
||||
sorter: (a: any, b: any) => Number(a.imsi) - Number(b.imsi),
|
||||
customRender(opt) {
|
||||
const idx = opt.value.lastIndexOf('-');
|
||||
if (idx != -1) {
|
||||
@@ -81,11 +82,13 @@ let tableColumns: ColumnsType = [
|
||||
return opt.value;
|
||||
},
|
||||
width: 150,
|
||||
|
||||
},
|
||||
{
|
||||
title: 'MSISDN',
|
||||
dataIndex: 'msisdn',
|
||||
align: 'center',
|
||||
sorter: (a: any, b: any) => Number(a.msisdn) - Number(b.msisdn),
|
||||
customRender(opt) {
|
||||
const idx = opt.value.lastIndexOf('-');
|
||||
if (idx != -1) {
|
||||
|
||||
@@ -1,63 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router';
|
||||
import { reactive, ref, onMounted, toRaw } from 'vue';
|
||||
import { PageContainer } from 'antdv-pro-layout';
|
||||
import { 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 { message, Form } from 'ant-design-vue/lib';
|
||||
import { ColumnsType } from 'ant-design-vue/lib/table';
|
||||
import { parseDateToStr } from '@/utils/date-utils';
|
||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||
import ChartLine from '@/components/ChartLine/index.vue';
|
||||
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
||||
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { listgoldData } from '@/api/perfManage/goldTarget';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import useDictStore from '@/store/modules/dict';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
const { getDict } = useDictStore();
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
import { getGoldTitleByNE, goldData } from '@/api/perfManage/goldTarget';
|
||||
import { parseDateToStr } from '@/utils/date-utils';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { t, currentLocale } = useI18n();
|
||||
|
||||
/**路由标题 */
|
||||
let title = ref<string>((route.meta.title as string) ?? '标题');
|
||||
/**网元参数 */
|
||||
let neCascaderOptions = ref<Record<string, any>[]>([]);
|
||||
|
||||
/**记录开始结束时间 */
|
||||
let queryRangePicker = ref<[string, string]>(['', '']);
|
||||
|
||||
/**查询参数 */
|
||||
let queryParams = reactive({
|
||||
/**网元类型 */
|
||||
neType: '',
|
||||
/**记录时间 */
|
||||
beginTime: '',
|
||||
endTime: '',
|
||||
/**排序字段 */
|
||||
sortField: 'value',
|
||||
/**排序方式 */
|
||||
sortOrder: 'asc',
|
||||
/**当前页数 */
|
||||
pageNum: 1,
|
||||
/**每页条数 */
|
||||
pageSize: 20,
|
||||
});
|
||||
|
||||
/**查询参数重置 */
|
||||
function fnQueryReset() {
|
||||
queryParams = Object.assign(queryParams, {
|
||||
neType: '',
|
||||
beginTime: '',
|
||||
endTime: '',
|
||||
sortField: 'value',
|
||||
sortOrder: 'asc',
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
});
|
||||
queryRangePicker.value = ['', ''];
|
||||
tablePagination.current = 1;
|
||||
tablePagination.pageSize = 20;
|
||||
fnGetList();
|
||||
}
|
||||
/**表格字段列排序 */
|
||||
let tableColumnsDnd = ref<ColumnsType>([]);
|
||||
|
||||
/**表格状态类型 */
|
||||
type TabeStateType = {
|
||||
/**表格列 */
|
||||
tableColumns: object[];
|
||||
/**加载等待 */
|
||||
loading: boolean;
|
||||
/**紧凑型 */
|
||||
@@ -70,53 +40,13 @@ type TabeStateType = {
|
||||
|
||||
/**表格状态 */
|
||||
let tableState: TabeStateType = reactive({
|
||||
tableColumns: [],
|
||||
loading: false,
|
||||
size: 'middle',
|
||||
seached: true,
|
||||
data: [],
|
||||
});
|
||||
|
||||
/**表格字段列 */
|
||||
let tableColumns: ColumnsType = [
|
||||
{
|
||||
title: t('views.perfManage.goldTarget.type'),
|
||||
dataIndex: 'neType',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.goldTarget.enTitle'),
|
||||
dataIndex: 'enTitle',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.goldTarget.value'),
|
||||
dataIndex: 'value',
|
||||
key: 'value',
|
||||
align: 'center',
|
||||
sorter: true,
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.goldTarget.startTime'),
|
||||
dataIndex: 'startTime',
|
||||
key: 'start_time',
|
||||
align: 'center',
|
||||
customRender(opt) {
|
||||
if (!opt.value) return '';
|
||||
return parseDateToStr(opt.value);
|
||||
},
|
||||
sorter: true,
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.goldTarget.endTime'),
|
||||
dataIndex: 'endTime',
|
||||
align: 'center',
|
||||
customRender(opt) {
|
||||
if (!opt.value) return '';
|
||||
return parseDateToStr(opt.value);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
/**表格分页器参数 */
|
||||
let tablePagination = reactive({
|
||||
/**当前页数 */
|
||||
@@ -150,45 +80,265 @@ 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;
|
||||
/**查询参数 */
|
||||
let queryParams: any = reactive({
|
||||
/**卡片切换Flag */
|
||||
cardFlag: 0, //0-显示统计图 1-显示统计表
|
||||
/**告警设备类型 */
|
||||
neType: '',
|
||||
/**告警网元标识 */
|
||||
neId: '',
|
||||
/**颗粒度 */
|
||||
particle: '15',
|
||||
beginTime: '',
|
||||
endTime: '',
|
||||
});
|
||||
|
||||
/**图表显示数据 */
|
||||
const chartsOption = reactive({
|
||||
/**性能指标 */
|
||||
perfChart: {},
|
||||
});
|
||||
|
||||
/**对象信息状态类型 */
|
||||
type StateType = {
|
||||
/**网元类型 */
|
||||
neType: string[];
|
||||
/**制表网元类型 */
|
||||
designNeType: string;
|
||||
/**黄金指标集 tree */
|
||||
designTreeData: any[];
|
||||
/**表单数据 */
|
||||
from: Record<string, any>;
|
||||
};
|
||||
|
||||
/**对象信息状态 */
|
||||
let state: StateType = reactive({
|
||||
neType: [],
|
||||
designNeType: '',
|
||||
designTreeData: [],
|
||||
from: {
|
||||
uploadLoading: false,
|
||||
sendLoading: false,
|
||||
},
|
||||
});
|
||||
|
||||
/**网元类型选择对应修改 */
|
||||
function fnNeChange(keys: any, _: any) {
|
||||
// 不是同类型时需要重新加载
|
||||
if (state.designNeType !== keys[0]) {
|
||||
state.designTreeData = [];
|
||||
queryParams.cardFlag = 0;
|
||||
fnGetList();
|
||||
}
|
||||
}
|
||||
|
||||
/**查询可选命令列表 */
|
||||
function fnGetList() {
|
||||
const neType = queryParams.neType[0];
|
||||
state.designNeType = neType;
|
||||
var language = currentLocale.value.split('_')[0];
|
||||
if (language === 'zh') language = 'cn';
|
||||
getGoldTitleByNE(neType).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
// 构建树结构
|
||||
const treeArr: Record<string, any>[] = [];
|
||||
for (const item of res.data) {
|
||||
const id = item['id'];
|
||||
const kpiDisplay = item[`${language}Title`];
|
||||
const kpiValue = item[`kpiId`];
|
||||
treeArr.push({
|
||||
key: kpiValue,
|
||||
title: kpiDisplay,
|
||||
});
|
||||
}
|
||||
state.designTreeData = treeArr;
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('common.getInfoFail'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
});
|
||||
fnDesign();
|
||||
}
|
||||
|
||||
/**根据 key 查找对应的 title */
|
||||
function findTitleByKey(key: string): string | undefined {
|
||||
const item = state.designTreeData.find(item => item.key === key);
|
||||
return item ? item.title : undefined;
|
||||
}
|
||||
|
||||
/**筛选条件进行制图 */
|
||||
function fnMakeTable(flag: any) {
|
||||
queryParams.cardFlag = flag;
|
||||
fnDesign();
|
||||
}
|
||||
|
||||
/**筛选条件进行制图 */
|
||||
function fnDesign() {
|
||||
//当前界面是表格界面
|
||||
const columnsArr = state.designTreeData.map(item => {
|
||||
return {
|
||||
title: item.title,
|
||||
dataIndex: item.key,
|
||||
align: 'center',
|
||||
};
|
||||
});
|
||||
tableState.tableColumns = columnsArr;
|
||||
tableState.tableColumns.unshift({
|
||||
title: t('views.perfManage.perfData.neName'),
|
||||
dataIndex: 'neName',
|
||||
align: 'center',
|
||||
});
|
||||
tableState.tableColumns.push({
|
||||
title: t('views.perfManage.goldTarget.time'),
|
||||
dataIndex: 'timeGroup',
|
||||
align: 'center',
|
||||
fixed: 'right',
|
||||
});
|
||||
if (!queryRangePicker.value) {
|
||||
queryRangePicker.value = ['', ''];
|
||||
}
|
||||
queryParams.beginTime = queryRangePicker.value[0];
|
||||
queryParams.endTime = queryRangePicker.value[1];
|
||||
listgoldData(toRaw(queryParams)).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
||||
tablePagination.total = res.total;
|
||||
tableState.data = res.rows;
|
||||
}
|
||||
tableState.loading = false;
|
||||
});
|
||||
}
|
||||
const neType = queryParams.neType[0];
|
||||
let goldXDate: any = [];
|
||||
let goldYData: any = [];
|
||||
let hideAll: any = {};
|
||||
goldData(queryParams).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
if (res.data.length > 0) {
|
||||
tableState.data = res.data;
|
||||
tablePagination.total = res.data.length;
|
||||
goldXDate = res.data.map((item: any) => item.timeGroup);
|
||||
goldYData = Object.keys(res.data[0])
|
||||
.filter(key => !['timeGroup', 'neName', 'startIndex'].includes(key))
|
||||
.map(key => {
|
||||
const title: any = findTitleByKey(key);
|
||||
hideAll[title]=false;
|
||||
return {
|
||||
name: title,
|
||||
data: res.data.map((item: any) => parseInt(item[key])),
|
||||
};
|
||||
});
|
||||
} else {
|
||||
tableState.data = [];
|
||||
tablePagination.total = 0;
|
||||
state.designTreeData.forEach((item: any) => {
|
||||
goldYData.push({ name: item.title, data: [] });
|
||||
});
|
||||
message.warning({
|
||||
content: t('views.perfManage.goldTarget.nullTip'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
|
||||
/**表格分页、排序、筛选变化时触发操作, 排序方式,取值为 ascend descend */
|
||||
function fnTableChange(pagination: any, filters: any, sorter: any, extra: any) {
|
||||
console.log(sorter);
|
||||
const { columnKey, order } = sorter;
|
||||
if (order) {
|
||||
queryParams.sortField = columnKey;
|
||||
queryParams.sortOrder = order.replace('end', '');
|
||||
} else {
|
||||
queryParams.sortOrder = 'asc';
|
||||
}
|
||||
fnGetList(1);
|
||||
// 图标参数
|
||||
const option = {
|
||||
xDatas: goldXDate,
|
||||
yDatas: goldYData,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (datas: any) {
|
||||
let res = datas[0].name + '<br/>';
|
||||
for (const item of datas) {
|
||||
res += `${item.marker} ${item.seriesName}:${item.data}<br/>`;
|
||||
}
|
||||
return res;
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
// orient: 'vertical',
|
||||
// left: 'left',
|
||||
type: 'scroll',
|
||||
orient: 'vertical', // vertical
|
||||
right: 20,
|
||||
//itemWidth: 20,
|
||||
itemGap: 25,
|
||||
textStyle: {
|
||||
color: '#646A73',
|
||||
},
|
||||
icon: 'circle',
|
||||
selected:hideAll,
|
||||
},
|
||||
grid: {
|
||||
left: '10%',
|
||||
right: '30%',
|
||||
bottom: '20%',
|
||||
},
|
||||
yAxis: [
|
||||
{ type: 'value', splitNumber: 4, axisLabel: { fontSize: 10 } },
|
||||
{
|
||||
type: 'value',
|
||||
position: 'right',
|
||||
alignTicks: true,
|
||||
axisLabel: {
|
||||
fontSize: 10,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
chartsOption.perfChart = option;
|
||||
|
||||
//处理表格数据
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('common.getInfoFail'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
useNeInfoStore().fnNelist();
|
||||
// 获取列表数据
|
||||
fnGetList();
|
||||
neInfoStore
|
||||
.fnNelist()
|
||||
.then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
if (res.data.length > 0) {
|
||||
// 过滤不可用的网元
|
||||
neCascaderOptions.value = neInfoStore.getNeCascaderOptions.filter(
|
||||
(item: any) => {
|
||||
return !['OMC'].includes(item.value);
|
||||
}
|
||||
);
|
||||
if (neCascaderOptions.value.length === 0) {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 默认选择AMF
|
||||
const item = neCascaderOptions.value.find(s => s.value === 'UPF');
|
||||
if (item && item.children) {
|
||||
const info = item.children[0];
|
||||
queryParams.neType = [info.neType, info.neId];
|
||||
} else {
|
||||
const info = neCascaderOptions.value[0].children[0];
|
||||
queryParams.neType = [info.neType, info.neId];
|
||||
}
|
||||
const initTime: Date = new Date();
|
||||
const startTime: Date = new Date(initTime);
|
||||
startTime.setHours(0, 0, 0, 0); // 设置为今天的0点
|
||||
const endTime: Date = new Date(initTime);
|
||||
endTime.setHours(23, 59, 59, 59); // 设置为今天的12点
|
||||
|
||||
queryRangePicker.value = [
|
||||
parseDateToStr(startTime),
|
||||
parseDateToStr(endTime),
|
||||
];
|
||||
fnGetList();
|
||||
}
|
||||
} else {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -200,48 +350,59 @@ onMounted(() => {
|
||||
:body-style="{ marginBottom: '24px', paddingBottom: 0 }"
|
||||
>
|
||||
<!-- 表格搜索栏 -->
|
||||
<a-form :model="queryParams" name="queryParams" layout="horizontal">
|
||||
<a-form :model="queryParams" name="queryParamsFrom" layout="horizontal">
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="6" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.perfManage.goldTarget.type')"
|
||||
name="neType"
|
||||
:label="t('views.traceManage.task.neType')"
|
||||
>
|
||||
<a-auto-complete
|
||||
<a-cascader
|
||||
v-model:value="queryParams.neType"
|
||||
:options="useNeInfoStore().getNeSelectOtions"
|
||||
allow-clear
|
||||
:options="neCascaderOptions"
|
||||
@change="fnNeChange"
|
||||
:allow-clear="false"
|
||||
:placeholder="t('common.selectPlease')"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="8" :md="12" :xs="24">
|
||||
<a-col :lg="10" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.perfManage.goldTarget.startTime')"
|
||||
name="queryRangePicker"
|
||||
:label="t('views.perfManage.goldTarget.timeFrame')"
|
||||
name="eventTime"
|
||||
>
|
||||
<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"
|
||||
style="width: 100%"
|
||||
></a-range-picker>
|
||||
:allow-clear="false"
|
||||
show-time
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="6" :md="12" :xs="24">
|
||||
<a-col :lg="4" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.perfManage.goldTarget.particle')"
|
||||
name="particle"
|
||||
>
|
||||
<a-select
|
||||
v-model:value="queryParams.particle"
|
||||
:placeholder="t('common.selectPlease')"
|
||||
:options="[
|
||||
{ label: '15M', value: '15' },
|
||||
{ label: '30M', value: '30' },
|
||||
{ label: '60M', value: '60' },
|
||||
]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="2" :md="12" :xs="24">
|
||||
<a-form-item>
|
||||
<a-space :size="8">
|
||||
<a-button type="primary" @click.prevent="fnGetList(1)">
|
||||
<a-button type="primary" @click.prevent="fnDesign()">
|
||||
<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>
|
||||
@@ -249,86 +410,112 @@ onMounted(() => {
|
||||
</a-form>
|
||||
</a-card>
|
||||
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title> </template>
|
||||
<template v-if="queryParams.cardFlag">
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-button type="primary" @click.prevent="fnMakeTable(0)">
|
||||
<template #icon> <area-chart-outlined /> </template>
|
||||
{{ t('views.perfManage.goldTarget.kpiTitle') }}
|
||||
</a-button>
|
||||
</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>
|
||||
<TableColumnsDnd
|
||||
:columns="tableState.tableColumns"
|
||||
v-model:columns-dnd="tableColumnsDnd"
|
||||
></TableColumnsDnd>
|
||||
<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="tableColumnsDnd"
|
||||
:loading="tableState.loading"
|
||||
:data-source="tableState.data"
|
||||
:size="tableState.size"
|
||||
:pagination="tablePagination"
|
||||
:scroll="{ x: tableColumnsDnd.length * 200, y: 450 }"
|
||||
@resizeColumn="(w:number, col:any) => (col.width = w)"
|
||||
:show-expand-column="false"
|
||||
>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<a-card :bordered="false" :body-style="{ marginBottom: '24px' }" v-else>
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>{{
|
||||
t('views.perfManage.goldTarget.kpiTitle')
|
||||
}}</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-button type="default" size="small" @click.prevent="fnMakeTable(1)">
|
||||
<template #icon>
|
||||
<ClearOutlined />
|
||||
</template>
|
||||
{{ t('views.perfManage.goldTarget.allData') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
<a-table
|
||||
class="table"
|
||||
row-key="id"
|
||||
:columns="tableColumns"
|
||||
:loading="tableState.loading"
|
||||
:data-source="tableState.data"
|
||||
:size="tableState.size"
|
||||
@change="fnTableChange"
|
||||
:pagination="tablePagination"
|
||||
:scroll="{ x: true }"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'alarmTitle'">
|
||||
<a-tooltip>
|
||||
<template #title>{{ record.operResult }}</template>
|
||||
<div class="alarmTitleText">{{ record.alarmTitle }}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
<div class="chart">
|
||||
<ChartLine
|
||||
:option="chartsOption.perfChart"
|
||||
:dataZoom="false"
|
||||
height="400px"
|
||||
></ChartLine>
|
||||
</div>
|
||||
</a-card>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.table :deep(.ant-pagination) {
|
||||
padding: 0 24px;
|
||||
}
|
||||
.alarmTitleText {
|
||||
max-width: 300px;
|
||||
cursor: pointer;
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
}
|
||||
</style>
|
||||
|
||||
334
src/views/perfManage/goldTarget/index1.vue
Normal file
@@ -0,0 +1,334 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router';
|
||||
import { reactive, ref, onMounted, toRaw } from 'vue';
|
||||
import { PageContainer } from 'antdv-pro-layout';
|
||||
import { Modal } from 'ant-design-vue/lib';
|
||||
import { SizeType } from 'ant-design-vue/lib/config-provider';
|
||||
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
|
||||
import { ColumnsType } from 'ant-design-vue/lib/table';
|
||||
import { parseDateToStr } from '@/utils/date-utils';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { listgoldData } from '@/api/perfManage/goldTarget';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import useDictStore from '@/store/modules/dict';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
const { getDict } = useDictStore();
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
||||
/**路由标题 */
|
||||
let title = ref<string>((route.meta.title as string) ?? '标题');
|
||||
|
||||
/**记录开始结束时间 */
|
||||
let queryRangePicker = ref<[string, string]>(['', '']);
|
||||
|
||||
/**查询参数 */
|
||||
let queryParams = reactive({
|
||||
/**网元类型 */
|
||||
neType: '',
|
||||
/**记录时间 */
|
||||
beginTime: '',
|
||||
endTime: '',
|
||||
/**排序字段 */
|
||||
sortField: 'value',
|
||||
/**排序方式 */
|
||||
sortOrder: 'asc',
|
||||
/**当前页数 */
|
||||
pageNum: 1,
|
||||
/**每页条数 */
|
||||
pageSize: 20,
|
||||
});
|
||||
|
||||
/**查询参数重置 */
|
||||
function fnQueryReset() {
|
||||
queryParams = Object.assign(queryParams, {
|
||||
neType: '',
|
||||
beginTime: '',
|
||||
endTime: '',
|
||||
sortField: 'value',
|
||||
sortOrder: 'asc',
|
||||
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('views.perfManage.goldTarget.type'),
|
||||
dataIndex: 'neType',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.goldTarget.enTitle'),
|
||||
dataIndex: 'enTitle',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.goldTarget.value'),
|
||||
dataIndex: 'value',
|
||||
key: 'value',
|
||||
align: 'center',
|
||||
sorter: true,
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.goldTarget.startTime'),
|
||||
dataIndex: 'startTime',
|
||||
key: 'start_time',
|
||||
align: 'center',
|
||||
customRender(opt) {
|
||||
if (!opt.value) return '';
|
||||
return parseDateToStr(opt.value);
|
||||
},
|
||||
sorter: true,
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.goldTarget.endTime'),
|
||||
dataIndex: 'endTime',
|
||||
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];
|
||||
listgoldData(toRaw(queryParams)).then(res => {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.rows)) {
|
||||
tablePagination.total = res.total;
|
||||
tableState.data = res.rows;
|
||||
}
|
||||
tableState.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**表格分页、排序、筛选变化时触发操作, 排序方式,取值为 ascend descend */
|
||||
function fnTableChange(pagination: any, filters: any, sorter: any, extra: any) {
|
||||
console.log(sorter);
|
||||
const { columnKey, order } = sorter;
|
||||
if (order) {
|
||||
queryParams.sortField = columnKey;
|
||||
queryParams.sortOrder = order.replace('end', '');
|
||||
} else {
|
||||
queryParams.sortOrder = 'asc';
|
||||
}
|
||||
fnGetList(1);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 获取网元网元列表
|
||||
useNeInfoStore().fnNelist();
|
||||
// 获取列表数据
|
||||
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.perfManage.goldTarget.type')"
|
||||
name="neType"
|
||||
>
|
||||
<a-auto-complete
|
||||
v-model:value="queryParams.neType"
|
||||
:options="useNeInfoStore().getNeSelectOtions"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="8" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.perfManage.goldTarget.startTime')"
|
||||
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"
|
||||
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"
|
||||
@change="fnTableChange"
|
||||
:pagination="tablePagination"
|
||||
:scroll="{ x: true }"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'alarmTitle'">
|
||||
<a-tooltip>
|
||||
<template #title>{{ record.operResult }}</template>
|
||||
<div class="alarmTitleText">{{ record.alarmTitle }}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.table :deep(.ant-pagination) {
|
||||
padding: 0 24px;
|
||||
}
|
||||
.alarmTitleText {
|
||||
max-width: 300px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -352,14 +352,6 @@ onMounted(() => {
|
||||
@change="fnTableChange"
|
||||
:scroll="{ x: true }"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'alarmTitle'">
|
||||
<a-tooltip>
|
||||
<template #title>{{ record.operResult }}</template>
|
||||
<div class="alarmTitleText">{{ record.alarmTitle }}</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</PageContainer>
|
||||
@@ -369,8 +361,4 @@ onMounted(() => {
|
||||
.table :deep(.ant-pagination) {
|
||||
padding: 0 24px;
|
||||
}
|
||||
.alarmTitleText {
|
||||
max-width: 300px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -322,7 +322,7 @@ function fnModalVisibleByEdit(id?: string) {
|
||||
* 进行表达规则校验
|
||||
*/
|
||||
function fnModalOk() {
|
||||
console.log(modalState.from);
|
||||
//console.log(modalState.from);
|
||||
modalStateFrom
|
||||
.validate()
|
||||
.then(e => {
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
taskStop,
|
||||
taskRun,
|
||||
} from '@/api/perfManage/taskManage';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { t, currentLocale } = useI18n();
|
||||
|
||||
const generateOptions = (start: any, end: any) => {
|
||||
@@ -378,7 +379,7 @@ function fnSelectPer(s: any, option: any) {
|
||||
/**性能测量数据集选择初始 */
|
||||
function fnSelectPerformanceInit(neType: string) {
|
||||
//console.logg(currentLocale.value); //当前语言
|
||||
const performance = useNeInfoStore().perMeasurementList.filter(
|
||||
const performance = neInfoStore.perMeasurementList.filter(
|
||||
i => i.neType === neType
|
||||
);
|
||||
//进行分组选择
|
||||
@@ -692,9 +693,9 @@ onMounted(() => {
|
||||
|
||||
Promise.allSettled([
|
||||
// 获取网元网元列表
|
||||
useNeInfoStore().fnNelist(),
|
||||
neInfoStore.fnNelist(),
|
||||
// 获取性能测量集列表
|
||||
useNeInfoStore().fnNeTaskPerformance(),
|
||||
neInfoStore.fnNeTaskPerformance(),
|
||||
]).finally(() => {
|
||||
// 获取列表数据
|
||||
fnGetList();
|
||||
@@ -719,7 +720,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-auto-complete
|
||||
v-model:value="queryParams.neType"
|
||||
:options="useNeInfoStore().getNeSelectOtions"
|
||||
:options="neInfoStore.getNeSelectOtions"
|
||||
allow-clear
|
||||
:placeholder="t('views.traceManage.task.neTypePlease')"
|
||||
/>
|
||||
@@ -887,7 +888,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-cascader
|
||||
:value="modalState.neType"
|
||||
:options="useNeInfoStore().getNeCascaderOtions"
|
||||
:options="neInfoStore.getNeCascaderOptions"
|
||||
disabled
|
||||
/>
|
||||
</a-form-item>
|
||||
@@ -1002,7 +1003,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-cascader
|
||||
v-model:value="modalState.neType"
|
||||
:options="useNeInfoStore().getNeCascaderOtions"
|
||||
:options="neInfoStore.getNeCascaderOptions"
|
||||
@change="fnNeChange"
|
||||
:allow-clear="false"
|
||||
:placeholder="t('views.traceManage.task.neTypePlease')"
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<script lang="ts" setup>
|
||||
import { GlobalFooter } from 'antdv-pro-layout';
|
||||
import { Modal, message } from 'ant-design-vue/lib';
|
||||
import { onMounted, reactive, toRaw } from 'vue';
|
||||
import { computed, onMounted, reactive, toRaw } from 'vue';
|
||||
import { register } from '@/api/login';
|
||||
import { regExpPasswd, regExpUserName } from '@/utils/regular-utils';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
const { t } = useI18n();
|
||||
import { parseUrlPath } from '@/plugins/file-static-url';
|
||||
const { t, currentLocale } = useI18n();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const appStore = useAppStore();
|
||||
@@ -70,6 +71,22 @@ function fnFinish() {
|
||||
});
|
||||
}
|
||||
|
||||
// LOGO地址
|
||||
const logoUrl = computed(() => {
|
||||
let url =
|
||||
appStore.logoType === 'brand'
|
||||
? parseUrlPath(appStore.filePathBrand)
|
||||
: parseUrlPath(appStore.filePathIcon);
|
||||
|
||||
if (url.indexOf('{language}') === -1) {
|
||||
return url;
|
||||
}
|
||||
// 语言参数替换
|
||||
const local = currentLocale.value;
|
||||
const lang = local.split('_')[0];
|
||||
return url.replace('{language}', lang);
|
||||
});
|
||||
|
||||
/**
|
||||
* 国际化翻译转换
|
||||
*/
|
||||
@@ -92,11 +109,11 @@ onMounted(() => {
|
||||
<div class="header">
|
||||
<a href="/" target="_self">
|
||||
<template v-if="appStore.logoType === 'icon'">
|
||||
<img :src="appStore.getLOGOIcon" class="logo" alt="logo" />
|
||||
<img :src="logoUrl" class="logo" alt="logo" />
|
||||
<span class="title">{{ appStore.appName }}</span>
|
||||
</template>
|
||||
<template v-if="appStore.logoType === 'brand'">
|
||||
<img :src="appStore.getLOGOBrand" class="logo" alt="logo" />
|
||||
<img :src="logoUrl" class="logo" alt="logo" />
|
||||
</template>
|
||||
</a>
|
||||
</div>
|
||||
@@ -205,7 +222,6 @@ onMounted(() => {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
padding: 110px 0 144px;
|
||||
background-image: url(../assets/background.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center 110px;
|
||||
background-size: 100%;
|
||||
|
||||
@@ -552,7 +552,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="fnModalVisibleByEdit()"
|
||||
@@ -588,12 +588,12 @@ onMounted(() => {
|
||||
<template #icon><ExportOutlined /></template>
|
||||
{{ t('common.export') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -642,7 +642,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
|
||||
@@ -192,7 +192,7 @@ const modalStateFrom = Form.useForm(
|
||||
{
|
||||
required: true,
|
||||
min: 1,
|
||||
max: 30,
|
||||
max: 50,
|
||||
message: t('views.system.dept.className') + t('common.unableNull'),
|
||||
},
|
||||
],
|
||||
@@ -621,26 +621,34 @@ onMounted(() => {
|
||||
:title="modalState.title"
|
||||
@cancel="fnModalCancel"
|
||||
>
|
||||
<a-form layout="horizontal">
|
||||
<a-form layout="horizontal" :label-col="{ span: 6 }" :labelWrap="true">
|
||||
<a-form-item
|
||||
:label="t('views.system.dept.highClass')"
|
||||
name="parentId"
|
||||
:label-col="{ span: 3 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<a-tree-select
|
||||
:value="modalState.from.parentId"
|
||||
disabled
|
||||
:tree-data="modalState.treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'deptName',
|
||||
value: 'deptId',
|
||||
}"
|
||||
tree-node-label-prop="deptName"
|
||||
>
|
||||
<template #suffixIcon></template>
|
||||
</a-tree-select>
|
||||
</a-form-item>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.dept.highClass')"
|
||||
name="parentId"
|
||||
:label="t('views.system.dept.className')"
|
||||
name="deptName"
|
||||
>
|
||||
<a-tree-select
|
||||
:value="modalState.from.parentId"
|
||||
disabled
|
||||
:tree-data="modalState.treeData"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'deptName',
|
||||
value: 'deptId',
|
||||
}"
|
||||
tree-node-label-prop="deptName"
|
||||
>
|
||||
<template #suffixIcon></template>
|
||||
</a-tree-select>
|
||||
{{ modalState.from.deptName }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
@@ -652,6 +660,7 @@ onMounted(() => {
|
||||
</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.system.dept.status')" name="status">
|
||||
@@ -668,21 +677,16 @@ onMounted(() => {
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.dept.className')"
|
||||
name="deptName"
|
||||
:label="t('views.system.dept.admin')"
|
||||
name="leader"
|
||||
:label-col="{ span: 3 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
{{ modalState.from.deptName }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.system.dept.admin')" name="leader">
|
||||
{{ modalState.from.leader }}
|
||||
</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.system.dept.phone')" name="phone">
|
||||
{{ modalState.from.phone }}
|
||||
@@ -713,7 +717,12 @@ onMounted(() => {
|
||||
@ok="fnModalOk"
|
||||
@cancel="fnModalCancel"
|
||||
>
|
||||
<a-form name="modalStateFrom" layout="horizontal">
|
||||
<a-form
|
||||
name="modalStateFrom"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 6 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<a-form-item
|
||||
:label="t('views.system.dept.highClass')"
|
||||
name="parentId"
|
||||
@@ -751,18 +760,6 @@ onMounted(() => {
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.dept.admin')"
|
||||
name="leader"
|
||||
v-bind="modalStateFrom.validateInfos.leader"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.leader"
|
||||
allow-clear
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="6" :xs="24">
|
||||
<a-form-item :label="t('views.system.dept.status')" name="status">
|
||||
<a-select
|
||||
v-model:value="modalState.from.status"
|
||||
@@ -772,8 +769,11 @@ onMounted(() => {
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="6" :xs="24">
|
||||
<a-form-item :label="t('views.system.dept.showSort')" name="orderNum">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.dept.showSort')"
|
||||
name="orderNum"
|
||||
>
|
||||
<a-input-number
|
||||
v-model:value="modalState.from.orderNum"
|
||||
:min="0"
|
||||
@@ -785,6 +785,20 @@ onMounted(() => {
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.dept.admin')"
|
||||
name="leader"
|
||||
v-bind="modalStateFrom.validateInfos.leader"
|
||||
:label-col="{ span: 3 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="modalState.from.leader"
|
||||
allow-clear
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.dept.phone')"
|
||||
@@ -800,7 +814,7 @@ onMounted(() => {
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.dept.email')"
|
||||
:label="t('views.system.dept.email')"
|
||||
name="email"
|
||||
v-bind="modalStateFrom.validateInfos.email"
|
||||
>
|
||||
|
||||
@@ -561,7 +561,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button type="default" @click.prevent="fnClose()">
|
||||
<template #icon><CloseOutlined /></template>
|
||||
{{ t('common.close') }}
|
||||
@@ -592,12 +592,12 @@ onMounted(() => {
|
||||
<template #icon><ExportOutlined /></template>
|
||||
{{ t('common.export') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -646,7 +646,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
|
||||
@@ -552,7 +552,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="fnModalVisibleByEdit()"
|
||||
@@ -596,12 +596,12 @@ onMounted(() => {
|
||||
<template #icon><ExportOutlined /></template>
|
||||
{{ t('common.export') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -650,7 +650,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
|
||||
@@ -491,7 +491,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="fnModalVisibleByEdit()"
|
||||
@@ -518,12 +518,12 @@ onMounted(() => {
|
||||
<template #icon><ExportOutlined /></template>
|
||||
{{ t('common.export') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -572,7 +572,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
|
||||
@@ -394,7 +394,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button type="default" @click.prevent="fnClose()">
|
||||
<template #icon><CloseOutlined /></template>
|
||||
{{ t('common.cancel') }}
|
||||
@@ -417,12 +417,12 @@ onMounted(() => {
|
||||
<template #icon><UsergroupDeleteOutlined /></template>
|
||||
{{ t('views.system.role.batchCancel') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -471,7 +471,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
@@ -498,7 +498,9 @@ onMounted(() => {
|
||||
<template v-if="column.key === 'userId'">
|
||||
<a-space :size="8" align="center">
|
||||
<a-tooltip>
|
||||
<template #title>{{t('views.system.role.cancelGive')}}</template>
|
||||
<template #title>{{
|
||||
t('views.system.role.cancelGive')
|
||||
}}</template>
|
||||
<a-button
|
||||
type="link"
|
||||
@click.prevent="fnRecordDelete(record.userId)"
|
||||
|
||||
@@ -815,7 +815,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="fnModalVisibleByEdit()"
|
||||
@@ -842,7 +842,7 @@ onMounted(() => {
|
||||
<template #icon><ExportOutlined /></template>
|
||||
{{ t('common.export') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
@@ -1236,7 +1236,10 @@ onMounted(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.system.role.createTime')" name="createTime">
|
||||
<a-form-item
|
||||
:label="t('views.system.role.createTime')"
|
||||
name="createTime"
|
||||
>
|
||||
<span v-if="+modalState.from.createTime > 0">
|
||||
{{ parseDateToStr(+modalState.from.createTime) }}
|
||||
</span>
|
||||
@@ -1245,12 +1248,18 @@ onMounted(() => {
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.system.role.roleSort')" name="roleSort">
|
||||
<a-form-item
|
||||
:label="t('views.system.role.roleSort')"
|
||||
name="roleSort"
|
||||
>
|
||||
{{ modalState.from.roleSort }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.system.role.roleStatus')" name="status">
|
||||
<a-form-item
|
||||
:label="t('views.system.role.roleStatus')"
|
||||
name="status"
|
||||
>
|
||||
<DictTag
|
||||
:options="dict.sysNormalDisable"
|
||||
:value="modalState.from.status"
|
||||
@@ -1260,17 +1269,20 @@ onMounted(() => {
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.system.role.roleName')" name="roleName">
|
||||
<a-form-item
|
||||
:label="t('views.system.role.roleName')"
|
||||
name="roleName"
|
||||
>
|
||||
{{ modalState.from.roleName }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.system.role.roleKey')" name="roleKey">
|
||||
<a-form-item :label="t('views.system.role.roleKey')" name="roleKey">
|
||||
{{ modalState.from.roleKey }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item :label="t('views.system.role.roleMark')" name="remark">
|
||||
<a-form-item :label="t('views.system.role.roleMark')" name="remark">
|
||||
{{ modalState.from.remark }}
|
||||
</a-form-item>
|
||||
|
||||
@@ -1293,21 +1305,21 @@ onMounted(() => {
|
||||
:checked="modalState.deptTree.expandedKeys.length > 0"
|
||||
@change="(e:any) => fnModalExpandedKeys(e.target.checked, 'dept')"
|
||||
>
|
||||
{{t('views.system.role.openSwitch')}}
|
||||
{{ t('views.system.role.openSwitch') }}
|
||||
</a-checkbox>
|
||||
<a-checkbox
|
||||
id="dept_2"
|
||||
:checked="modalState.from.deptIds.length > 0"
|
||||
@change="(e:any) => fnModalCheckedKeys(e.target.checked, 'dept')"
|
||||
>
|
||||
{{t('views.system.role.selAllSwitch')}}
|
||||
{{ t('views.system.role.selAllSwitch') }}
|
||||
</a-checkbox>
|
||||
<a-checkbox
|
||||
id="dept_1"
|
||||
:checked="modalState.from.deptCheckStrictly === '1'"
|
||||
@change="(e:any) => fnModalCheckStrictly(e.target.checked, 'dept')"
|
||||
>
|
||||
{{t('views.system.role.relationSwitch')}}
|
||||
{{ t('views.system.role.relationSwitch') }}
|
||||
</a-checkbox>
|
||||
</a-space>
|
||||
<a-tree
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script lang="ts" setup>
|
||||
import { Modal, message } from 'ant-design-vue/lib';
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { transferHelpDoc } from '@/api/index';
|
||||
import { uploadFileChunk } from '@/api/tool/file';
|
||||
import { transferStaticFile, uploadFileChunk } from '@/api/tool/file';
|
||||
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
import { useRouter } from 'vue-router';
|
||||
const appStore = useAppStore();
|
||||
const router = useRouter();
|
||||
const { t, currentLocale, optionsLocale } = useI18n();
|
||||
|
||||
@@ -79,9 +80,10 @@ function fnSave() {
|
||||
// 发送请求
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
state.loading = true;
|
||||
transferHelpDoc({
|
||||
transferStaticFile({
|
||||
language: state.language,
|
||||
uploadPath: state.filePath,
|
||||
staticPath: appStore.helpDoc,
|
||||
}).then(res => {
|
||||
state.loading = false;
|
||||
hide();
|
||||
@@ -121,6 +123,7 @@ onMounted(() => {
|
||||
v-model:value="state.language"
|
||||
style="width: 100px"
|
||||
size="small"
|
||||
v-perms:has="['system:setting:i18n']"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="opt in optionsLocale"
|
||||
@@ -166,6 +169,7 @@ onMounted(() => {
|
||||
v-model:value="state.language"
|
||||
style="width: 100px"
|
||||
size="small"
|
||||
v-perms:has="['system:setting:i18n']"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="opt in optionsLocale"
|
||||
|
||||
143
src/views/system/setting/components/change-i18n.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<script lang="ts" setup>
|
||||
import { Modal, message } from 'ant-design-vue/lib';
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { changeValue } from '@/api/system/config';
|
||||
import { CACHE_LOCAL_I18N } from '@/constants/cache-keys-constants';
|
||||
import { localSet } from '@/utils/cache-local-utils';
|
||||
const appStore = useAppStore();
|
||||
const { t, optionsLocale } = useI18n();
|
||||
|
||||
type StateType = {
|
||||
edite: boolean;
|
||||
loading: boolean;
|
||||
open: boolean;
|
||||
default: string;
|
||||
};
|
||||
|
||||
let state: StateType = reactive({
|
||||
edite: false,
|
||||
loading: false,
|
||||
open: false,
|
||||
default: '',
|
||||
});
|
||||
|
||||
/**进入可编辑 */
|
||||
function fnEdit(v: boolean) {
|
||||
state.edite = v;
|
||||
if (!v) {
|
||||
state.open = appStore.i18nOpen;
|
||||
state.default = appStore.i18nDefault;
|
||||
}
|
||||
}
|
||||
|
||||
/**提交保存 */
|
||||
function fnSave() {
|
||||
Modal.confirm({
|
||||
title: t('common.tipTitle'),
|
||||
content: t('views.system.setting.sysOfficialUrlTipContent'),
|
||||
onOk() {
|
||||
// 发送请求
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
state.loading = true;
|
||||
Promise.all([
|
||||
changeValue({ key: 'sys.i18n.open', value: `${state.open}` }),
|
||||
changeValue({ key: 'sys.i18n.default', value: `${state.default}` }),
|
||||
])
|
||||
.then(resArr => {
|
||||
// 不判断
|
||||
message.success(t('views.system.setting.saveSuccess'), 3);
|
||||
appStore.i18nOpen = state.open;
|
||||
appStore.i18nDefault = state.default;
|
||||
localSet(CACHE_LOCAL_I18N, state.default);
|
||||
fnEdit(false);
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
hide();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
state.open = appStore.i18nOpen;
|
||||
state.default = appStore.i18nDefault;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24" style="margin-bottom: 30px">
|
||||
<a-form v-if="state.edite">
|
||||
<a-form-item :label="t('views.system.setting.i18nOpen')">
|
||||
<a-switch
|
||||
:checked-children="t('common.switch.open')"
|
||||
:un-checked-children="t('common.switch.shut')"
|
||||
v-model:checked="state.open"
|
||||
></a-switch>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('views.system.setting.i18nDefault')">
|
||||
<a-select v-model:value="state.default" style="width: 100px">
|
||||
<a-select-option
|
||||
v-for="opt in optionsLocale"
|
||||
:key="opt.value"
|
||||
:value="opt.value"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<a-button type="primary" @click="fnSave">
|
||||
{{ t('views.system.setting.saveSubmit') }}
|
||||
</a-button>
|
||||
<a-button style="margin-left: 10px" @click="fnEdit(false)">
|
||||
{{ t('common.cancel') }}
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<template v-else>
|
||||
<a-form-item :label="t('views.system.setting.i18nOpen')">
|
||||
<a-switch
|
||||
:disabled="true"
|
||||
:checked-children="t('common.switch.open')"
|
||||
:un-checked-children="t('common.switch.shut')"
|
||||
v-model:checked="state.open"
|
||||
></a-switch>
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('views.system.setting.i18nDefault')">
|
||||
<a-select
|
||||
v-model:value="state.default"
|
||||
style="width: 100px"
|
||||
:disabled="true"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="opt in optionsLocale"
|
||||
:key="opt.value"
|
||||
:value="opt.value"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-button type="dashed" @click="fnEdit(true)">
|
||||
{{ t('common.editText') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-typography>
|
||||
<a-typography-paragraph>
|
||||
{{ t('views.system.setting.i18nInstruction') }}
|
||||
</a-typography-paragraph>
|
||||
</a-typography>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -9,6 +9,7 @@ import { uploadFile } from '@/api/tool/file';
|
||||
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
import { sessionGet } from '@/utils/cache-session-utils';
|
||||
import { parseUrlPath } from '@/plugins/file-static-url';
|
||||
const appStore = useAppStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -84,7 +85,7 @@ function fnEdit(v: boolean) {
|
||||
state.edite = v;
|
||||
if (!v) {
|
||||
state.filePath = '#';
|
||||
state.flag = appStore.getLoginBackground;
|
||||
state.flag = parseUrlPath(appStore.loginBackground);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,8 +143,8 @@ function fnRevert() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
state.filePath = appStore.getLoginBackground;
|
||||
state.flag = appStore.getLoginBackground;
|
||||
state.filePath = parseUrlPath(appStore.loginBackground);
|
||||
state.flag = parseUrlPath(appStore.loginBackground);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -3,20 +3,21 @@ import { Modal, message } from 'ant-design-vue/lib';
|
||||
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
import IconFont from '@/components/IconFont/index.vue';
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { onMounted, reactive, watch, computed } from 'vue';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { uploadFile } from '@/api/tool/file';
|
||||
import { transferStaticFile, uploadFile } from '@/api/tool/file';
|
||||
import { changeValue } from '@/api/system/config';
|
||||
import { computed } from 'vue';
|
||||
import { sessionGet } from '@/utils/cache-session-utils';
|
||||
import { parseUrlPath } from '@/plugins/file-static-url';
|
||||
const appStore = useAppStore();
|
||||
const { t } = useI18n();
|
||||
const { t, currentLocale, optionsLocale } = useI18n();
|
||||
|
||||
type StateType = {
|
||||
edite: boolean;
|
||||
loading: boolean;
|
||||
language: string;
|
||||
filePath: string; // 是否上传文件
|
||||
flag: string; // 是否变更标记
|
||||
type: 'brand' | 'icon';
|
||||
@@ -27,6 +28,7 @@ type StateType = {
|
||||
let state: StateType = reactive({
|
||||
edite: false,
|
||||
loading: false,
|
||||
language: '',
|
||||
filePath: '',
|
||||
flag: '',
|
||||
type: 'icon',
|
||||
@@ -39,11 +41,14 @@ function fnBeforeUpload(file: FileType) {
|
||||
if (state.loading) return false;
|
||||
const isJpgOrPng = ['image/jpeg', 'image/png'].includes(file.type);
|
||||
if (!isJpgOrPng) {
|
||||
message.error('只支持上传图片格式(jpg、png)', 3);
|
||||
message.error(
|
||||
t('views.system.setting.uploadFormat', { format: 'jpg、png' }),
|
||||
3
|
||||
);
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('图片文件大小必须小于 2MB', 3);
|
||||
message.error(t('views.system.setting.uploadSize', { size: 2 }), 3);
|
||||
}
|
||||
return isJpgOrPng && isLt2M;
|
||||
}
|
||||
@@ -92,8 +97,8 @@ function fnEdit(v: boolean) {
|
||||
filePath: '',
|
||||
flag: `${appStore.logoType}/`,
|
||||
type: appStore.logoType,
|
||||
icon: appStore.getLOGOIcon,
|
||||
brand: appStore.getLOGOBrand,
|
||||
icon: getLogoURL('icon'),
|
||||
brand: getLogoURL('brand'),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -107,12 +112,16 @@ function fnSave() {
|
||||
const reqArr = [];
|
||||
// 改变LOGO地址
|
||||
if (state.filePath) {
|
||||
let changeFilePath = 'sys.logo.filePathIcon';
|
||||
let changeFilePath = appStore.filePathIcon;
|
||||
if (state.type === 'brand') {
|
||||
changeFilePath = 'sys.logo.filePathBrand';
|
||||
changeFilePath = appStore.filePathBrand;
|
||||
}
|
||||
reqArr.push(
|
||||
changeValue({ key: changeFilePath, value: state.filePath })
|
||||
transferStaticFile({
|
||||
language: state.language,
|
||||
uploadPath: state.filePath,
|
||||
staticPath: changeFilePath,
|
||||
})
|
||||
);
|
||||
}
|
||||
// 判断类型是否改变
|
||||
@@ -128,9 +137,6 @@ function fnSave() {
|
||||
hide();
|
||||
if (resArr[0].code === RESULT_CODE_SUCCESS) {
|
||||
message.success(t('views.system.setting.saveSuccess'), 3);
|
||||
if (state.filePath) {
|
||||
appStore.setLOGO(state.type, state.filePath);
|
||||
}
|
||||
if (state.type !== appStore.logoType) {
|
||||
appStore.logoType = state.type;
|
||||
}
|
||||
@@ -152,13 +158,38 @@ const changeStatus = computed(() => {
|
||||
return true;
|
||||
});
|
||||
|
||||
// LOGO地址
|
||||
function getLogoURL(type: 'brand' | 'icon') {
|
||||
let url =
|
||||
type === 'brand'
|
||||
? parseUrlPath(appStore.filePathBrand)
|
||||
: parseUrlPath(appStore.filePathIcon);
|
||||
if (url.indexOf('{language}') === -1) {
|
||||
return url;
|
||||
}
|
||||
// 语言参数替换
|
||||
const local = state.language;
|
||||
const lang = local.split('_')[0];
|
||||
return url.replace('{language}', lang || 'en');
|
||||
}
|
||||
|
||||
// 监听语言切换
|
||||
watch(
|
||||
() => state.language,
|
||||
() => {
|
||||
state.icon = getLogoURL('icon');
|
||||
state.brand = getLogoURL('brand');
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
Object.assign(state, {
|
||||
language: currentLocale.value,
|
||||
filePath: '',
|
||||
flag: `${appStore.logoType}/`,
|
||||
type: appStore.logoType,
|
||||
icon: appStore.getLOGOIcon,
|
||||
brand: appStore.getLOGOBrand,
|
||||
icon: getLogoURL('icon'),
|
||||
brand: getLogoURL('brand'),
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -166,21 +197,39 @@ onMounted(() => {
|
||||
<template>
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24" style="margin-bottom: 30px">
|
||||
<div class="header">
|
||||
<div class="header-brand" v-show="state.type === 'brand'">
|
||||
<img :width="174" :height="48" :src="state.brand" />
|
||||
</div>
|
||||
<div class="header-icon" v-show="state.type === 'icon'">
|
||||
<img :src="state.icon" />
|
||||
<h1 :title="appStore.appName">
|
||||
{{ appStore.appName }}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="header-menu">
|
||||
<IconFont type="icon-pcduan" style="margin-right: 10px"></IconFont>
|
||||
{{ t('router.index') }}
|
||||
</div>
|
||||
</div>
|
||||
<a-form layout="vertical">
|
||||
<a-form-item style="margin-bottom: 12px">
|
||||
<div class="header">
|
||||
<div class="header-brand" v-show="state.type === 'brand'">
|
||||
<img :width="174" :height="48" :src="state.brand" />
|
||||
</div>
|
||||
<div class="header-icon" v-show="state.type === 'icon'">
|
||||
<img :src="state.icon" />
|
||||
<h1 :title="appStore.appName">
|
||||
{{ appStore.appName }}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="header-menu">
|
||||
<IconFont
|
||||
type="icon-pcduan"
|
||||
style="margin-right: 10px"
|
||||
></IconFont>
|
||||
{{ t('router.index') }}
|
||||
</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item v-perms:has="['system:setting:i18n']">
|
||||
<a-select v-model:value="state.language" style="width: 100px">
|
||||
<a-select-option
|
||||
v-for="opt in optionsLocale"
|
||||
:key="opt.value"
|
||||
:value="opt.value"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<a-form layout="vertical" v-if="state.edite">
|
||||
<a-form-item>
|
||||
@@ -257,7 +306,6 @@ onMounted(() => {
|
||||
height: 48px;
|
||||
padding-left: 16px;
|
||||
background-color: #001529;
|
||||
margin-bottom: 24px;
|
||||
|
||||
&-brand {
|
||||
width: 174px;
|
||||
|
||||
@@ -6,6 +6,7 @@ import ChangeTitle from './components/change-title.vue';
|
||||
import ChangeCopyright from './components/change-copyright.vue';
|
||||
import ChangeHelpDoc from './components/change-help-doc.vue';
|
||||
import ChangeOfficialUrl from './components/change-official-url.vue';
|
||||
import ChangeI18n from './components/change-i18n.vue';
|
||||
import useI18n from '@/hooks/useI18n';
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
@@ -29,14 +30,20 @@ const { t } = useI18n();
|
||||
{{ t('views.system.setting.sysLoginBg') }}
|
||||
</a-divider>
|
||||
<ChangeLogoBG></ChangeLogoBG>
|
||||
<a-divider orientation="left">
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.system.setting.sysHelpDoc') }}
|
||||
</a-divider>
|
||||
</a-divider>
|
||||
<ChangeHelpDoc></ChangeHelpDoc>
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.system.setting.sysOfficialUrl') }}
|
||||
</a-divider>
|
||||
<ChangeOfficialUrl></ChangeOfficialUrl>
|
||||
<div v-perms:has="['system:setting:i18n']">
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.system.setting.i18n') }}
|
||||
</a-divider>
|
||||
<ChangeI18n></ChangeI18n>
|
||||
</div>
|
||||
</a-card>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
@@ -135,7 +135,7 @@ let tableColumns: ColumnsType = [
|
||||
{
|
||||
title: t('views.system.user.permission'),
|
||||
key: 'roles',
|
||||
align: 'center',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('views.system.user.className'),
|
||||
@@ -889,7 +889,7 @@ onMounted(() => {
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<!-- 插槽-卡片左侧侧 -->
|
||||
<template #title>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-button
|
||||
type="primary"
|
||||
@click.prevent="fnModalVisibleByEdit()"
|
||||
@@ -924,12 +924,12 @@ onMounted(() => {
|
||||
<template #icon><ExportOutlined /></template>
|
||||
{{ t('common.export') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 插槽-卡片右侧 -->
|
||||
<template #extra>
|
||||
<a-space :size="8" align="center">
|
||||
<div class="button-container">
|
||||
<a-tooltip>
|
||||
<template #title>{{ t('common.searchBarText') }}</template>
|
||||
<a-switch
|
||||
@@ -978,7 +978,7 @@ onMounted(() => {
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格列表 -->
|
||||
@@ -1258,7 +1258,12 @@ onMounted(() => {
|
||||
@ok="fnModalOk"
|
||||
@cancel="fnModalCancel"
|
||||
>
|
||||
<a-form name="modalStateFromByEdit" layout="horizontal">
|
||||
<a-form
|
||||
name="modalStateFromByEdit"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 6 }"
|
||||
:labelWrap="true"
|
||||
>
|
||||
<a-row :gutter="16" v-if="!modalState.from.userId">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
@@ -1309,22 +1314,20 @@ onMounted(() => {
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="6" :xs="24">
|
||||
<a-form-item :label="t('views.system.user.sex')" name="sex">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.user.userWork')"
|
||||
name="postIds"
|
||||
>
|
||||
<a-select
|
||||
v-model:value="modalState.from.sex"
|
||||
default-value="1"
|
||||
:options="dict.sysUserSex"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6" :md="6" :xs="24">
|
||||
<a-form-item :label="t('views.system.user.status')" name="status">
|
||||
<a-select
|
||||
v-model:value="modalState.from.status"
|
||||
default-value="0"
|
||||
:options="dict.sysNormalDisable"
|
||||
v-model:value="modalState.from.postIds"
|
||||
allow-clear
|
||||
mode="multiple"
|
||||
show-search
|
||||
option-filter-prop="postName"
|
||||
option-label-prop="postName"
|
||||
:options="modalState.options.posts"
|
||||
:field-names="{ label: 'postName', value: 'postId' }"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
@@ -1360,7 +1363,53 @@ onMounted(() => {
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item :label="t('views.system.user.fromClass')" name="deptId">
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.system.user.sex')" name="sex">
|
||||
<a-select
|
||||
v-model:value="modalState.from.sex"
|
||||
default-value="1"
|
||||
:options="dict.sysUserSex"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.system.user.status')" name="status">
|
||||
<a-select
|
||||
v-model:value="modalState.from.status"
|
||||
default-value="0"
|
||||
:options="dict.sysNormalDisable"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item
|
||||
:label="t('views.system.user.permission')"
|
||||
name="roleIds"
|
||||
:label-col="{ span: 3 }"
|
||||
v-perms:has="['system:user:editRole']"
|
||||
>
|
||||
<a-select
|
||||
v-model:value="modalState.from.roleIds"
|
||||
:allow-clear="false"
|
||||
mode="multiple"
|
||||
show-search
|
||||
option-filter-prop="roleName"
|
||||
option-label-prop="roleName"
|
||||
:options="modalState.options.roles"
|
||||
:field-names="{ label: 'roleName', value: 'roleId' }"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
:label="t('views.system.user.fromClass')"
|
||||
name="deptId"
|
||||
:label-col="{ span: 3 }"
|
||||
>
|
||||
<a-tree-select
|
||||
v-model:value="modalState.from.deptId"
|
||||
show-search
|
||||
@@ -1379,46 +1428,11 @@ onMounted(() => {
|
||||
</a-tree-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.user.userWork')"
|
||||
name="postIds"
|
||||
>
|
||||
<a-select
|
||||
v-model:value="modalState.from.postIds"
|
||||
allow-clear
|
||||
mode="multiple"
|
||||
show-search
|
||||
option-filter-prop="postName"
|
||||
option-label-prop="postName"
|
||||
:options="modalState.options.posts"
|
||||
:field-names="{ label: 'postName', value: 'postId' }"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.system.user.permission')"
|
||||
name="roleIds"
|
||||
>
|
||||
<a-select
|
||||
v-model:value="modalState.from.roleIds"
|
||||
:allow-clear="false"
|
||||
mode="multiple"
|
||||
show-search
|
||||
option-filter-prop="roleName"
|
||||
option-label-prop="roleName"
|
||||
:options="modalState.options.roles"
|
||||
:field-names="{ label: 'roleName', value: 'roleId' }"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item :label="t('views.system.user.userTip')" name="remark">
|
||||
<a-form-item
|
||||
:label="t('views.system.user.userTip')"
|
||||
name="remark"
|
||||
:label-col="{ span: 3 }"
|
||||
>
|
||||
<a-textarea
|
||||
v-model:value="modalState.from.remark"
|
||||
:auto-size="{ minRows: 4, maxRows: 6 }"
|
||||
|
||||
@@ -6,13 +6,14 @@ import { useRoute } from 'vue-router';
|
||||
import { VuePDF, usePDF } from '@tato30/vue-pdf';
|
||||
import '@tato30/vue-pdf/style.css';
|
||||
import saveAs from 'file-saver';
|
||||
import { parseUrlPath } from '@/plugins/file-static-url';
|
||||
const { t, currentLocale } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
const route = useRoute();
|
||||
|
||||
// 文档地址
|
||||
const docUrl = computed(() => {
|
||||
let url = appStore.getHelpDoc;
|
||||
let url = parseUrlPath(appStore.helpDoc);
|
||||
if (url.indexOf('{language}') === -1) {
|
||||
return url;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
tcpdumpPcapDownload,
|
||||
} from '@/api/traceManage/pcap';
|
||||
import { ref } from 'vue';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
/**对话框对象信息状态类型 */
|
||||
@@ -136,6 +137,7 @@ function fnStart() {
|
||||
cmd: from.cmd,
|
||||
})
|
||||
.then(res => {
|
||||
console.log(res)
|
||||
if (res.code === RESULT_CODE_SUCCESS) {
|
||||
message.success({
|
||||
content: t('views.traceManage.pcap.execSuccess'),
|
||||
@@ -151,7 +153,7 @@ function fnStart() {
|
||||
msg.indexOf('tcpdump: listening on any,') !== -1;
|
||||
} else if (
|
||||
res.code === RESULT_CODE_ERROR &&
|
||||
res.msg.includes('timeout')
|
||||
res.msg.includes('imeout')
|
||||
) {
|
||||
message.warning({
|
||||
content: t('views.traceManage.pcap.execBreak'),
|
||||
@@ -337,7 +339,7 @@ onUnmounted(() => {
|
||||
>
|
||||
<a-cascader
|
||||
v-model:value="modalState.neType"
|
||||
:options="useNeInfoStore().getNeCascaderOtions"
|
||||
:options="neInfoStore.getNeCascaderOptions"
|
||||
@change="fnNeChange"
|
||||
:allow-clear="false"
|
||||
:placeholder="t('views.traceManage.pcap.neTypePlease')"
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
} from '@/api/traceManage/task';
|
||||
import useDictStore from '@/store/modules/dict';
|
||||
import { regExpIPv4, regExpPort } from '@/utils/regular-utils';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const { getDict } = useDictStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -382,7 +383,7 @@ function fnSelectInterface(s: any, _: any) {
|
||||
|
||||
/**信令接口选择初始 */
|
||||
function fnSelectInterfaceInit(neType: string) {
|
||||
const interfaces = useNeInfoStore().traceInterfaceList;
|
||||
const interfaces = neInfoStore.traceInterfaceList;
|
||||
modalState.neTypeInterface = interfaces
|
||||
.filter(i => i.neType === neType)
|
||||
.map(i => {
|
||||
@@ -535,9 +536,9 @@ onMounted(() => {
|
||||
});
|
||||
Promise.allSettled([
|
||||
// 获取网元网元列表
|
||||
useNeInfoStore().fnNelist(),
|
||||
neInfoStore.fnNelist(),
|
||||
// 获取跟踪接口列表
|
||||
useNeInfoStore().fnNeTraceInterface(),
|
||||
neInfoStore.fnNeTraceInterface(),
|
||||
]).finally(() => {
|
||||
// 获取列表数据
|
||||
fnGetList();
|
||||
@@ -562,7 +563,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-auto-complete
|
||||
v-model:value="queryParams.neType"
|
||||
:options="useNeInfoStore().getNeSelectOtions"
|
||||
:options="neInfoStore.getNeSelectOtions"
|
||||
allow-clear
|
||||
:placeholder="t('views.traceManage.task.neTypePlease')"
|
||||
/>
|
||||
@@ -748,7 +749,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-cascader
|
||||
:value="modalState.neType"
|
||||
:options="useNeInfoStore().getNeCascaderOtions"
|
||||
:options="neInfoStore.getNeCascaderOptions"
|
||||
disabled
|
||||
/>
|
||||
</a-form-item>
|
||||
@@ -866,7 +867,7 @@ onMounted(() => {
|
||||
>
|
||||
<a-cascader
|
||||
v-model:value="modalState.neType"
|
||||
:options="useNeInfoStore().getNeCascaderOtions"
|
||||
:options="neInfoStore.getNeCascaderOptions"
|
||||
@change="fnNeChange"
|
||||
:allow-clear="false"
|
||||
:placeholder="t('views.traceManage.task.neTypePlease')"
|
||||
|
||||
@@ -21,7 +21,7 @@ export default defineConfig(({ mode }) => {
|
||||
// https://cn.vitejs.dev/config/#server-proxy
|
||||
[env.VITE_API_BASE_URL]: {
|
||||
// target: 'http://192.168.2.166:3030',
|
||||
target: 'http://192.168.2.114:3040',
|
||||
target: 'http://192.168.5.58:3040',
|
||||
changeOrigin: true,
|
||||
rewrite: p => p.replace(env.VITE_API_BASE_URL, ''),
|
||||
},
|
||||
@@ -70,7 +70,7 @@ export default defineConfig(({ mode }) => {
|
||||
verbose: false,
|
||||
algorithm: 'gzip',
|
||||
ext: '.gz',
|
||||
disable: false, // 是否禁用
|
||||
disable: true, // 是否禁用
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||