feat: 基站状态导入功能
This commit is contained in:
BIN
public/nbStateImput/en.xlsx
Normal file
BIN
public/nbStateImput/en.xlsx
Normal file
Binary file not shown.
BIN
public/nbStateImput/zh.xlsx
Normal file
BIN
public/nbStateImput/zh.xlsx
Normal file
Binary file not shown.
@@ -727,6 +727,7 @@ export default {
|
|||||||
editRadio: "Edit Radio Info",
|
editRadio: "Edit Radio Info",
|
||||||
history: "Status History",
|
history: "Status History",
|
||||||
exportTip: "Confirm exporting xlsx table files based on search criteria?",
|
exportTip: "Confirm exporting xlsx table files based on search criteria?",
|
||||||
|
importDataEmpty: "Imported data is empty",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
neUser: {
|
neUser: {
|
||||||
|
|||||||
@@ -727,6 +727,7 @@ export default {
|
|||||||
editRadio: "更新基站信息",
|
editRadio: "更新基站信息",
|
||||||
history: "历史记录",
|
history: "历史记录",
|
||||||
exportTip: "确认根据搜索条件导出xlsx表格文件吗?",
|
exportTip: "确认根据搜索条件导出xlsx表格文件吗?",
|
||||||
|
importDataEmpty: "导入数据为空",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
neUser: {
|
neUser: {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export async function readLoalXlsx(
|
|||||||
/**
|
/**
|
||||||
* 读取表格数据 工作表
|
* 读取表格数据 工作表
|
||||||
* @param fileBolb 文件对象
|
* @param fileBolb 文件对象
|
||||||
* @param index 文件保存路径
|
* @param index SheetName索引
|
||||||
* @return 表格对象列表
|
* @return 表格对象列表
|
||||||
*/
|
*/
|
||||||
export async function readSheet(
|
export async function readSheet(
|
||||||
|
|||||||
@@ -150,12 +150,6 @@ let tableColumns = ref<ColumnsType>([
|
|||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
maxWidth: 200,
|
maxWidth: 200,
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// title: t('views.neData.baseStation.ueNum'),
|
|
||||||
// dataIndex: 'ueNum',
|
|
||||||
// align: 'left',
|
|
||||||
// width: 80,
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
title: t('views.neData.baseStation.state'),
|
title: t('views.neData.baseStation.state'),
|
||||||
dataIndex: 'state',
|
dataIndex: 'state',
|
||||||
@@ -215,7 +209,7 @@ function fnExportList() {
|
|||||||
content: t('common.operateOk'),
|
content: t('common.operateOk'),
|
||||||
duration: 3,
|
duration: 3,
|
||||||
});
|
});
|
||||||
saveAs(res.data, `nb_state_records_export_${Date.now()}.xlsx`);
|
saveAs(res.data, `nb_state_history_records_export_${Date.now()}.xlsx`);
|
||||||
} else {
|
} else {
|
||||||
message.error({
|
message.error({
|
||||||
content: `${res.msg}`,
|
content: `${res.msg}`,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
import { PageContainer } from 'antdv-pro-layout';
|
||||||
import ListComponent from '@/views/ne-data/base-station/components/list.vue';
|
import ListComponent from './list.vue';
|
||||||
import TopologyComponent from '@/views/ne-data/base-station/components/topology.vue';
|
import TopologyComponent from './topology.vue';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const value = ref<string>('list');
|
const value = ref<string>('list');
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ import { Form, message, Modal } from 'ant-design-vue';
|
|||||||
import { SizeType } from 'ant-design-vue/es/config-provider';
|
import { SizeType } from 'ant-design-vue/es/config-provider';
|
||||||
import { ColumnsType } from 'ant-design-vue/es/table';
|
import { ColumnsType } from 'ant-design-vue/es/table';
|
||||||
import { ProModal } from 'antdv-pro-modal';
|
import { ProModal } from 'antdv-pro-modal';
|
||||||
|
import UploadModal from '@/components/UploadModal/index.vue';
|
||||||
import useNeInfoStore from '@/store/modules/neinfo';
|
import useNeInfoStore from '@/store/modules/neinfo';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
const { t } = useI18n();
|
const { t, currentLocale } = useI18n();
|
||||||
import {
|
import {
|
||||||
addAMFNbState,
|
addAMFNbState,
|
||||||
delAMFNbState,
|
delAMFNbState,
|
||||||
@@ -28,9 +29,11 @@ import {
|
|||||||
} from '@/api/neData/mme';
|
} from '@/api/neData/mme';
|
||||||
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 { writeSheet } from '@/utils/execl-utils';
|
import { readSheet, writeSheet } from '@/utils/execl-utils';
|
||||||
// 异步加载组件
|
// 异步加载组件
|
||||||
const HistoryModal = defineAsyncComponent(() => import('./history.vue'));
|
const HistoryModal = defineAsyncComponent(
|
||||||
|
() => import('./components/history.vue')
|
||||||
|
);
|
||||||
|
|
||||||
const nbState = ref<DictType[]>([
|
const nbState = ref<DictType[]>([
|
||||||
{
|
{
|
||||||
@@ -311,20 +314,22 @@ const stateNum = computed(() => {
|
|||||||
type ModalStateType = {
|
type ModalStateType = {
|
||||||
/**新增框或修改框是否显示 */
|
/**新增框或修改框是否显示 */
|
||||||
openByEdit: boolean;
|
openByEdit: boolean;
|
||||||
/**历史框 */
|
|
||||||
openByHistory: boolean;
|
|
||||||
/**标题 */
|
/**标题 */
|
||||||
title: string;
|
title: string;
|
||||||
/**表单数据 */
|
/**表单数据 */
|
||||||
from: Record<string, any>;
|
from: Record<string, any>;
|
||||||
/**确定按钮 loading */
|
/**确定按钮 loading */
|
||||||
confirmLoading: boolean;
|
confirmLoading: boolean;
|
||||||
|
/**历史框 */
|
||||||
|
openByHistory: boolean;
|
||||||
|
/**导入框 */
|
||||||
|
openByImport: boolean;
|
||||||
|
importMsgArr: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**对话框对象信息状态 */
|
/**对话框对象信息状态 */
|
||||||
let modalState: ModalStateType = reactive({
|
let modalState: ModalStateType = reactive({
|
||||||
openByEdit: false,
|
openByEdit: false,
|
||||||
openByHistory: false,
|
|
||||||
title: 'NB Config List',
|
title: 'NB Config List',
|
||||||
from: {
|
from: {
|
||||||
address: '',
|
address: '',
|
||||||
@@ -338,6 +343,9 @@ let modalState: ModalStateType = reactive({
|
|||||||
ueNum: undefined,
|
ueNum: undefined,
|
||||||
},
|
},
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
|
openByHistory: false,
|
||||||
|
openByImport: false,
|
||||||
|
importMsgArr: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
/**对话框内表单属性和校验规则 */
|
/**对话框内表单属性和校验规则 */
|
||||||
@@ -448,11 +456,6 @@ function fnModalCancel() {
|
|||||||
modalStateFrom.resetFields();
|
modalStateFrom.resetFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**跳转字典数据页面 */
|
|
||||||
function fnHistoryView() {
|
|
||||||
modalState.openByHistory = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**导出当前列表 */
|
/**导出当前列表 */
|
||||||
function fnExportList() {
|
function fnExportList() {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
@@ -501,12 +504,7 @@ function fnExportList() {
|
|||||||
t('views.neData.baseStation.time'),
|
t('views.neData.baseStation.time'),
|
||||||
],
|
],
|
||||||
}).then(fileBlob =>
|
}).then(fileBlob =>
|
||||||
saveAs(
|
saveAs(fileBlob, `nb_state_records_export_${Date.now()}.xlsx`)
|
||||||
fileBlob,
|
|
||||||
`${t('views.neData.baseStation.state')}_${t(
|
|
||||||
'views.neData.baseStation.list'
|
|
||||||
)}_${Date.now()}.xlsx`
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
modalState.confirmLoading = false;
|
modalState.confirmLoading = false;
|
||||||
@@ -515,6 +513,144 @@ function fnExportList() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**对话框弹出历史窗口 */
|
||||||
|
function fnHistoryView() {
|
||||||
|
modalState.openByHistory = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框表格信息导入弹出窗口 */
|
||||||
|
function fnModalImportOpen() {
|
||||||
|
modalState.openByImport = true;
|
||||||
|
}
|
||||||
|
function fnModalImportClose() {
|
||||||
|
modalState.openByImport = false;
|
||||||
|
fnQueryReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框表格信息导入上传 */
|
||||||
|
function fnModalImportUpload(file: File) {
|
||||||
|
const hide = message.loading(t('common.loading'), 0);
|
||||||
|
const [neType, neId] = neTypeAndId.value;
|
||||||
|
modalState.importMsgArr = [];
|
||||||
|
|
||||||
|
// 获取最大index
|
||||||
|
let index = 0;
|
||||||
|
if (tableState.data.length <= 0) {
|
||||||
|
index = 1;
|
||||||
|
} else {
|
||||||
|
const last = tableState.data[tableState.data.length - 1];
|
||||||
|
index = last.index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = function (e: any) {
|
||||||
|
const arrayBuffer = e.target.result;
|
||||||
|
readSheet(arrayBuffer).then(async rows => {
|
||||||
|
console.log(rows);
|
||||||
|
if (rows.length <= 0) {
|
||||||
|
hide();
|
||||||
|
message.error({
|
||||||
|
content: t('views.neData.baseStation.importDataEmpty'),
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 开始导入
|
||||||
|
modalState.confirmLoading = true;
|
||||||
|
for (const row of rows) {
|
||||||
|
const rowId = row[t('common.rowId')];
|
||||||
|
const name = row[t('views.neData.baseStation.name')];
|
||||||
|
const position = row[t('views.neData.baseStation.position')];
|
||||||
|
const address = row[t('views.neData.baseStation.address')];
|
||||||
|
let result: any = null;
|
||||||
|
// 检查IP地址是否定义
|
||||||
|
const hasAddress = tableState.data.find(
|
||||||
|
item => item.address === address
|
||||||
|
);
|
||||||
|
if (hasAddress) {
|
||||||
|
// 定义则更新名称位置
|
||||||
|
if (neType === 'MME') {
|
||||||
|
result = await editMMENbState(
|
||||||
|
neId,
|
||||||
|
Object.assign({}, hasAddress, {
|
||||||
|
name,
|
||||||
|
position,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (neType === 'AMF') {
|
||||||
|
result = await editAMFNbState(
|
||||||
|
neId,
|
||||||
|
Object.assign({}, hasAddress, {
|
||||||
|
name,
|
||||||
|
position,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let msg = `${t('common.rowId')}: ${rowId} ${t(
|
||||||
|
'views.neData.baseStation.editRadio'
|
||||||
|
)}${t('common.operateErr')}`;
|
||||||
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
|
msg = `${t('common.rowId')}: ${rowId} ${t(
|
||||||
|
'views.neData.baseStation.editRadio'
|
||||||
|
)}${t('common.operateOk')}`;
|
||||||
|
}
|
||||||
|
modalState.importMsgArr.push(msg);
|
||||||
|
} else {
|
||||||
|
// 未定义则新增
|
||||||
|
const form = {
|
||||||
|
index,
|
||||||
|
name: `${name}`,
|
||||||
|
position: `${position}`,
|
||||||
|
address: `${address}`,
|
||||||
|
};
|
||||||
|
if (neType === 'MME') {
|
||||||
|
result = await addMMENbState(neId, form);
|
||||||
|
}
|
||||||
|
if (neType === 'AMF') {
|
||||||
|
result = await addAMFNbState(neId, form);
|
||||||
|
}
|
||||||
|
let msg = `${t('common.rowId')}: ${rowId} ${t(
|
||||||
|
'views.neData.baseStation.addRadio'
|
||||||
|
)}${t('common.operateErr')}`;
|
||||||
|
if (result.code === RESULT_CODE_SUCCESS) {
|
||||||
|
index += 1;
|
||||||
|
msg = `${t('common.rowId')}: ${rowId} ${t(
|
||||||
|
'views.neData.baseStation.addRadio'
|
||||||
|
)}${t('common.operateOk')}`;
|
||||||
|
}
|
||||||
|
modalState.importMsgArr.push(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hide();
|
||||||
|
modalState.confirmLoading = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
reader.onerror = function (e) {
|
||||||
|
hide();
|
||||||
|
console.error('reader file error:', e);
|
||||||
|
};
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**对话框表格信息导入模板 */
|
||||||
|
async function fnModalImportTemplate() {
|
||||||
|
const baseUrl = import.meta.env.VITE_HISTORY_BASE_URL;
|
||||||
|
const xlsxUrl = `${
|
||||||
|
baseUrl.length === 1 && baseUrl.indexOf('/') === 0
|
||||||
|
? ''
|
||||||
|
: baseUrl.indexOf('/') === -1
|
||||||
|
? '/' + baseUrl
|
||||||
|
: baseUrl
|
||||||
|
}/nbStateImput`;
|
||||||
|
const lang = currentLocale.value.split('_')[0];
|
||||||
|
saveAs(
|
||||||
|
`${xlsxUrl}/${lang}.xlsx`,
|
||||||
|
`nb_state_records_import_template_${Date.now()}.xlsx`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 获取网元网元列表
|
// 获取网元网元列表
|
||||||
useNeInfoStore()
|
useNeInfoStore()
|
||||||
@@ -633,14 +769,18 @@ onMounted(() => {
|
|||||||
<template #icon><DeleteOutlined /></template>
|
<template #icon><DeleteOutlined /></template>
|
||||||
{{ t('common.deleteText') }}
|
{{ t('common.deleteText') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button type="default" @click.prevent="fnHistoryView()">
|
<a-button type="dashed" @click.prevent="fnModalImportOpen()">
|
||||||
<template #icon><ContainerOutlined /></template>
|
<template #icon><ImportOutlined /></template>
|
||||||
{{ t('views.neData.baseStation.history') }}
|
{{ t('common.import') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button type="dashed" @click.prevent="fnExportList()">
|
<a-button type="dashed" @click.prevent="fnExportList()">
|
||||||
<template #icon><ExportOutlined /></template>
|
<template #icon><ExportOutlined /></template>
|
||||||
{{ t('common.export') }}
|
{{ t('common.export') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
|
<a-button type="default" @click.prevent="fnHistoryView()">
|
||||||
|
<template #icon><ContainerOutlined /></template>
|
||||||
|
{{ t('views.neData.baseStation.history') }}
|
||||||
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -773,6 +913,38 @@ onMounted(() => {
|
|||||||
:ne-id="neTypeAndId[1]"
|
:ne-id="neTypeAndId[1]"
|
||||||
@cancel="fnModalCancel"
|
@cancel="fnModalCancel"
|
||||||
></HistoryModal>
|
></HistoryModal>
|
||||||
|
|
||||||
|
<!-- 上传导入表格数据文件框 -->
|
||||||
|
<UploadModal
|
||||||
|
:title="t('common.import')"
|
||||||
|
@upload="fnModalImportUpload"
|
||||||
|
@close="fnModalImportClose"
|
||||||
|
v-model:open="modalState.openByImport"
|
||||||
|
:ext="['.xls', '.xlsx']"
|
||||||
|
:size="10"
|
||||||
|
>
|
||||||
|
<template #default>
|
||||||
|
<a-row justify="space-between" align="middle">
|
||||||
|
<a-col :span="12"> </a-col>
|
||||||
|
<a-col :span="6">
|
||||||
|
<a-button
|
||||||
|
type="link"
|
||||||
|
:title="t('views.system.user.downloadObj')"
|
||||||
|
@click.prevent="fnModalImportTemplate"
|
||||||
|
>
|
||||||
|
{{ t('views.system.user.downloadObj') }}
|
||||||
|
</a-button>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-textarea
|
||||||
|
:disabled="true"
|
||||||
|
:hidden="modalState.importMsgArr.length <= 0"
|
||||||
|
:value="modalState.importMsgArr.join('\r\n')"
|
||||||
|
:auto-size="{ minRows: 2, maxRows: 8 }"
|
||||||
|
style="background-color: transparent; color: rgba(0, 0, 0, 0.85)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</UploadModal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
Reference in New Issue
Block a user