feat: 基站状态导入功能

This commit is contained in:
TsMask
2025-02-08 19:39:47 +08:00
parent 0346dfd584
commit 7ccb580e91
9 changed files with 198 additions and 30 deletions

BIN
public/nbStateImput/en.xlsx Normal file

Binary file not shown.

BIN
public/nbStateImput/zh.xlsx Normal file

Binary file not shown.

View File

@@ -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: {

View File

@@ -727,6 +727,7 @@ export default {
editRadio: "更新基站信息", editRadio: "更新基站信息",
history: "历史记录", history: "历史记录",
exportTip: "确认根据搜索条件导出xlsx表格文件吗?", exportTip: "确认根据搜索条件导出xlsx表格文件吗?",
importDataEmpty: "导入数据为空",
}, },
}, },
neUser: { neUser: {

View File

@@ -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(

View File

@@ -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}`,

View File

@@ -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');

View File

@@ -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>