fix: 优化PCF用户策略页面及接口调整

This commit is contained in:
TsMask
2025-04-30 16:55:16 +08:00
parent f0fd698bec
commit d3b9f21511
5 changed files with 488 additions and 626 deletions

View File

@@ -33,53 +33,3 @@ export async function updateNeConfigReload(neType: string, neId: string) {
} }
return result; return result;
} }
/**
* 从参数配置PCF中获取对应信息提供给PCC用户策略输入框
* @param neId
* @returns object {pccRules,sessionRules,qosTemplate,headerEnrichTemplate,serviceAreaRestriction}
*/
export async function getPCCRule(neId: any) {
const paramNameArr = [
'pccRules',
'sessionRules',
'qosTemplate',
'headerEnrichTemplate',
'serviceAreaRestriction',
];
const reqArr = [];
for (const paramName of paramNameArr) {
reqArr.push(
request({
url: `/ne/config/data`,
params: { neType: 'PCF', neId, paramName },
method: 'GET',
})
);
}
return await Promise.allSettled(reqArr).then(resArr => {
// 规则数据
const obj: any = {};
resArr.forEach((item, i: number) => {
if (item.status === 'fulfilled') {
const res = item.value;
if (res.code === RESULT_CODE_SUCCESS) {
const key = paramNameArr[i];
obj[key] = res.data.map((item: any) => {
if ('qosTemplate' === key) {
return { value: item.qosId, label: item.qosId };
}
if ('headerEnrichTemplate' === key) {
return { value: item.templateName, label: item.templateName };
}
if ('serviceAreaRestriction' === key) {
return { value: item.name, label: item.name };
}
return { value: item.ruleId, label: item.ruleId };
});
}
}
});
return obj;
});
}

View File

@@ -1,3 +1,4 @@
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { request } from '@/plugins/http-fetch'; import { request } from '@/plugins/http-fetch';
/** /**
@@ -64,3 +65,53 @@ export function delNeConfigData(params: Record<string, any>) {
params, params,
}); });
} }
/**
* 从参数配置PCF中获取对应信息提供给PCF用户策略输入框
* @param neId
* @returns object {pccRules,sessionRules,qosTemplate,headerEnrichTemplate,serviceAreaRestriction}
*/
export async function getPCFRule(neId: any) {
const paramNameArr = [
'pccRules',
'sessionRules',
'qosTemplate',
'headerEnrichTemplate',
'serviceAreaRestriction',
];
const reqArr = [];
for (const paramName of paramNameArr) {
reqArr.push(
request({
url: `/ne/config/data`,
params: { neType: 'PCF', neId, paramName },
method: 'GET',
})
);
}
return await Promise.allSettled(reqArr).then(resArr => {
// 规则数据
const obj: any = {};
resArr.forEach((item, i: number) => {
if (item.status === 'fulfilled') {
const res = item.value;
if (res.code === RESULT_CODE_SUCCESS) {
const key = paramNameArr[i];
obj[key] = res.data.map((item: any) => {
if ('qosTemplate' === key) {
return { value: item.qosId, label: item.qosId };
}
if ('headerEnrichTemplate' === key) {
return { value: item.templateName, label: item.templateName };
}
if ('serviceAreaRestriction' === key) {
return { value: item.name, label: item.name };
}
return { value: item.ruleId, label: item.ruleId };
});
}
}
});
return obj;
});
}

82
src/api/neData/pcf.ts Normal file
View File

@@ -0,0 +1,82 @@
import { request } from '@/plugins/http-fetch';
/**
* PCF-策略配置列表
* @param query 查询参数
* @returns object
*/
export function listPCFRule(query: Record<string, any>) {
return request({
url: '/neData/pcf/rule/list',
method: 'GET',
params: query,
timeout: 60_000,
});
}
/**
* PCF-策略配置添加
* @param data 参数
* @returns object
*/
export function addPCFRule(data: Record<string, any>) {
return request({
url: `/neData/pcf/rule`,
method: 'POST',
data,
});
}
/**
* PCF-策略配置更新
* @param data 参数
* @returns object
*/
export function editPCFRule(data: Record<string, any>) {
return request({
url: `/neData/pcf/rule`,
method: 'PUT',
data,
});
}
/**
* PCF-策略配置删除
*@param data 参数
* @returns object
*/
export function delPCFRule(data: Record<string, any>) {
return request({
url: `/neData/pcf/rule`,
method: 'DELETE',
params: data,
});
}
/**
* PCF-策略配置导出
* @param data 参数{ neId, fileType }
* @returns object
*/
export function exportPCFRule(data: Record<string, any>) {
return request({
url: '/neData/pcf/rule/export',
method: 'GET',
params: data,
responseType: 'blob',
timeout: 60_000,
});
}
/**
* PCF-策略配置导入
* @param data 参数
* @returns object
*/
export function importPCFRule(data: Record<string, any>) {
return request({
url: '/neData/pcf/rule/import',
method: 'PUT',
data,
});
}

View File

