ae92c7d6 by fanguang Committed by lihua

标注代码表导入

1 parent 193e9c24
......@@ -258,6 +258,17 @@ const routes: RouteRecordRaw[] = [
breadcrumb: false,
cache: true
}
},
{
path: 'standard-import',
name: 'metadataStandardImport',
component: () => import('@/views/data_meta/standard-import.vue'),
meta: {
title: '标准代码导入',
breadcrumb: false,
cache: true,
activeMenu: '/data-meta/metadata-standard/standard-codetable'
}
}
]
}
......
......@@ -26,6 +26,7 @@ const { proxy } = getCurrentInstance() as any;
const cacheStore = useCatchStore()
const standardGuid = ref("")
const standardName = ref('')
const tableSearchInput = ref('')
const tableFields: any = ref([])
const orginData: any = ref([])
......@@ -156,19 +157,17 @@ const tablePageChange = (info) => {
};
const toolBtnClick = (btn) => {
console.log('btnType', btn)
const type = btn.value
if (type == 'export') {
exportData()
} else if (type == 'import') {
const info = {
type: 'dictionary',
standardGuid: standardGuid.value
}
const info = [
{ standardGuid: standardGuid.value, standardName: standardName.value }
]
cacheStore.setCatch('uploadSetting', info)
nextTick(() => {
router.push({
path: '/data-inventory/data-dictionary/import-file',
path: '/data-meta/metadata-standard/standard-import',
});
})
} else if (type == 'submit') {
......@@ -537,6 +536,7 @@ const dialogBtnClick = (btn, info) => {
defineExpose({
standardGuid,
standardName,
getFirstPageData,
checkSave
});
......
......@@ -38,6 +38,7 @@ import {
checkDictionaryData,
getNewDataTypeList
} from '@/api/modules/dataInventory';
import router from '@/router'
const { proxy } = getCurrentInstance() as any;
......@@ -103,6 +104,7 @@ const page = ref({
],
});
const selectRowData = ref([])
const selectedRowData = ref([])
const tableInfo: any = ref({
id: 'data-source-table',
multiple: true,
......@@ -140,6 +142,7 @@ const orginOptions = [
{ label: 'code', value: 'code' },
{ label: 'name', value: 'name' },
]
let codeOptions = ref([])
const orginItems = [
{
label: '标准类型',
......@@ -306,18 +309,17 @@ const formItems: any = ref([
required: true
},
{
label: '编码字段',
label: '编码字段11',
type: 'select',
placeholder: '请选择',
field: 'codeFields',
default: [],
options: [
{ label: 'code', value: 'code' },
{ label: 'name', value: 'name' }
],
options: codeOptions,
clearable: true,
required: true,
multiple: true
multiple: true,
tagsTooltip: true,
filterable: true,
},
{
label: '编码名称',
......@@ -325,10 +327,7 @@ const formItems: any = ref([
placeholder: '请选择',
field: 'codeFieldName',
default: '',
options: [
{ label: 'code', value: 'code' },
{ label: 'name', value: 'name' }
],
options: codeOptions,
clearable: true,
required: true
},
......@@ -759,6 +758,7 @@ const tableSelectionChange = (val, tId) => {
}
} else {
selectRowData.value = val.map((item) => item.guid);
selectedRowData.value = val
}
};
......@@ -789,11 +789,7 @@ const setCodeOptions = () => {
opts.push(row)
}
})
formItems.value.at(-1).children.map(child => {
if (child.type == 'select') {
child.options = opts
}
})
codeOptions.value = opts
}
const toolBtnClick = (btn, data) => {
......@@ -1222,7 +1218,7 @@ const loadDrawer = async () => {
drawerInfo.value.visible = true
console.log('table', formTable.value)
console.log('formInfo', formInfo)
setCodeOptions()
};
const batching = (type) => {
......@@ -1238,6 +1234,26 @@ const batching = (type) => {
open("此操作将永久删除, 是否继续?", "warning", true);
tableInfo.value.loading = false
}
if (type == 'export') {
if (selectRowData.value.length == 0) {
ElMessage({
type: 'error',
message: '请选择代码名称',
})
return
}
// console.log(selectedRowData)
let uploadSetting = selectedRowData.value.map(item => {
return {
standardName: item.codeName,
standardGuid: item.guid
}
})
cacheStore.setCatch('uploadSetting', uploadSetting)
router.push({
path: '/data-meta/metadata-standard/standard-import',
});
}
};
const nodeClick = (data) => {
......@@ -1251,6 +1267,7 @@ const nodeClick = (data) => {
showFiledsPage.value = true
nextTick(() => {
dictFiledsRef.value.standardGuid = data.value
dictFiledsRef.value.standardName = data.label
dictFiledsRef.value.getFirstPageData()
})
} else {
......@@ -1354,6 +1371,7 @@ const setDetailInfo = () => {
drawerInfo.value.container.contents = contents.value['add']
drawerInfo.value.visible = true
setCodeOptions()
}
const saveData = async (params) => {
......@@ -1504,6 +1522,7 @@ onMounted(() => {
<div class="tools_btns">
<el-button type="primary" @click="loadDrawer" v-preReClick>新建</el-button>
<el-button @click="batching('delete')" v-preReClick>批量删除</el-button>
<el-button @click="batching('export')" v-preReClick>批量导入</el-button>
</div>
<el-input class="table_search_input" v-model.trim="tableSearchInput" placeholder="请输入代码名称搜索"
:suffix-icon="Search" clearable @change="val => getFirstPageData()" />
......
<route lang="yaml">
name: importFile
</route>
<script lang="ts" setup name="importFile">
import { ref } from "vue";
import { useRoute, useRouter } from "vue-router"
import useUserStore from "@/store/modules/user";
import { ElMessage, ElMessageBox } from "element-plus";
import Tabs from '@/components/Tabs/index.vue'
import Table from '@/components/Table/index.vue'
import Dialog from '@/components/Dialog/index.vue'
import useCatchStore from "@/store/modules/catch";
import { download, downFileByBob, downFile } from '@/utils/common'
import {
addImportData,
deleteImportData,
getImportData,
exportDictionary,
exportCollectTask,
// getImageContent
} from '@/api/modules/queryService';
import {
parseAndDecodeUrl,
getDownFileSignByUrl,
obsDownloadRequest
} from '@/api/modules/obsService';
import {
getDictionaryTree
} from '@/api/modules/dataInventory';
import { commonPageConfig } from '@/utils/enum';
const { proxy } = getCurrentInstance() as any;
const userStore = useUserStore()
const route = useRoute()
const router = useRouter()
/** 2表示资产目录的。3是主数据; 4是元数据导入 */
const isfileImport = route.query.isfileImport
const userData = JSON.parse(userStore.userData)
const cacheStore = useCatchStore()
const standardSetList = ref([])
const standardSetGuid = ref('')
const dictionaryList = ref([])
const dictionaryGuid = ref('')
const tabsActiveName = ref('')
const uploadSetting: any = ref([])
const importType = ref('')
const defaulttabs = [
// { label: '标准集导入', name: 'standard' },
// { label: '字段标准导入', name: 'field' },
// { label: '命名标准导入', name: 'naming' },
{ label: '数据字典导入', name: 'dictionary' },
// { label: '质量模型导入', name: 'qualityModelGroup' },
// { label: '质量规则导入', name: 'qualityRule' },
]
const importTabs = [
{ label: '导入文件数据', name: 'importFile' },
// { label: '质量模型导入', name: 'qualityModelGroup' },
// { label: '质量规则导入', name: 'qualityRule' },
]
const tabsInfo = ref({
activeName: '',
tabs: isfileImport ? importTabs : defaulttabs
})
const currTableData: any = ref<Object>({});
const page = ref(commonPageConfig);
const selectRowData = ref([])
const tableInfo = ref({
id: 'data-source-table',
multiple: true,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "文件名称", field: "fileName", width: 240, },
{ label: "状态", field: "importState", type: 'tag', width: 110, align: 'center' },
{ label: "导入结果", field: "importMessage", width: 280 },
{ label: "导入时间", field: "createTime", width: 180 },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 220,
fixed: 'right',
btns: (scope) => {
const row = scope.row
let btnsArr = [
{ label: '下载文件', value: 'export_file' },
{ label: '删除', value: 'delete' }
]
if (row.importState != 0 && row.importState != 1) {
btnsArr.splice(1, 0, { label: '下载异常数据', value: 'export_abnormal_data' })
}
return btnsArr
},
},
loading: false
})
const uploadFiles = ref([])
const uploadSteps: any = ref([])
const uploadInfo = ref({
type: 'upload',
title: '',
col: '',
uploadInfo: {
id: 'upload-file-form',
type: 'panel',
steps: [],
extraParams: {dictionaryGuid: 'xx'},
},
})
const dialogInfo: any = ref({
visible: false,
size: 700,
direction: "column",
header: {
title: "新建",
},
type: 'upload',
contents: [
uploadInfo.value
],
footer: {
visible: true,
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", loading: false, label: "开始导入", value: "submit" },
],
},
})
// // 获取所有数据字典
const getDictList = () => {
const params = {
paramCode: '数据字典类型'
}
getDictionaryTree(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data ?? []
const treeList = data.filter(item => item.children && item.children.length)
dictionaryList.value = treeList
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
})
}
const tabsChange = (name) => {
tabsActiveName.value = name
let info: any = {
type: name
}
if (tabsActiveName.value == 'field' || tabsActiveName.value == 'naming') {
info.standardSetGuid = standardSetGuid.value
} else if (tabsActiveName.value == 'dictionary') {
info.dictionaryGuid = dictionaryGuid.value
} else if (tabsActiveName.value == 'importFile') {
}
cacheStore.setCatch('uploadSetting', info)
setUploadInfo()
}
const getFirstPageData = () => {
page.value.curr = 1
toSearch({})
console.log('store', cacheStore.getCatch('uploadSetting'))
}
const toSearch = (val: any, clear: boolean = false) => {
let params: any = Object.keys(val).length ? { ...val } : {}
params.pageIndex = page.value.curr;
params.pageSize = page.value.limit;
params.staffGuid = userData.staffGuid;
params.importType = importType.value;
params.bizGuid = route.query.bizGuid || ''
getTableData(params);
};
const getTableData = (params) => {
tableInfo.value.loading = true
getImportData(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || {}
tableInfo.value.data = data.records || []
tableInfo.value.page.limit = data.pageSize
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
tableInfo.value.loading = false
}).catch(xhr => {
tableInfo.value.loading = false
})
};
const tableSelectionChange = (val) => {
selectRowData.value = val.map(item => item.guid);
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
toSearch({});
};
const tableBtnClick = async (scope, btn) => {
const type = btn.value;
const row = scope.row;
currTableData.value = row;
if (type == "export_file") {
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.filePath).fileName);
if (!refSignInfo?.data) {
refSignInfo?.msg && ElMessage.error(refSignInfo?.msg);
return;
}
obsDownloadRequest(refSignInfo?.data).then((res: any) => {
if (res && !res.msg) {
downFileByBob(res, row.fileName);
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
//downFile(row.filePath, row.fileName)
} else if (type == 'export_abnormal_data') {
//downFile(row.errorFilePath, '')
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.errorFilePath).fileName);
if (!refSignInfo?.data) {
refSignInfo?.msg && ElMessage.error(refSignInfo?.msg);
return;
}
obsDownloadRequest(refSignInfo?.data).then((res: any) => {
if (res && !res.msg) {
let name = row.errorFilePath;
let fileName = name ? name.substring(name.lastIndexOf('/') + 1) : ''
downFileByBob(res, fileName);
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
} else if (type == "delete") {
open("此操作将永久删除, 是否继续?", "warning");
}
};
const batching = (type) => {
if (type == 'import') {
dialogInfo.value.header.title = '导入数据'
dialogInfo.value.type = 'upload'
dialogInfo.value.size = 640
uploadFiles.value = []
// if (tabsActiveName.value == 'field' || tabsActiveName.value == 'naming') {
// uploadSteps.value[0].selectInfo.options = standardSetList.value
// } else if (tabsActiveName.value == 'dictionary') {
// uploadSteps.value[0].cascaderInfo.options = dictionaryList.value
// }
uploadInfo.value.uploadInfo.steps = uploadSteps.value
const content: any = [uploadInfo.value]
dialogInfo.value.contents = content
dialogInfo.value.visible = true
} else if (type == 'delete') {
if (selectRowData.value.length == 0) {
ElMessage({
type: 'error',
message: '请选择需要删除的数据',
})
return
}
open("此操作将永久删除, 是否继续?", "warning", true);
} else if (type === 'importFile') {
if (isfileImport == '2' || isfileImport == '4') {
dialogInfo.value.header.title = '导入数据'
dialogInfo.value.type = 'upload'
dialogInfo.value.size = isfileImport == '4' ? 600 : 500;
uploadFiles.value = []
uploadInfo.value.uploadInfo.steps = uploadSteps.value
const content: any = [uploadInfo.value]
dialogInfo.value.contents = content
dialogInfo.value.visible = true
} else {
router.push({
name: "importData",
query: route.query
})
}
}
};
const open = (msg, type, isBatch = false) => {
ElMessageBox.confirm(msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: type,
}).then(() => {
let guids = [currTableData.value.guid]
if (isBatch) {
guids = selectRowData.value
}
deleteImportData(guids).then((res: any) => {
if (res.code == proxy.$passCode) {
getFirstPageData();
ElMessage({
type: "success",
message: "删除成功",
});
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
});
});
};
const onUpload = (file, fileList) => {
uploadFiles.value = fileList
}
const uploadBtnClick = (btn) => {
exportData()
}
const cascaderChange = (val) => {
dictionaryGuid.value = val ? val.at(-1) : ''
}
const selectChange = (val) => {
standardSetGuid.value = val
}
const exportData = (ids: any = null) => {
if (tabsActiveName.value == 'standard') {
const fieldTemplate = "/files/set.xlsx";
downFile(fieldTemplate, '标准集模板.xlsx')
} else if (tabsActiveName.value == 'field') {
const fieldTemplate = "/files/field.xlsx";
downFile(fieldTemplate, '字段标准模板.xlsx')
} else if (tabsActiveName.value == 'naming') {
const namingTemplate = "/files/naming.xlsx";
downFile(namingTemplate, '命名标准模板.xlsx')
} else if (tabsActiveName.value == 'dictionary') {
const params = {
guid: dictionaryGuid.value
}
exportDictionary(params).then((res: any) => {
if (res && !res.msg) {
download(res, '数据字典模板.xlsx', 'excel');
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
} else if (tabsActiveName.value == 'importFile' && isfileImport == '4') {
exportCollectTask({
importTypes: [
"0042"
]
}).then((res: any) => {
if (res && !res.msg) {
download(res, '元数据模板.xlsx', 'excel');
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
}
}
const importData = (info) => {
let params = new FormData()
if (uploadFiles.value.length == 0) {
ElMessage({
type: 'error',
message: '请选择上传文件'
})
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
return
}
let sheetPass = uploadSetting.value.every(item => item.value)
if (!sheetPass) {
ElMessage({ type: 'error', message: '请选择sheet页'})
return
}
let paramUrl = '';
uploadFiles.value.forEach((item: any, index: number) => {
params.append("file", item.raw);
});
let sheetMaps = {}
uploadSetting.value.forEach(item => {
sheetMaps[item.value] = item.standardGuid
})
sheetMaps = JSON.stringify(sheetMaps)
// console.log('sheetMaps', sheetMaps)
paramUrl = encodeURI(`${import.meta.env.VITE_APP_ADD_FILE}/import-data/import-batch-common?importType=${importType.value}&staffGuid=${userData.staffGuid}&tenantGuid=${userData.tenantGuid}&sheetMaps=${sheetMaps}`)
// if (info && Object.keys(info).length) {
// paramUrl += `&extendFields=${encodeURIComponent(JSON.stringify(info))}`
// }
dialogInfo.value.footer.btns[1].loading = true;
addImportData(paramUrl, params).then((res: any) => {
dialogInfo.value.footer.btns[1].loading = false;
if (res.code == proxy.$passCode) {
getFirstPageData();
ElMessage({
type: "success",
message: '导入成功',
});
dialogInfo.value.visible = false;
} else {
ElMessage({
type: "error",
message: res.msg,
});
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
}
}).catch(() => {
dialogInfo.value.footer.btns[1].loading = false;
})
}
const dialogBtnClick = (btn, info) => {
if (btn.value == 'submit') {
// dialogInfo.value.footer.btns.map((item: any) => item.disabled = true)
if (dialogInfo.value.type == 'upload') {
if (tabsActiveName.value == 'dictionary') {
importData({ bizGuid: dictionaryGuid.value })
} else {
importData(info)
}
}
} else if (btn.value == 'cancel') {
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
nextTick(() => {
dialogInfo.value.visible = false;
})
};
}
const setUploadInfo = () => {
importType.value = '0101'
tabsInfo.value.activeName = tabsActiveName.value
getFirstPageData()
uploadSteps.value = [
{
title: '1、选择准备好的文件导入',
type: 'btn_upload',
uploadInfo: {
action: '',
auto: false,
cover: true,
fileList: [],
accept: '.xlsx, .xls',
tips: '当前支持xls、xlsx文件,支持一个文件多个sheet批量导入'
}
}
]
}
onActivated(() => {
let list = cacheStore.getCatch('uploadSetting') || []
uploadSetting.value = list.map(item => {
item.value = null
return item
})
console.log('uploadSetting', uploadSetting.value)
setUploadInfo()
})
</script>
<template>
<div class="container_wrap">
<!-- <Tabs v-if="!isfileImport" :tabs-info="tabsInfo" @tabChange="tabsChange" /> -->
<div class="table_tool_wrap">
<div class="tools_btns">
<el-button type="primary" @click="batching('import')" v-if="tabsActiveName !== 'importFile'"
v-preReClick>批量导入</el-button>
<el-button type="primary" @click="batching('importFile')" v-if="tabsActiveName == 'importFile'"
v-preReClick>文件导入</el-button>
<el-button @click="batching('delete')" v-preReClick>批量删除</el-button>
<el-button @click="getFirstPageData" v-preReClick>刷新结果</el-button>
</div>
<span class="tips_text">请及时刷新查看最终结果</span>
</div>
<div class="table_panel_wrap" :style="{ height: !isfileImport ? 'calc(100% - 71px)' : 'calc(100% - 44px)' }">
<Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tableSelectionChange="tableSelectionChange"
@tablePageChange="tablePageChange" />
</div>
<Dialog :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" @onUpload="onUpload" @uploadBtnClick="uploadBtnClick"
@cascaderChange="cascaderChange" @selectChange="selectChange">
<div>
<div class="title" style="color:#333">2、导入前请先导入文件的sheet与标准做对应</div>
<el-form :label-width="120" style="margin-top:20px">
<el-form-item label="全局变量">
<span>选择sheet页</span>
</el-form-item>
<el-form-item v-for="item in uploadSetting" :key="item.standardGuid" :label="item.standardName" required >
<el-select v-model="item.value" placeholder="请选择" style="width:200px" clearable>
<el-option v-for="i in uploadSetting.length" :label="`Sheet${i}`" :value="`Sheet${i}`" :key="i"></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</Dialog>
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
padding: 0;
:deep(.el-tabs) {
.el-tabs__header {
margin-bottom: 0;
}
.el-tabs__item {
height: 32px;
&:nth-child(2) {
padding-left: 16px;
}
&:last-child {
padding-right: 16px;
}
&::after {
content: '';
width: 100%;
height: 2px;
background-color: transparent;
position: absolute;
left: 0;
bottom: 0;
}
&.is-active {
&::after {
background-color: var(--el-color-primary);
}
}
}
.el-tabs__active-bar {
display: none;
}
}
.table_tool_wrap {
padding: 0 16px;
display: flex;
align-items: center;
.tips_text {
margin-left: 16px;
font-size: 14px;
color: #b2b2b2;
}
}
.table_panel_wrap {
padding: 0 16px;
height: calc(100% - 71px);
}
}
</style>
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!