feat: UDM用户数据导入输出失败记录,UDM2.2502.58

This commit is contained in:
TsMask
2025-02-07 16:00:52 +08:00
parent fbc1535015
commit fd82d710b6
4 changed files with 579 additions and 146 deletions

View File

@@ -737,6 +737,7 @@ export default {
checkExport : 'Check Export',
checkExportConfirm: 'Confirm exporting the checked authenticated user data?',
import: 'Import',
importFail: 'Failure Record',
loadDataConfirm: 'Are you sure you want to reload the data?',
loadData: 'Load Data',
loadDataTip: 'Successfully fetched loaded data: {num} items, the system is internally updating the data, it will take about {timer} seconds, please wait!!!!!.',
@@ -765,6 +766,7 @@ export default {
checkExport : 'Check Export',
checkExportConfirm: 'Are you sure to export the data of the checked subscribers?',
import: 'Import',
importFail: 'Failure Record',
loadDataConfirm: 'Are you sure you want to reload the data?',
loadData: 'Load Data',
loadDataTip: 'Successfully fetched loaded data: {num} items, the system is internally updating the data, it will take about {timer} seconds, please wait!!!!!.',

View File

@@ -737,6 +737,7 @@ export default {
checkExport : '勾选导出',
checkExportConfirm: '确认导出已勾选的鉴权用户数据吗?',
import: '导入',
importFail: '失败记录',
loadDataConfirm: '确认要重新加载数据吗?',
loadData: '加载数据',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,大约需要{timer}秒,请稍候!!!',
@@ -765,6 +766,7 @@ export default {
checkExport : '勾选导出',
checkExportConfirm: '确认导出已勾选的签约用户数据吗?',
import: '导入',
importFail: '失败记录',
loadDataConfirm: '确认要重新加载数据吗?',
loadData: '加载数据',
loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,大约需要{timer}秒,请稍候!!!',

View File

@@ -25,6 +25,7 @@ import {
listUDMAuth,
} from '@/api/neData/udm_auth';
import { uploadFile } from '@/api/tool/file';
import { getNeViewFile } from '@/api/tool/neFile';
const { t } = useI18n();
/**网元参数 */
@@ -98,12 +99,6 @@ let tableColumns = ref<ColumnsType>([
align: 'center',
width: 80,
},
{
title: 'Status',
dataIndex: 'status',
align: 'center',
width: 80,
},
// {
// title: 'KI',
// dataIndex: 'ki',
@@ -598,6 +593,8 @@ type ModalUploadImportStateType = {
loading: boolean;
/**上传结果信息 */
msg: string;
/**含失败信息 */
hasFail: boolean;
/**导入类型 */
typeOptions: { label: string; value: string }[];
/**表单 */
@@ -610,6 +607,7 @@ let uploadImportState: ModalUploadImportStateType = reactive({
title: t('components.UploadModal.uploadTitle'),
loading: false,
msg: '',
hasFail: false,
typeOptions: [
{ label: 'Default', value: 'default' },
{ label: 'K4', value: 'k4' },
@@ -626,9 +624,37 @@ function fnModalUploadImportTypeChange() {
uploadImportState.msg = '';
}
/**对话框表格信息导入失败原因 */
function fnModalUploadImportFailReason() {
const neId = queryParams.neId;
if (!neId) return;
const hide = message.loading(t('common.loading'), 0);
getNeViewFile({
neType: 'UDM',
neId: neId,
path: '/tmp',
fileName: 'import_authdata_err_records.txt',
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success(t('common.operateOk'), 3);
const blob = new Blob([res.data], {
type: 'text/plain',
});
saveAs(blob, `import_authdata_err_records_${Date.now()}.txt`);
} else {
message.error(`${res.msg}`, 3);
}
})
.finally(() => {
hide();
});
}
/**对话框表格信息导入弹出窗口 */
function fnModalUploadImportOpen() {
uploadImportState.msg = '';
uploadImportState.hasFail = false;
uploadImportState.from.typeVal = 'default';
uploadImportState.from.typeData = undefined;
uploadImportState.loading = false;
@@ -675,6 +701,14 @@ function fnModalUploadImportUpload(file: File) {
.then(res => {
if (!res) return;
uploadImportState.msg = res.msg;
const regex = /fail num: (\d+)/;
const match = res.msg.match(regex);
if (match) {
const failNum = Number(match[1]);
uploadImportState.hasFail = failNum > 0;
} else {
uploadImportState.hasFail = false;
}
})
.finally(() => {
hide();
@@ -1018,14 +1052,6 @@ onMounted(() => {
</a-input>
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item label="Status" name="status">
<a-select value="1">
<a-select-option value="1">Active</a-select-option>
<a-select-option value="0">Inactive</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row>
@@ -1210,13 +1236,23 @@ onMounted(() => {
v-model:value="uploadImportState.from.typeData"
:placeholder="t('common.inputPlease')"
/>
<a-textarea
:disabled="true"
:hidden="!uploadImportState.msg"
:value="uploadImportState.msg"
:auto-size="{ minRows: 2, maxRows: 8 }"
style="background-color: transparent; color: rgba(0, 0, 0, 0.85)"
/>
<a-alert
:message="uploadImportState.msg"
:type="uploadImportState.hasFail ? 'warning' : 'info'"
v-show="uploadImportState.msg.length > 0"
>
<template #action>
<a-button
size="small"
type="link"
danger
@click="fnModalUploadImportFailReason"
v-if="uploadImportState.hasFail"
>
{{ t('views.neUser.auth.importFail') }}
</a-button>
</template>
</a-alert>
</template>
</UploadModal>
</PageContainer>

View File

@@ -25,6 +25,7 @@ import {
updateUDMSub,
} from '@/api/neData/udm_sub';
import { uploadFile } from '@/api/tool/file';
import { getNeViewFile } from '@/api/tool/neFile';
const { t } = useI18n();
/**网元参数 */
@@ -556,7 +557,8 @@ function transformFormData(data: any) {
if (isValid) {
smStaticIpArr.push(dnnParts);
}
} else {//无/ 无:也有可能为dnn的字符串
} else {
//无/ 无:也有可能为dnn的字符串
smallRowJson.dnn += '-' + dnnParts;
}
}
@@ -971,6 +973,8 @@ type ModalUploadImportStateType = {
loading: boolean;
/**上传结果信息 */
msg: string;
/**含失败信息 */
hasFail: boolean;
};
/**对话框表格信息导入对象信息状态 */
@@ -979,11 +983,40 @@ let uploadImportState: ModalUploadImportStateType = reactive({
title: t('components.UploadModal.uploadTitle'),
loading: false,
msg: '',
hasFail: false,
});
/**对话框表格信息导入失败原因 */
function fnModalUploadImportFailReason() {
const neId = queryParams.neId;
if (!neId) return;
const hide = message.loading(t('common.loading'), 0);
getNeViewFile({
neType: 'UDM',
neId: neId,
path: '/tmp',
fileName: 'import_udmuser_err_records.txt',
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success(t('common.operateOk'), 3);
const blob = new Blob([res.data], {
type: 'text/plain',
});
saveAs(blob, `import_udmuser_err_records_${Date.now()}.txt`);
} else {
message.error(`${res.msg}`, 3);
}
})
.finally(() => {
hide();
});
}
/**对话框表格信息导入弹出窗口 */
function fnModalUploadImportOpen() {
uploadImportState.msg = '';
uploadImportState.hasFail = false;
uploadImportState.loading = false;
uploadImportState.open = true;
}
@@ -1027,6 +1060,14 @@ function fnModalUploadImportUpload(file: File) {
.then(res => {
if (!res) return;
uploadImportState.msg = res.msg;
const regex = /fail num: (\d+)/;
const match = res.msg.match(regex);
if (match) {
const failNum = Number(match[1]);
uploadImportState.hasFail = failNum > 0;
} else {
uploadImportState.hasFail = false;
}
})
.finally(() => {
hide();
@@ -1103,26 +1144,42 @@ onMounted(() => {
<template>
<PageContainer>
<a-card v-show="tableState.seached" :bordered="false" :body-style="{ marginBottom: '24px', paddingBottom: 0 }">
<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.neUser.sub.neType')" name="neId ">
<a-select v-model:value="queryParams.neId" :options="neOtions" :placeholder="t('common.selectPlease')"
@change="fnGetList(1)" />
<a-select
v-model:value="queryParams.neId"
:options="neOtions"
:placeholder="t('common.selectPlease')"
@change="fnGetList(1)"
/>
</a-form-item>
</a-col>
<a-col :lg="6" :md="12" :xs="24">
<a-form-item label="IMSI" name="imsi">
<a-input v-model:value="queryParams.imsi" allow-clear :maxlength="15"
:placeholder="t('common.inputPlease')"></a-input>
<a-input
v-model:value="queryParams.imsi"
allow-clear
:maxlength="15"
:placeholder="t('common.inputPlease')"
></a-input>
</a-form-item>
</a-col>
<a-col :lg="6" :md="12" :xs="24">
<a-form-item label="MSISDN" name="msisdn">
<a-input v-model:value="queryParams.msisdn" allow-clear :maxlength="32"
:placeholder="t('common.inputPlease')"></a-input>
<a-input
v-model:value="queryParams.msisdn"
allow-clear
:maxlength="32"
:placeholder="t('common.inputPlease')"
></a-input>
</a-form-item>
</a-col>
<a-col :lg="6" :md="12" :xs="24">
@@ -1158,16 +1215,31 @@ onMounted(() => {
{{ t('common.addText') }}
</a-button>
<a-button type="primary" danger ghost @click.prevent="fnModalVisibleByBatch()">
<a-button
type="primary"
danger
ghost
@click.prevent="fnModalVisibleByBatch()"
>
<template #icon>
<DeleteOutlined />
</template>
{{ t('views.neUser.auth.batchDelText') }}
</a-button>
<a-popconfirm :title="t('views.neUser.sub.loadDataConfirm')" :ok-text="t('common.ok')"
:cancel-text="t('common.cancel')" :disabled="modalState.loadDataLoading" @confirm="fnLoadData">
<a-button type="dashed" danger :disabled="modalState.loadDataLoading" :loading="modalState.loadDataLoading">
<a-popconfirm
:title="t('views.neUser.sub.loadDataConfirm')"
:ok-text="t('common.ok')"
:cancel-text="t('common.cancel')"
:disabled="modalState.loadDataLoading"
@confirm="fnLoadData"
>
<a-button
type="dashed"
danger
:disabled="modalState.loadDataLoading"
:loading="modalState.loadDataLoading"
>
<template #icon>
<SyncOutlined />
</template>
@@ -1182,8 +1254,13 @@ onMounted(() => {
{{ t('views.neUser.sub.import') }}
</a-button>
<a-popconfirm :title="t('views.neUser.sub.exportConfirm')" placement="topRight" ok-text="TXT"
ok-type="default" @confirm="fnExportList('txt')">
<a-popconfirm
:title="t('views.neUser.sub.exportConfirm')"
placement="topRight"
ok-text="TXT"
ok-type="default"
@confirm="fnExportList('txt')"
>
<a-button type="dashed">
<template #icon>
<ExportOutlined />
@@ -1192,17 +1269,31 @@ onMounted(() => {
</a-button>
</a-popconfirm>
<a-button type="default" danger :disabled="tableState.selectedRowKeys.length <= 0"
:loading="modalState.loadDataLoading" @click.prevent="fnRecordDelete('0')">
<a-button
type="default"
danger
:disabled="tableState.selectedRowKeys.length <= 0"
:loading="modalState.loadDataLoading"
@click.prevent="fnRecordDelete('0')"
>
<template #icon>
<DeleteOutlined />
</template>
{{ t('views.neUser.sub.checkDel') }}
</a-button>
<a-popconfirm :title="t('views.neUser.sub.checkExportConfirm')" placement="topRight" ok-text="TXT"
ok-type="default" @confirm="fnRecordExport('txt')" :disabled="tableState.selectedRowKeys.length <= 0">
<a-button type="default" :disabled="tableState.selectedRowKeys.length <= 0">
<a-popconfirm
:title="t('views.neUser.sub.checkExportConfirm')"
placement="topRight"
ok-text="TXT"
ok-type="default"
@confirm="fnRecordExport('txt')"
:disabled="tableState.selectedRowKeys.length <= 0"
>
<a-button
type="default"
:disabled="tableState.selectedRowKeys.length <= 0"
>
<template #icon>
<ExportOutlined />
</template>
@@ -1217,8 +1308,12 @@ onMounted(() => {
<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-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>
@@ -1228,7 +1323,11 @@ onMounted(() => {
</template>
</a-button>
</a-tooltip>
<TableColumnsDnd cache-id="udmSubData" :columns="tableColumns" v-model:columns-dnd="tableColumnsDnd">
<TableColumnsDnd
cache-id="udmSubData"
:columns="tableColumns"
v-model:columns-dnd="tableColumnsDnd"
>
</TableColumnsDnd>
<a-tooltip placement="topRight">
<template #title>{{ t('common.sizeText') }}</template>
@@ -1239,7 +1338,10 @@ onMounted(() => {
</template>
</a-button>
<template #overlay>
<a-menu :selected-keys="[tableState.size as string]" @click="fnTableSize">
<a-menu
:selected-keys="[tableState.size as string]"
@click="fnTableSize"
>
<a-menu-item key="default">
{{ t('common.size.default') }}
</a-menu-item>
@@ -1257,14 +1359,23 @@ onMounted(() => {
</template>
<!-- 表格列表 -->
<a-table class="table" row-key="imsi" :columns="tableColumnsDnd" :loading="tableState.loading"
:data-source="tableState.data" :size="tableState.size" :pagination="tablePagination"
:scroll="{ y: 'calc(100vh - 480px)' }" @change="fnTableChange"
@resizeColumn="(w: number, col: any) => (col.width = w)" :row-selection="{
<a-table
class="table"
row-key="imsi"
:columns="tableColumnsDnd"
:loading="tableState.loading"
:data-source="tableState.data"
:size="tableState.size"
:pagination="tablePagination"
:scroll="{ y: 'calc(100vh - 480px)' }"
@change="fnTableChange"
@resizeColumn="(w: number, col: any) => (col.width = w)"
:row-selection="{
type: 'checkbox',
selectedRowKeys: tableState.selectedRowKeys,
onChange: fnTableSelectedRowKeys,
}">
}"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'cnFlag'">
{{
@@ -1284,7 +1395,10 @@ onMounted(() => {
<a-space :size="8" align="center">
<a-tooltip>
<template #title>{{ t('common.editText') }}</template>
<a-button type="link" @click.prevent="fnModalVisibleByEdit(record.imsi)">
<a-button
type="link"
@click.prevent="fnModalVisibleByEdit(record.imsi)"
>
<template #icon>
<FormOutlined />
</template>
@@ -1292,7 +1406,10 @@ onMounted(() => {
</a-tooltip>
<a-tooltip>
<template #title>{{ t('common.deleteText') }}</template>
<a-button type="link" @click.prevent="fnRecordDelete(record.imsi)">
<a-button
type="link"
@click.prevent="fnRecordDelete(record.imsi)"
>
<template #icon>
<DeleteOutlined />
</template>
@@ -1305,26 +1422,58 @@ onMounted(() => {
</a-card>
<!-- 新增框或修改框 -->
<ProModal :drag="true" :width="800" :destroyOnClose="true" style="top: 0px"
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }" :keyboard="false" :mask-closable="false"
:open="modalState.openByEdit" :title="modalState.title" :confirm-loading="modalState.confirmLoading"
@ok="fnModalOk" @cancel="fnModalCancel">
<a-form name="modalStateFrom" layout="horizontal" :label-col="{ span: 6 }" :labelWrap="true">
<ProModal
:drag="true"
:width="800"
:destroyOnClose="true"
style="top: 0px"
:body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByEdit"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnModalOk"
@cancel="fnModalCancel"
>
<a-form
name="modalStateFrom"
layout="horizontal"
:label-col="{ span: 6 }"
:labelWrap="true"
>
<a-row>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item :label="t('views.neUser.sub.numAdd')" name="num" v-bind="modalStateFrom.validateInfos.num"
v-show="!modalState.from.id">
<a-input-number v-model:value="modalState.from.num" style="width: 100%" :min="1" :max="10000"
placeholder="<=10000"></a-input-number>
<a-form-item
:label="t('views.neUser.sub.numAdd')"
name="num"
v-bind="modalStateFrom.validateInfos.num"
v-show="!modalState.from.id"
>
<a-input-number
v-model:value="modalState.from.num"
style="width: 100%"
:min="1"
:max="10000"
placeholder="<=10000"
></a-input-number>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item label="IMSI" name="imsi" v-bind="modalStateFrom.validateInfos.imsi">
<a-input v-model:value="modalState.from.imsi" allow-clear :maxlength="15"
:disabled="!!modalState.from.id">
<a-form-item
label="IMSI"
name="imsi"
v-bind="modalStateFrom.validateInfos.imsi"
>
<a-input
v-model:value="modalState.from.imsi"
allow-clear
:maxlength="15"
:disabled="!!modalState.from.id"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
@@ -1340,8 +1489,16 @@ onMounted(() => {
</a-form-item>
</a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-form-item label="MSISDN" name="msisdn" v-bind="modalStateFrom.validateInfos.msisdn">
<a-input v-model:value="modalState.from.msisdn" allow-clear :maxlength="32">
<a-form-item
label="MSISDN"
name="msisdn"
v-bind="modalStateFrom.validateInfos.msisdn"
>
<a-input
v-model:value="modalState.from.msisdn"
allow-clear
:maxlength="32"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
@@ -1355,24 +1512,49 @@ onMounted(() => {
</a-col>
</a-row>
<a-form-item :label="t('common.remark')" :label-col="{ span: 3 }" :label-wrap="true">
<a-textarea v-model:value="modalState.from.remark" :auto-size="{ minRows: 1, maxRows: 6 }" :maxlength="500"
:show-count="true" :placeholder="t('common.inputPlease')" />
<a-form-item
:label="t('common.remark')"
:label-col="{ span: 3 }"
:label-wrap="true"
>
<a-textarea
v-model:value="modalState.from.remark"
:auto-size="{ minRows: 1, maxRows: 6 }"
:maxlength="500"
:show-count="true"
:placeholder="t('common.inputPlease')"
/>
</a-form-item>
<!-- SM Data ---- S -->
<a-divider orientation="left">
Subscribed SM Data
<a-tooltip title="Add SM Data">
<a-button shape="circle" @click="addBigRow" style="margin-left: 10px">
<a-button
shape="circle"
@click="addBigRow"
style="margin-left: 10px"
>
<template #icon><plus-outlined /></template>
</a-button> </a-tooltip></a-divider>
</a-button> </a-tooltip
></a-divider>
<!-- 大数组布局 -->
<div v-for="(row, index) in bigRows" :key="String(row.id)">
<a-row>
<a-col :lg="6" :md="6" :xs="24">
<a-form-item label="SST" name="row.sst" :label-col="{ span: 12 }" :validateTrigger="[]" :required="true">
<a-input-number v-model:value="row.sst" :min="1" :max="3" :step="1" />
<a-form-item
label="SST"
name="row.sst"
:label-col="{ span: 12 }"
:validateTrigger="[]"
:required="true"
>
<a-input-number
v-model:value="row.sst"
:min="1"
:max="3"
:step="1"
/>
</a-form-item>
</a-col>
@@ -1385,7 +1567,11 @@ onMounted(() => {
<a-row>
<a-col :span="4">
<a-tooltip title="Add DNN">
<a-button shape="circle" @click="addSmallRow(row.id)" style="margin-left:10px ;">
<a-button
shape="circle"
@click="addSmallRow(row.id)"
style="margin-left: 10px"
>
<template #icon><plus-square-outlined /></template>
</a-button>
</a-tooltip>
@@ -1402,27 +1588,51 @@ onMounted(() => {
</a-row>
<!-- 小数组布局 -->
<div v-for="(smallRow, smallIndex) in row.smallRows" :key="String(smallRow.id)">
<div
v-for="(smallRow, smallIndex) in row.smallRows"
:key="String(smallRow.id)"
>
<a-row>
<a-col :lg="6" :md="6" :xs="24">
<a-form-item label="DNN/APN" name="dnn" :validateTrigger="[]" :required="true"
:label-col="{ span: 12 }">
<a-form-item
label="DNN/APN"
name="dnn"
:validateTrigger="[]"
:required="true"
:label-col="{ span: 12 }"
>
<a-input v-model:value="smallRow.dnn" allow-clear></a-input>
</a-form-item>
</a-col>
<a-col :lg="8" :md="8" :xs="24">
<a-form-item label="Static IP" name="smStaticIp" :label-col="{ span: 5 }">
<a-input v-model:value="smallRow.smStaticIp" allow-clear></a-input>
<a-form-item
label="Static IP"
name="smStaticIp"
:label-col="{ span: 5 }"
>
<a-input
v-model:value="smallRow.smStaticIp"
allow-clear
></a-input>
</a-form-item>
</a-col>
<a-col :lg="8" :md="8" :xs="24">
<a-form-item label="Routing Behind MS IP" style="margin-left:10px ;" name="msIp">
<a-form-item
label="Routing Behind MS IP"
style="margin-left: 10px"
name="msIp"
>
<a-input v-model:value="smallRow.msIp" allow-clear></a-input>
</a-form-item>
</a-col>
<a-col :lg="2" :md="2" :xs="24" v-if="smallIndex !== 0">
<a-tooltip title="Delete DNN">
<a-button danger shape="circle" @click="delDNN(smallIndex, row.id)" style="margin-left:10px ;">
<a-button
danger
shape="circle"
@click="delDNN(smallIndex, row.id)"
style="margin-left: 10px"
>
<template #icon><close-square-outlined /></template>
</a-button>
</a-tooltip>
@@ -1439,7 +1649,11 @@ onMounted(() => {
</template>
<a-row>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5GC Flag" name="cnFlag" :help="t('views.neUser.sub.cnFlag')">
<a-form-item
label="5GC Flag"
name="cnFlag"
:help="t('views.neUser.sub.cnFlag')"
>
<a-select v-model:value="modalState.from.cnType">
<a-select-option value="3">
{{ t('views.neUser.sub.enable') }}
@@ -1451,44 +1665,71 @@ onMounted(() => {
</a-form-item>
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5G Subscribed UE AMBR Template" name="ambr"
v-bind="modalStateFrom.validateInfos.ambr">
<a-input v-model:value="modalState.from.ambr" allow-clear :maxlength="50">
<a-form-item
label="5G Subscribed UE AMBR Template"
name="ambr"
v-bind="modalStateFrom.validateInfos.ambr"
>
<a-input
v-model:value="modalState.from.ambr"
allow-clear
:maxlength="50"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.inputTip', { num: '50' }) }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5G Subscribed SNSSAIs Template" name="nssai"
v-bind="modalStateFrom.validateInfos.nssai">
<a-input v-model:value="modalState.from.nssai" allow-clear :maxlength="50">
<a-form-item
label="5G Subscribed SNSSAIs Template"
name="nssai"
v-bind="modalStateFrom.validateInfos.nssai"
>
<a-input
v-model:value="modalState.from.nssai"
allow-clear
:maxlength="50"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.inputTip', { num: '50' }) }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5G Subscribed SMF Selection Data Template" name="smfSel">
<a-input v-model:value="modalState.from.smfSel" allow-clear :maxlength="50">
<a-form-item
label="5G Subscribed SMF Selection Data Template"
name="smfSel"
>
<a-input
v-model:value="modalState.from.smfSel"
allow-clear
:maxlength="50"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.inputTip', { num: '50' }) }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input>
@@ -1496,48 +1737,77 @@ onMounted(() => {
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5G Forbidden Areas Template" name="arfb">
<a-input v-model:value="modalState.from.arfb" allow-clear :maxlength="50">
<a-input
v-model:value="modalState.from.arfb"
allow-clear
:maxlength="50"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.arfbTip') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5G CAG Template" name="cag" v-bind="modalStateFrom.validateInfos.cag">
<a-input v-model:value="modalState.from.cag" allow-clear :maxlength="50">
<a-form-item
label="5G CAG Template"
name="cag"
v-bind="modalStateFrom.validateInfos.cag"
>
<a-input
v-model:value="modalState.from.cag"
allow-clear
:maxlength="50"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.inputTip', { num: '50' }) }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5G Service Area Restriction Template" name="sar">
<a-input v-model:value="modalState.from.sar" allow-clear :maxlength="50">
<a-form-item
label="5G Service Area Restriction Template"
name="sar"
>
<a-input
v-model:value="modalState.from.sar"
allow-clear
:maxlength="50"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.sarTip') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input>
</a-form-item>
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5G MICO Mode" name="mico" :help="t('views.neUser.sub.micoTip')">
<a-form-item
label="5G MICO Mode"
name="mico"
:help="t('views.neUser.sub.micoTip')"
>
<a-select v-model:value="modalState.from.mico">
<a-select-option value="1">
{{ t('views.neUser.sub.enable') }}
@@ -1560,14 +1830,21 @@ onMounted(() => {
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5G UE Usage Type" name="ueUsageType">
<a-input-number v-model:value="modalState.from.ueUsageType" style="width: 100%" :min="0" :max="127"
placeholder="0 ~ 127">
<a-input-number
v-model:value="modalState.from.ueUsageType"
style="width: 100%"
:min="0"
:max="127"
placeholder="0 ~ 127"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.ueTypeTip') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input-number>
@@ -1575,14 +1852,21 @@ onMounted(() => {
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="5G RFSP Index" name="rfspIndex">
<a-input-number v-model:value="modalState.from.rfspIndex" style="width: 100%" :min="0" :max="127"
placeholder="0 ~ 127">
<a-input-number
v-model:value="modalState.from.rfspIndex"
style="width: 100%"
:min="0"
:max="127"
placeholder="0 ~ 127"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.rfspTip') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input-number>
@@ -1597,7 +1881,11 @@ onMounted(() => {
</template>
<a-row>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="4G EPS Flag" name="epsFlag" :help="t('views.neUser.sub.epsFlagTip')">
<a-form-item
label="4G EPS Flag"
name="epsFlag"
:help="t('views.neUser.sub.epsFlagTip')"
>
<a-select v-model:value="modalState.from.epsFlag">
<a-select-option value="1">
{{ t('views.neUser.sub.enable') }}
@@ -1609,15 +1897,24 @@ onMounted(() => {
</a-form-item>
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="4G EPS User Template Name" name="epstpl"
v-bind="modalStateFrom.validateInfos.epstpl">
<a-input v-model:value="modalState.from.epstpl" allow-clear :maxlength="50">
<a-form-item
label="4G EPS User Template Name"
name="epstpl"
v-bind="modalStateFrom.validateInfos.epstpl"
>
<a-input
v-model:value="modalState.from.epstpl"
allow-clear
:maxlength="50"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.inputTip', { num: '50' }) }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input>
@@ -1626,14 +1923,20 @@ onMounted(() => {
</a-row>
<a-row>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item label="4G Static IP" v-bind="modalStateFrom.validateInfos.staticIp" name="staticIp">
<a-form-item
label="4G Static IP"
v-bind="modalStateFrom.validateInfos.staticIp"
name="staticIp"
>
<a-input v-model:value="modalState.from.staticIp" allow-clear>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
{{ t('views.neUser.sub.staticIpTip') }}
</template>
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
<InfoCircleOutlined
style="opacity: 0.45; color: inherit"
/>
</a-tooltip>
</template>
</a-input>
@@ -1653,33 +1956,73 @@ onMounted(() => {
</a-input>
</a-form-item>
<a-form-item label="4G APN Context List" name="apnContext" :help="t('views.neUser.sub.apnContextTip')">
<a-form-item
label="4G APN Context List"
name="apnContext"
:help="t('views.neUser.sub.apnContextTip')"
>
<a-input-group compact>
<a-input-number v-for="(_, i) in modalState.from.apnContext" :key="i" :title="i" style="width: 16.5%"
:min="0" :max="99" v-model:value="modalState.from.apnContext[i]"></a-input-number>
<a-input-number
v-for="(_, i) in modalState.from.apnContext"
:key="i"
:title="i"
style="width: 16.5%"
:min="0"
:max="99"
v-model:value="modalState.from.apnContext[i]"
></a-input-number>
</a-input-group>
</a-form-item>
<a-form-item label="4G EPS ODB" name="epsOdb" v-bind="modalStateFrom.validateInfos.epsOdb">
<a-tooltip :title="t('views.neUser.sub.epsOdbTip')" placement="topLeft">
<a-select v-model:value="modalState.from.epsOdb" mode="multiple" style="width: 100%"
placeholder="Please select" :options="modalStateFromOption.odbJson" @change="">
<a-form-item
label="4G EPS ODB"
name="epsOdb"
v-bind="modalStateFrom.validateInfos.epsOdb"
>
<a-tooltip
:title="t('views.neUser.sub.epsOdbTip')"
placement="topLeft"
>
<a-select
v-model:value="modalState.from.epsOdb"
mode="multiple"
style="width: 100%"
placeholder="Please select"
:options="modalStateFromOption.odbJson"
@change=""
>
</a-select>
</a-tooltip>
</a-form-item>
<a-form-item label="4G HPLMN ODB" name="hplmnOdb">
<a-tooltip :title="t('views.neUser.sub.hplmnOdbTip')" placement="topLeft">
<a-select v-model:value="modalState.from.hplmnOdb" mode="multiple" style="width: 100%"
:options="modalStateFromOption.hplmnOdb" @change="">
<a-tooltip
:title="t('views.neUser.sub.hplmnOdbTip')"
placement="topLeft"
>
<a-select
v-model:value="modalState.from.hplmnOdb"
mode="multiple"
style="width: 100%"
:options="modalStateFromOption.hplmnOdb"
@change=""
>
</a-select>
</a-tooltip>
</a-form-item>
<a-form-item label="4G Access Restriction Data" name="ard">
<a-tooltip :title="t('views.neUser.sub.ardTip')" placement="topLeft">
<a-select v-model:value="modalState.from.ard" mode="multiple" style="width: 100%"
:options="modalStateFromOption.ardJson" @change="">
<a-tooltip
:title="t('views.neUser.sub.ardTip')"
placement="topLeft"
>
<a-select
v-model:value="modalState.from.ard"
mode="multiple"
style="width: 100%"
:options="modalStateFromOption.ardJson"
@change=""
>
</a-select>
</a-tooltip>
</a-form-item>
@@ -1689,15 +2032,36 @@ onMounted(() => {
</ProModal>
<!-- 批量删除框 -->
<ProModal :drag="true" :destroyOnClose="true" style="top: 0px" :keyboard="false" :mask-closable="false"
:open="modalState.openByBatchDel" :title="modalState.title" :confirm-loading="modalState.confirmLoading"
@ok="fnBatchDelModalOk" @cancel="fnBatchDelModalCancel">
<a-form name="modalStateBatchDelFrom" layout="horizontal" :label-col="{ span: 6 }" :labelWrap="true">
<ProModal
:drag="true"
:destroyOnClose="true"
style="top: 0px"
:keyboard="false"
:mask-closable="false"
:open="modalState.openByBatchDel"
:title="modalState.title"
:confirm-loading="modalState.confirmLoading"
@ok="fnBatchDelModalOk"
@cancel="fnBatchDelModalCancel"
>
<a-form
name="modalStateBatchDelFrom"
layout="horizontal"
:label-col="{ span: 6 }"
:labelWrap="true"
>
<a-row>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item :label="t('views.neUser.sub.startIMSI')" name="imsi"
v-bind="modalStateBatchDelFrom.validateInfos.imsi">
<a-input v-model:value="modalState.BatchDelForm.imsi" allow-clear :maxlength="15">
<a-form-item
:label="t('views.neUser.sub.startIMSI')"
name="imsi"
v-bind="modalStateBatchDelFrom.validateInfos.imsi"
>
<a-input
v-model:value="modalState.BatchDelForm.imsi"
allow-clear
:maxlength="15"
>
<template #prefix>
<a-tooltip placement="topLeft">
<template #title>
@@ -1713,10 +2077,18 @@ onMounted(() => {
</a-form-item>
</a-col>
<a-col :lg="24" :md="24" :xs="24">
<a-form-item :label="t('views.neUser.sub.numDel')" name="num"
v-bind="modalStateBatchDelFrom.validateInfos.num">
<a-input-number v-model:value="modalState.BatchDelForm.num" style="width: 100%" :min="1" :max="10000"
placeholder="<=10000"></a-input-number>
<a-form-item
:label="t('views.neUser.sub.numDel')"
name="num"
v-bind="modalStateBatchDelFrom.validateInfos.num"
>
<a-input-number
v-model:value="modalState.BatchDelForm.num"
style="width: 100%"
:min="1"
:max="10000"
placeholder="<=10000"
></a-input-number>
</a-form-item>
</a-col>
</a-row>
@@ -1724,12 +2096,33 @@ onMounted(() => {
</ProModal>
<!-- 上传导入表格数据文件框 -->
<UploadModal :title="uploadImportState.title" :loading="uploadImportState.loading"
@upload="fnModalUploadImportUpload" @close="fnModalUploadImportClose" v-model:open="uploadImportState.open"
:ext="['.txt']" :size="10">
<UploadModal
:title="uploadImportState.title"
:loading="uploadImportState.loading"
@upload="fnModalUploadImportUpload"
@close="fnModalUploadImportClose"
v-model:open="uploadImportState.open"
:ext="['.txt']"
:size="10"
>
<template #default>
<a-textarea :disabled="true" :hidden="!uploadImportState.msg" :value="uploadImportState.msg"
:auto-size="{ minRows: 2, maxRows: 8 }" style="background-color: transparent; color: rgba(0, 0, 0, 0.85)" />
<a-alert
:message="uploadImportState.msg"
:type="uploadImportState.hasFail ? 'warning' : 'info'"
v-show="uploadImportState.msg.length > 0"
>
<template #action>
<a-button
size="small"
type="link"
danger
@click="fnModalUploadImportFailReason"
v-if="uploadImportState.hasFail"
>
{{ t('views.neUser.auth.importFail') }}
</a-button>
</template>
</a-alert>
</template>
</UploadModal>
</PageContainer>