@@ -1,233 +0,0 @@
import {
RESULT_CODE_ERROR,
RESULT_CODE_SUCCESS,
} from '@/constants/result-constants';
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: 'GET',
params: data,
responseType: 'blob',
timeout: 180_000,
});
}
/**
* 导入规则数据
* @param data 表单数据对象
* @returns object
*/
export function importRuleData(data: Record<string, any>) {
return request({
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,
});
}
/**
* 查询规则列表
* @param query 查询参数
* @returns object
*/
export async function listRules(query: Record<string, any>) {
const result = await request({
url: '/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo',
method: 'GET',
params: query,
});
const data = {
data: { total: 0, rows: [] } as any,
code: result.code,
msg: result.msg,
};
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
if (result.data?.status) {
return {
code: RESULT_CODE_ERROR,
msg: result.data?.cause,
data: result.data,
};
}
if (Array.isArray(result.data.data)) {
const rows = parseObjLineToHump(result.data.data);
data.data.total = rows.length;
data.data.rows = rows;
}
}
// 模拟数据
// data.rows = [
// {
// "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;
}
/**
* 查询规则详细
* @param neId 网元ID
* @returns object
*/
export async function getRule(neId: string, imsi: string) {
const result = await request({
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${neId}&imsi=${imsi}`,
method: 'GET',
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) {
result.data = result.data.data[0];
}
return result;
}
/**
* 修改规则
* @param data 规则对象
* @returns object
*/
export async function updateRule(data: Record<string, any>) {
const result = await request({
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${data.neId}`,
method: 'PUT',
data: data,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && result.data?.status) {
return {
code: RESULT_CODE_ERROR,
msg: result.data?.cause,
data: result.data,
};
}
return result;
}
/**
* 批量修改规则
* @param data 规则对象
* @returns object
*/
export async function batchUpdateRule(data: Record<string, any>) {
const result = await request({
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
method: 'PUT',
data: data,
timeout: 60_000,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
if (result.data?.status) {
return {
code: RESULT_CODE_ERROR,
msg: result.data?.cause,
data: result.data,
};
}
if (result.data?.data) {
result.data = result.data.data;
return result;
}
}
return result;
}
/**
* 新增规则
* @param data 规则对象
* @returns object
*/
export async function addRule(data: Record<string, any>) {
const result = await request({
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${data.neId}`,
method: 'POST',
data: data,
timeout: 60_000,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS && result.data?.status) {
return {
code: RESULT_CODE_ERROR,
msg: result.data?.cause,
data: result.data,
};
}
return result;
}
/**
* 批量新增规则
* @param data 规则对象
* @returns object
*/
export async function batchAddRule(data: Record<string, any>) {
const result = await request({
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}`,
method: 'POST',
data: data,
timeout: 60_000,
});
// 解析数据
if (result.code === RESULT_CODE_SUCCESS) {
if (result.data?.status) {
return {
code: RESULT_CODE_ERROR,
msg: result.data?.cause,
data: result.data,
};
}
if (result.data?.data) {
result.data = result.data.data;
return result;
}
}
return result;
}
/**
* 删除规则
* @param data 规则对象
* @returns object
*/
export function delRule(neId: string, imsi: string) {
return request({
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo?neId=${neId}&imsi=${imsi}`,
method: 'DELETE',
timeout: 60_000,
});
}
/**
* 批量删除规则
* @param data 规则对象
* @returns object
*/
export async function batchDelRule(data: Record<string, any>) {
return request({
url: `/api/rest/ueManagement/v1/elementType/pcf/objectType/ueInfo/batch/${data.num}?neId=${data.neId}&imsi=${data.imsi}`,
method: 'DELETE',
timeout: 60_000,
});
}

View File

@@ -6,24 +6,20 @@ import { message, Modal, Form, TableColumnsType } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider'; import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import UploadModal from '@/components/UploadModal/index.vue'; import UploadModal from '@/components/UploadModal/index.vue';
import {
listRules,
getRule,
updateRule,
addRule,
delRule,
exportRule,
importRuleData,
batchAddRule,
batchDelRule,
batchUpdateRule,
} from '@/api/neUser/pcf';
import { getPCCRule } from '@/api/configManage/configParam';
import useNeInfoStore from '@/store/modules/neinfo'; import useNeInfoStore from '@/store/modules/neinfo';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import {
addPCFRule,
delPCFRule,
editPCFRule,
exportPCFRule,
importPCFRule,
listPCFRule,
} from '@/api/neData/pcf';
import { getPCFRule } from '@/api/ne/neConfig';
import { uploadFileToNE } from '@/api/tool/file';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
import { uploadFileToNE } from '@/api/tool/file';
const { t } = useI18n(); const { t } = useI18n();
/**网元参数 */ /**网元参数 */
@@ -149,7 +145,7 @@ let tableColumns = ref<TableColumnsType>([
dataIndex: 'pccRules', dataIndex: 'pccRules',
align: 'left', align: 'left',
resizable: true, resizable: true,
width: 150, width: 200,
minWidth: 100, minWidth: 100,
maxWidth: 300, maxWidth: 300,
}, },
@@ -157,7 +153,10 @@ let tableColumns = ref<TableColumnsType>([
title: 'SESS Rules', title: 'SESS Rules',
dataIndex: 'sessRules', dataIndex: 'sessRules',
align: 'left', align: 'left',
width: 150, resizable: true,
width: 200,
minWidth: 100,
maxWidth: 300,
}, },
{ {
title: 'HDR Enrich', title: 'HDR Enrich',
@@ -169,13 +168,13 @@ let tableColumns = ref<TableColumnsType>([
title: 'UE Policy', title: 'UE Policy',
dataIndex: 'uePolicy', dataIndex: 'uePolicy',
align: 'left', align: 'left',
width: 150,
}, },
{ {
title: t('common.operate'), title: t('common.operate'),
key: 'imsi', key: 'imsi',
align: 'left', align: 'left',
width: 100, width: 150,
fixed: 'right',
}, },
]); ]);
@@ -241,7 +240,7 @@ let modalState: ModalStateType = reactive({
openByEdit: false, openByEdit: false,
title: '用户策略', title: '用户策略',
from: { from: {
num: 1, num: undefined,
imsi: '', imsi: '',
msisdn: '', msisdn: '',
qosAudio: '', qosAudio: '',
@@ -265,11 +264,13 @@ const modalStateFrom = Form.useForm(
num: [ num: [
{ {
required: true, required: true,
message: t('views.neUser.pcf.batchNum') + t('common.unableNull'), message: t('views.neData.common.batchNum'),
}, },
], ],
imsi: [{ required: true, message: `IMSI ${t('common.unableNull')}` }], imsi: [{ required: true, message: t('views.neData.common.imsiPlease') }],
msisdn: [{ required: true, message: `MSISDN ${t('common.unableNull')}` }], msisdn: [
{ required: true, message: t('views.neData.common.msisdnPlease') },
],
}) })
); );
@@ -278,7 +279,7 @@ const modalStateFrom = Form.useForm(
* @param noticeId 网元id, 不传为新增 * @param noticeId 网元id, 不传为新增
*/ */
function fnModalVisibleByEdit(row?: Record<string, any>) { function fnModalVisibleByEdit(row?: Record<string, any>) {
getPCCRule(queryParams.neId) getPCFRule(queryParams.neId)
.then((data: any) => { .then((data: any) => {
pcfRuleOption.value = data; pcfRuleOption.value = data;
}) })
@@ -286,20 +287,14 @@ function fnModalVisibleByEdit(row?: Record<string, any>) {
modalState.isBatch = false; modalState.isBatch = false;
if (!row) { if (!row) {
modalStateFrom.resetFields(); //重置表单 modalStateFrom.resetFields(); //重置表单
modalState.title = t('views.neUser.pcf.addTitle'); modalState.title = t('views.neData.pcfSub.addTitle');
modalState.openByEdit = true; modalState.openByEdit = true;
modalState.type = 'add'; modalState.type = 'add';
} else { } else {
if (modalState.confirmLoading) return; Object.assign(modalState.from, row);
const hide = message.loading(t('common.loading'), 0);
modalState.confirmLoading = true;
const neID = queryParams.neId || '-';
getRule(neID, row.imsi)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
Object.assign(modalState.from, res.data);
let pccRules = res.data.pccRules; // 处理多选框数据
let pccRules = row.pccRules;
if (!pccRules) { if (!pccRules) {
pccRules = []; pccRules = [];
} else if (pccRules.includes('|')) { } else if (pccRules.includes('|')) {
@@ -308,7 +303,8 @@ function fnModalVisibleByEdit(row?: Record<string, any>) {
pccRules = [pccRules]; pccRules = [pccRules];
} }
modalState.from.pccRules = pccRules; modalState.from.pccRules = pccRules;
let sessRules = res.data.sessRules; // 处理多选框数据
let sessRules = row.sessRules;
if (!sessRules) { if (!sessRules) {
sessRules = []; sessRules = [];
} else if (sessRules.includes('|')) { } else if (sessRules.includes('|')) {
@@ -318,19 +314,12 @@ function fnModalVisibleByEdit(row?: Record<string, any>) {
} }
modalState.from.sessRules = sessRules; modalState.from.sessRules = sessRules;
modalState.title = t('views.neUser.pcf.updateTitle', { // 打开对话框
modalState.title = t('views.neData.pcfSub.updateTitle', {
imsi: row.imsi, imsi: row.imsi,
}); });
modalState.openByEdit = true; modalState.openByEdit = true;
modalState.type = 'update'; modalState.type = 'update';
} else {
message.error(t('common.getInfoFail'), 2);
}
})
.finally(() => {
hide();
modalState.confirmLoading = false;
});
} }
}); });
} }
@@ -341,8 +330,9 @@ function fnModalVisibleByEdit(row?: Record<string, any>) {
*/ */
function fnModalOk() { function fnModalOk() {
const from = JSON.parse(JSON.stringify(modalState.from)); const from = JSON.parse(JSON.stringify(modalState.from));
from.neId = queryParams.neId || '-'; const neId = queryParams.neId || '-';
from.rfsp = Number(from.rfsp) || 0; from.rfsp = Number(from.rfsp) || 0;
// 处理多选框数据
let pccRules = modalState.from.pccRules; let pccRules = modalState.from.pccRules;
if (Array.isArray(pccRules)) { if (Array.isArray(pccRules)) {
pccRules = pccRules.join('|'); pccRules = pccRules.join('|');
@@ -350,7 +340,7 @@ function fnModalOk() {
pccRules = ''; pccRules = '';
} }
from.pccRules = pccRules; from.pccRules = pccRules;
// 处理多选框数据
let sessRules = modalState.from.sessRules; let sessRules = modalState.from.sessRules;
if (Array.isArray(sessRules)) { if (Array.isArray(sessRules)) {
sessRules = sessRules.join('|'); sessRules = sessRules.join('|');
@@ -359,6 +349,7 @@ function fnModalOk() {
} }
from.sessRules = sessRules; from.sessRules = sessRules;
// 必要字段校验
let validateArr = ['imsi', 'msisdn']; let validateArr = ['imsi', 'msisdn'];
if (modalState.isBatch) { if (modalState.isBatch) {
validateArr.push('num'); validateArr.push('num');
@@ -377,20 +368,40 @@ function fnModalOk() {
let result: any = null; let result: any = null;
if (modalState.isBatch) { if (modalState.isBatch) {
if (modalState.type === 'add') { if (modalState.type === 'add') {
result = batchAddRule(from); result = addPCFRule({
neId: neId,
num: from.num,
paramData: from,
});
} }
if (modalState.type === 'update') { if (modalState.type === 'update') {
result = batchUpdateRule(from); result = editPCFRule({
neId: neId,
num: from.num,
paramData: from,
});
} }
if (modalState.type === 'delete') { if (modalState.type === 'delete') {
result = batchDelRule(from); result = delPCFRule({
neId: neId,
num: from.num,
imsi: from.imsi,
});
} }
} else { } else {
if (modalState.type === 'add') { if (modalState.type === 'add') {
result = addRule(from); result = addPCFRule({
neId: neId,
num: 0,
paramData: from,
});
} }
if (modalState.type === 'update') { if (modalState.type === 'update') {
result = updateRule(from); result = editPCFRule({
neId: neId,
num: 0,
paramData: from,
});
} }
} }
@@ -454,7 +465,7 @@ function fnModalCancel() {
* @param type 类型 * @param type 类型
*/ */
function fnModalVisibleByBatch(type: 'delete' | 'add' | 'update') { function fnModalVisibleByBatch(type: 'delete' | 'add' | 'update') {
getPCCRule(queryParams.neId) getPCFRule(queryParams.neId)
.then((data: any) => { .then((data: any) => {
pcfRuleOption.value = data; pcfRuleOption.value = data;
console.log(data); console.log(data);
@@ -462,17 +473,18 @@ function fnModalVisibleByBatch(type: 'delete' | 'add' | 'update') {
.finally(() => { .finally(() => {
modalStateFrom.resetFields(); //重置表单 modalStateFrom.resetFields(); //重置表单
modalState.isBatch = true; modalState.isBatch = true;
modalState.from.num = 1;
modalState.type = type; modalState.type = type;
if (type === 'add') { if (type === 'add') {
modalState.title = t('views.neUser.pcf.batchAddText'); modalState.title = t('views.neData.common.batchAddText');
modalState.openByEdit = true; modalState.openByEdit = true;
} }
if (type === 'update') { if (type === 'update') {
modalState.title = t('views.neUser.pcf.batchUpdateText'); modalState.title = t('views.neData.common.batchUpdateText');
modalState.openByEdit = true; modalState.openByEdit = true;
} }
if (type === 'delete') { if (type === 'delete') {
modalState.title = t('views.neUser.pcf.batchDelText'); modalState.title = t('views.neData.common.batchDelText');
modalState.openByEdit = true; modalState.openByEdit = true;
} }
}); });
@@ -483,8 +495,8 @@ function fnModalVisibleByBatch(type: 'delete' | 'add' | 'update') {
* @param imsi 网元编号ID * @param imsi 网元编号ID
*/ */
function fnRecordDelete(imsi: string) { function fnRecordDelete(imsi: string) {
const neID = queryParams.neId; const neId = queryParams.neId;
if (!neID) return; if (!neId) return;
let imsiMsg = imsi; let imsiMsg = imsi;
if (imsi === '0') { if (imsi === '0') {
imsiMsg = `${tableState.selectedRowKeys[0]}... ${tableState.selectedRowKeys.length}`; imsiMsg = `${tableState.selectedRowKeys[0]}... ${tableState.selectedRowKeys.length}`;
@@ -493,25 +505,29 @@ function fnRecordDelete(imsi: string) {
Modal.confirm({ Modal.confirm({
title: t('common.tipTitle'), title: t('common.tipTitle'),
content: t('views.neUser.pcf.delSure', { imsi: imsiMsg }), content: t('views.neData.pcfSub.delSure', { imsi: imsiMsg }),
onOk() { onOk() {
const key = 'delRule'; const hide = message.loading(t('common.loading'), 0);
message.loading({ content: t('common.loading'), key }); delPCFRule({
delRule(neID, imsi).then(res => { neId: neId,
imsi: imsi,
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) { if (res.code === RESULT_CODE_SUCCESS) {
message.success({ message.success({
content: `${res.msg}`, content: `${t('common.operateOk')}`,
key,
duration: 3, duration: 3,
}); });
fnGetList();
} else { } else {
message.error({ message.error({
content: `${res.msg}`, content: `${res.msg}`,
key: key,
duration: 3, duration: 3,
}); });
} }
})
.finally(() => {
hide();
fnGetList();
}); });
}, },
}); });
@@ -519,28 +535,29 @@ function fnRecordDelete(imsi: string) {
/**列表导出 */ /**列表导出 */
function fnExportList(type: string) { function fnExportList(type: string) {
const neID = queryParams.neId; const neId = queryParams.neId;
if (!neID) return; if (!neId) return;
const key = 'exportRule'; const hide = message.loading(t('common.loading'), 0);
message.loading({ content: t('common.loading'), key }); exportPCFRule({
exportRule({ neId: neId,
neId: neID,
fileType: type, fileType: type,
}).then(res => { })
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) { if (res.code === RESULT_CODE_SUCCESS) {
message.success({ message.success({
content: t('common.msgSuccess', { msg: t('common.export') }), content: t('common.msgSuccess', { msg: t('common.export') }),
key, duration: 3,
duration: 2,
}); });
saveAs(res.data, `PCF_${neID}_${Date.now()}.${type}`); saveAs(res.data, `PCFRlue_${neId}_${Date.now()}.${type}`);
} else { } else {
message.error({ message.error({
content: `${res.msg}`, content: `${res.msg}`,
key, duration: 3,
duration: 2,
}); });
} }
})
.finally(() => {
hide();
}); });
} }
@@ -552,15 +569,14 @@ function fnGetList(pageNum?: number) {
queryParams.pageNum = pageNum; queryParams.pageNum = pageNum;
tablePagination.current = pageNum; tablePagination.current = pageNum;
} }
listRules(toRaw(queryParams)).then(res => { listPCFRule(toRaw(queryParams)).then(res => {
if (res.code === RESULT_CODE_SUCCESS) { if (res.code === RESULT_CODE_SUCCESS) {
// 取消勾选 // 取消勾选
if (tableState.selectedRowKeys.length > 0) { if (tableState.selectedRowKeys.length > 0) {
tableState.selectedRowKeys = []; tableState.selectedRowKeys = [];
} }
const { total, rows } = res.data; tablePagination.total = res.data.length;
tablePagination.total = total; tableState.data = res.data;
tableState.data = rows;
} else { } else {
tableState.data = []; tableState.data = [];
} }
@@ -578,6 +594,8 @@ type ModalUploadImportStateType = {
loading: boolean; loading: boolean;
/**上传结果信息 */ /**上传结果信息 */
msg: string; msg: string;
/**含失败信息 */
hasFail: boolean;
}; };
/**对话框表格信息导入对象信息状态 */ /**对话框表格信息导入对象信息状态 */
@@ -586,6 +604,7 @@ let uploadImportState: ModalUploadImportStateType = reactive({
title: t('components.UploadModal.uploadTitle'), title: t('components.UploadModal.uploadTitle'),
loading: false, loading: false,
msg: '', msg: '',
hasFail: false,
}); });
/**对话框表格信息导入弹出窗口 */ /**对话框表格信息导入弹出窗口 */
@@ -603,31 +622,42 @@ function fnModalUploadImportClose() {
/**对话框表格信息导入上传 */ /**对话框表格信息导入上传 */
function fnModalUploadImportUpload(file: File) { function fnModalUploadImportUpload(file: File) {
const neID = queryParams.neId; const neId = queryParams.neId;
if (!neID) { if (!neId) {
return Promise.reject('Unknown network element'); return Promise.reject('Unknown network element');
} }
const hide = message.loading(t('common.loading'), 0); const hide = message.loading(t('common.loading'), 0);
uploadImportState.loading = true; uploadImportState.loading = true;
uploadFileToNE('PCF', neID, file, 5) // 上传文件
uploadFileToNE('PCF', neId, file, 3)
.then(res => { .then(res => {
if (res.code === RESULT_CODE_SUCCESS) { if (res.code === RESULT_CODE_SUCCESS) {
return importRuleData({ return res.data;
neId: neID, } else {
filePath: res.data, uploadImportState.msg = res.msg;
fileType: 'txt', uploadImportState.loading = false;
}); return '';
} }
return res; })
.then((filePath: string) => {
if (!filePath) return;
// 文件导入
return importPCFRule({
neId: neId,
fileType: 'txt',
filePath: filePath,
});
}) })
.then(res => { .then(res => {
if (res.code === RESULT_CODE_SUCCESS && res.data?.data) { if (!res) return;
uploadImportState.msg = res.data?.data; uploadImportState.msg = res.msg;
// uploadImportState.msg = t('views.neUser.pcf.uploadFileOk'); const regex = /fail num: (\d+)/;
} else if (res.code === RESULT_CODE_SUCCESS && res.data?.detail) { const match = res.msg.match(regex);
uploadImportState.msg = res.data?.detail; if (match) {
const failNum = Number(match[1]);
uploadImportState.hasFail = failNum > 0;
} else { } else {
uploadImportState.msg = t('views.neUser.pcf.uploadFileErr'); uploadImportState.hasFail = false;
} }
}) })
.finally(() => { .finally(() => {
@@ -704,7 +734,7 @@ onMounted(() => {
<a-form :model="queryParams" name="queryParams" layout="horizontal"> <a-form :model="queryParams" name="queryParams" layout="horizontal">
<a-row :gutter="16"> <a-row :gutter="16">
<a-col :lg="6" :md="12" :xs="24"> <a-col :lg="6" :md="12" :xs="24">
<a-form-item :label="t('views.neUser.pcf.neType')" name="neId "> <a-form-item label="PCF" name="neId ">
<a-select <a-select
v-model:value="queryParams.neId" v-model:value="queryParams.neId"
:options="neOtions" :options="neOtions"
@@ -772,27 +802,27 @@ onMounted(() => {
@click.prevent="fnRecordDelete('0')" @click.prevent="fnRecordDelete('0')"
> >
<template #icon><DeleteOutlined /></template> <template #icon><DeleteOutlined /></template>
{{ t('views.neUser.pcf.checkDel') }} {{ t('views.neData.common.checkDel') }}
</a-button> </a-button>
<a-dropdown trigger="click"> <a-dropdown trigger="click">
<a-button> <a-button>
{{ t('views.neUser.pcf.batchOper') }} {{ t('views.neData.common.batchOper') }}
<DownOutlined /> <DownOutlined />
</a-button> </a-button>
<template #overlay> <template #overlay>
<a-menu @click="({ key }:any) => fnModalVisibleByBatch(key)"> <a-menu @click="({ key }:any) => fnModalVisibleByBatch(key)">
<a-menu-item key="add"> <a-menu-item key="add">
<PlusOutlined /> <PlusOutlined />
{{ t('views.neUser.pcf.batchAddText') }} {{ t('views.neData.common.batchAddText') }}
</a-menu-item> </a-menu-item>
<a-menu-item key="update"> <a-menu-item key="update">
<FormOutlined /> <FormOutlined />
{{ t('views.neUser.pcf.batchUpdateText') }} {{ t('views.neData.common.batchUpdateText') }}
</a-menu-item> </a-menu-item>
<a-menu-item key="delete"> <a-menu-item key="delete">
<DeleteOutlined /> <DeleteOutlined />
{{ t('views.neUser.pcf.batchDelText') }} {{ t('views.neData.common.batchDelText') }}
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
</template> </template>
@@ -800,18 +830,18 @@ onMounted(() => {
<a-button type="dashed" @click.prevent="fnModalUploadImportOpen"> <a-button type="dashed" @click.prevent="fnModalUploadImportOpen">
<template #icon><ImportOutlined /></template> <template #icon><ImportOutlined /></template>
{{ t('views.neUser.pcf.import') }} {{ t('common.import') }}
</a-button> </a-button>
<a-popconfirm <a-popconfirm
placement="topRight" placement="topRight"
:title="t('views.neUser.pcf.exportConfirm')" :title="t('views.neData.pcfSub.exportTip')"
ok-text="TXT" ok-text="TXT"
ok-type="default" ok-type="default"
@confirm="fnExportList('txt')" @confirm="fnExportList('txt')"
> >
<a-button type="dashed"> <a-button type="dashed">
<template #icon><ExportOutlined /></template> <template #icon><ExportOutlined /></template>
{{ t('views.neUser.pcf.export') }} {{ t('common.export') }}
</a-button> </a-button>
</a-popconfirm> </a-popconfirm>
</a-space> </a-space>
@@ -882,7 +912,7 @@ onMounted(() => {
:data-source="tableState.data" :data-source="tableState.data"
:size="tableState.size" :size="tableState.size"
:pagination="tablePagination" :pagination="tablePagination"
:scroll="{ y: 'calc(100vh - 480px)' }" :scroll="{ x: tableColumns.length * 150, y: 'calc(100vh - 480px)' }"
@resizeColumn="(w:number, col:any) => (col.width = w)" @resizeColumn="(w:number, col:any) => (col.width = w)"
:row-selection="{ :row-selection="{
type: 'checkbox', type: 'checkbox',
@@ -924,12 +954,13 @@ onMounted(() => {
<!-- 新增框或修改框 --> <!-- 新增框或修改框 -->
<ProModal <ProModal
:drag="true" :drag="true"
:width="modalState.type === 'delete' ? 520 : 800" :width="520"
:destroyOnClose="true" :destroyOnClose="true"
:keyboard="false" :keyboard="false"
:mask-closable="false" :mask-closable="false"
:open="modalState.openByEdit" :open="modalState.openByEdit"
:title="modalState.title" :title="modalState.title"
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
:confirm-loading="modalState.confirmLoading" :confirm-loading="modalState.confirmLoading"
@ok="fnModalOk" @ok="fnModalOk"
@cancel="fnModalCancel" @cancel="fnModalCancel"
@@ -937,13 +968,13 @@ onMounted(() => {
<a-form <a-form
name="modalStateFrom" name="modalStateFrom"
layout="horizontal" layout="horizontal"
:label-col="{ span: 6 }" :label-col="{ span: 5 }"
:labelWrap="true" :labelWrap="true"
> >
<!--批量删除--> <!--批量删除-->
<template v-if="modalState.isBatch && modalState.type === 'delete'"> <template v-if="modalState.isBatch && modalState.type === 'delete'">
<a-form-item <a-form-item
:label="t('views.neUser.pcf.batchNum')" :label="t('views.neData.common.batchNum')"
name="num" name="num"
v-bind="modalStateFrom.validateInfos.num" v-bind="modalStateFrom.validateInfos.num"
> >
@@ -951,13 +982,13 @@ onMounted(() => {
v-model:value="modalState.from.num" v-model:value="modalState.from.num"
style="width: 100%" style="width: 100%"
:min="1" :min="1"
:max="100000" :max="500"
placeholder="<=100000" placeholder="<=500"
></a-input-number> ></a-input-number>
</a-form-item> </a-form-item>
<a-form-item <a-form-item
:label=" :label="
modalState.isBatch ? t('views.neUser.pcf.startIMSI') : 'IMSI' modalState.isBatch ? t('views.neData.common.startIMSI') : 'IMSI'
" "
name="imsi" name="imsi"
v-bind="modalStateFrom.validateInfos.imsi" v-bind="modalStateFrom.validateInfos.imsi"
@@ -966,14 +997,15 @@ onMounted(() => {
v-model:value="modalState.from.imsi" v-model:value="modalState.from.imsi"
allow-clear allow-clear
:maxlength="64" :maxlength="64"
:placeholder="t('common.inputPlease')"
> >
<template #prefix> <template #prefix>
<a-tooltip placement="topLeft"> <a-tooltip placement="topLeft">
<template #title> <template #title>
{{ t('views.neUser.pcf.imsiTip') }}<br /> {{ t('views.neData.common.imsiTip') }}<br />
{{ t('views.neUser.pcf.imsiTip1') }}<br /> {{ t('views.neData.common.imsiTip1') }}<br />
{{ t('views.neUser.pcf.imsiTip2') }}<br /> {{ t('views.neData.common.imsiTip2') }}<br />
{{ t('views.neUser.pcf.imsiTip3') }} {{ t('views.neData.common.imsiTip3') }}
</template> </template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" /> <InfoCircleOutlined style="opacity: 0.45; color: inherit" />
</a-tooltip> </a-tooltip>
@@ -984,10 +1016,9 @@ onMounted(() => {
<template v-else> <template v-else>
<!--批量数--> <!--批量数-->
<a-row v-if="modalState.isBatch">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item <a-form-item
:label="t('views.neUser.pcf.batchNum')" v-if="modalState.isBatch"
:label="t('views.neData.common.batchNum')"
name="num" name="num"
v-bind="modalStateFrom.validateInfos.num" v-bind="modalStateFrom.validateInfos.num"
> >
@@ -995,18 +1026,14 @@ onMounted(() => {
v-model:value="modalState.from.num" v-model:value="modalState.from.num"
style="width: 100%" style="width: 100%"
:min="1" :min="1"
:max="100000" :max="500"
placeholder="<=100000" placeholder="<=500"
></a-input-number> ></a-input-number>
</a-form-item> </a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item <a-form-item
:label=" :label="
modalState.isBatch ? t('views.neUser.pcf.startIMSI') : 'IMSI' modalState.isBatch ? t('views.neData.common.startIMSI') : 'IMSI'
" "
name="imsi" name="imsi"
v-bind="modalStateFrom.validateInfos.imsi" v-bind="modalStateFrom.validateInfos.imsi"
@@ -1015,27 +1042,22 @@ onMounted(() => {
v-model:value="modalState.from.imsi" v-model:value="modalState.from.imsi"
allow-clear allow-clear
:maxlength="64" :maxlength="64"
:disabled=" :disabled="!modalState.isBatch && modalState.type === 'update'"
!modalState.isBatch && modalState.type === 'update' :placeholder="t('common.inputPlease')"
"
> >
<template #prefix> <template #prefix>
<a-tooltip placement="topLeft"> <a-tooltip placement="topLeft">
<template #title> <template #title>
{{ t('views.neUser.pcf.imsiTip') }}<br /> {{ t('views.neData.common.imsiTip') }}<br />
{{ t('views.neUser.pcf.imsiTip1') }}<br /> {{ t('views.neData.common.imsiTip1') }}<br />
{{ t('views.neUser.pcf.imsiTip2') }}<br /> {{ t('views.neData.common.imsiTip2') }}<br />
{{ t('views.neUser.pcf.imsiTip3') }} {{ t('views.neData.common.imsiTip3') }}
</template> </template>
<InfoCircleOutlined <InfoCircleOutlined style="opacity: 0.45; color: inherit" />
style="opacity: 0.45; color: inherit"
/>
</a-tooltip> </a-tooltip>
</template> </template>
</a-input> </a-input>
</a-form-item> </a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item <a-form-item
label="MSISDN" label="MSISDN"
name="msisdn" name="msisdn"
@@ -1045,43 +1067,50 @@ onMounted(() => {
v-model:value="modalState.from.msisdn" v-model:value="modalState.from.msisdn"
allow-clear allow-clear
:maxlength="16" :maxlength="16"
:disabled=" :disabled="!modalState.isBatch && modalState.type === 'update'"
!modalState.isBatch && modalState.type === 'update' :placeholder="t('common.inputPlease')"
"
> >
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neData.common.msisdn') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
</a-tooltip>
</template>
</a-input> </a-input>
</a-form-item> </a-form-item>
</a-col>
</a-row>
<a-row> <a-form-item
<a-col :lg="12" :md="12" :xs="24"> label="PCC Rules"
<a-form-item label="PCC Rules" name="pccRules"> name="pccRules"
:help="t('views.neData.pcfSub.pccRuleTip')"
>
<a-select <a-select
v-model:value="modalState.from.pccRules" v-model:value="modalState.from.pccRules"
allow-clear allow-clear
mode="tags" mode="tags"
:options="pcfRuleOption.pccRules" :options="pcfRuleOption.pccRules"
:title="t('views.neUser.pcf.pccRuleTip')"
/> />
</a-form-item> </a-form-item>
</a-col> <a-form-item
<a-col :lg="12" :md="12" :xs="24"> label="SESS Rules"
<a-form-item label="SESS Rules" name="sessRules"> name="sessRules"
:help="t('views.neData.pcfSub.sessRuleTip')"
>
<a-select <a-select
v-model:value="modalState.from.sessRules" v-model:value="modalState.from.sessRules"
allow-clear allow-clear
mode="tags" mode="tags"
:options="pcfRuleOption.sessionRules" :options="pcfRuleOption.sessionRules"
:title="t('views.neUser.pcf.sessRuleTip')"
/> />
</a-form-item> </a-form-item>
</a-col>
</a-row>
<a-row> <a-form-item
<a-col :lg="12" :md="12" :xs="24"> label="QoS Audio"
<a-form-item label="QoS Audio" name="qosAudio"> name="qosAudio"
:help="t('views.neData.pcfSub.qosAudioTip')"
>
<a-auto-complete <a-auto-complete
v-model:value="modalState.from.qosAudio" v-model:value="modalState.from.qosAudio"
allow-clear allow-clear
@@ -1089,9 +1118,11 @@ onMounted(() => {
:filter-option="filterOption" :filter-option="filterOption"
/> />
</a-form-item> </a-form-item>
</a-col> <a-form-item
<a-col :lg="12" :md="12" :xs="24"> label="QoS Video"
<a-form-item label="QoS Video" name="qosVideo"> name="qosVideo"
:help="t('views.neData.pcfSub.qosVideoTip')"
>
<a-auto-complete <a-auto-complete
v-model:value="modalState.from.qosVideo" v-model:value="modalState.from.qosVideo"
allow-clear allow-clear
@@ -1099,12 +1130,12 @@ onMounted(() => {
:filter-option="filterOption" :filter-option="filterOption"
/> />
</a-form-item> </a-form-item>
</a-col>
</a-row>
<a-row> <a-form-item
<a-col :lg="12" :md="12" :xs="24"> label="HDR Enrich"
<a-form-item label="HDR Enrich" name="hdrEnrich"> name="hdrEnrich"
:help="t('views.neData.pcfSub.hdrEnrichTip')"
>
<a-auto-complete <a-auto-complete
v-model:value="modalState.from.hdrEnrich" v-model:value="modalState.from.hdrEnrich"
allow-clear allow-clear
@@ -1112,32 +1143,24 @@ onMounted(() => {
:filter-option="filterOption" :filter-option="filterOption"
/> />
</a-form-item> </a-form-item>
</a-col> <a-form-item
<a-col :lg="12" :md="12" :xs="24"> label="UE Policy"
<a-form-item label="UE Policy" name="uePolicy"> name="uePolicy"
:help="t('views.neData.pcfSub.uePolicyTip')"
>
<a-input <a-input
v-model:value="modalState.from.uePolicy" v-model:value="modalState.from.uePolicy"
allow-clear allow-clear
:maxlength="64" :maxlength="64"
> >
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.pcf.ueTip') }}
</template>
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input> </a-input>
</a-form-item> </a-form-item>
</a-col>
</a-row>
<a-row> <a-form-item
<a-col :lg="12" :md="12" :xs="24"> label="SAR"
<a-form-item label="SAR" name="sar"> name="sar"
:help="t('views.neData.pcfSub.sarTip')"
>
<a-auto-complete <a-auto-complete
v-model:value="modalState.from.sar" v-model:value="modalState.from.sar"
allow-clear allow-clear
@@ -1145,9 +1168,11 @@ onMounted(() => {
:filter-option="filterOption" :filter-option="filterOption"
/> />
</a-form-item> </a-form-item>
</a-col> <a-form-item
<a-col :lg="12" :md="12" :xs="24"> label="RFSP"
<a-form-item label="RFSP" name="rfsp"> name="rfsp"
:help="t('views.neData.pcfSub.rfsfTip')"
>
<a-input-number <a-input-number
v-model:value="modalState.from.rfsp" v-model:value="modalState.from.rfsp"
style="width: 100%" style="width: 100%"
@@ -1155,20 +1180,8 @@ onMounted(() => {
:max="255" :max="255"
placeholder="0~255" placeholder="0~255"
> >
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.pcf.rfsfTip') }}
</template>
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input-number> </a-input-number>
</a-form-item> </a-form-item>
</a-col>
</a-row>
</template> </template>
</a-form> </a-form>
</ProModal> </ProModal>
@@ -1195,13 +1208,12 @@ onMounted(() => {
</a-button> </a-button>
</a-col> </a-col>
</a-row> </a-row>
<a-textarea <a-alert
:disabled="true" :message="uploadImportState.msg"
:hidden="!uploadImportState.msg" :type="uploadImportState.hasFail ? 'warning' : 'info'"
:value="uploadImportState.msg" v-show="uploadImportState.msg.length > 0"
:auto-size="{ minRows: 2, maxRows: 8 }" >
style="background-color: transparent; color: rgba(0, 0, 0, 0.85)" </a-alert>
/>
</template> </template>
</UploadModal> </UploadModal>
</PageContainer> </PageContainer>