Commit b4ba0b5e authored by chenjiahao's avatar chenjiahao

数据库离线加载-源端配置

parent 113ba2c7
<template> <template>
<BasicModal <BasicModal
style="width: 50%"
v-bind="$attrs" v-bind="$attrs"
@register="registerModal" @register="registerModal"
:title="getTitle" title="获取元数据"
@ok="handleSubmit" @ok="handleSubmit"
minHeight="50" minHeight="50"
> >
<BasicForm @register="registerForm" /> <div style="display: flex">
<BasicTree title="表名" search :treeData="tableTree" />
<BasicForm @register="registerForm" style="width: 70%">
<template #incrementIdentificationColumnAlert>
<Alert
show-icon
style="font-size: 12px"
message="基于数量的加载策略,要求在进行数据加载时,源端的表不要发生数据变更,否则可能会出现数据加载异常。"
type="info"
/>
</template>
</BasicForm>
</div>
</BasicModal> </BasicModal>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, unref, reactive } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal'; import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form'; import { Alert } from 'ant-design-vue';
import { MoveFormSchema } from './dataEntry.data'; import { ref } from 'vue';
import { useMessage } from '@/hooks/web/useMessage'; import { useMessage } from '@/hooks/web/useMessage';
import { TreeData } from './mock'; import { tableTreeData } from '@/views/dataIntegration/dataLoading/dataEntryLake/mock';
import { BasicTree } from '@/components/Tree';
import { BasicForm, FormSchema, useForm } from '@/components/Form';
const emit = defineEmits(['success', 'register']); const emit = defineEmits(['register']);
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const isUpdate = ref(true); const tableTree = ref(tableTreeData);
const rowId = ref('');
const idList = ref([]); const deplysFormSchema: FormSchema[] = [
const rowData = ref([]); {
let isMove = ref(); field: 'incrementIdentificationColumn',
//获取接口数据并放在下拉框里(这里是打开了一个弹框) label: '增量标识列',
//初始化表单 component: 'Input',
const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({ componentProps: {
labelWidth: 100, placeholder: '',
baseColProps: { span: 24 }, },
schemas: MoveFormSchema, required: true,
showActionButtonGroup: false, ifShow: false,
actionColOptions: { },
span: 23, {
field: 'incrementIdentificationColumnAlert',
component: 'Slot',
slot: 'incrementIdentificationColumnAlert',
ifShow: false,
},
{
field: 'site',
component: 'Checkbox',
label: ' ',
colProps: { lg: 5.5, md: 5.5 },
suffix: '位点',
ifShow: false,
},
{
field: 'divider',
component: 'Divider',
ifShow: false,
}, },
});
//初始化弹框
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log('data', data);
// //每次点击弹窗 需要清空存储的数据
rowData.value = [];
isMove.value = data.isMove;
// //重置表单数据
resetFields();
setModalProps({ confirmLoading: false });
// if (data.idList != null && data.idList.length > 0) {
// /* empty */
// } else {
// rowData.value.push(data.record);
// //单个移动
// rowId.value = data.record.businessId;
// data.record.taskId = data.record.businessId;
// setFieldsValue({
// ...data.record,
// });
// }
const treeList = handleTree(TreeData, 'businessId', undefined, undefined, undefined);
updateSchema([
{ {
field: 'taskId', field: 'loadingStrategy',
label: '加载策略',
component: 'RadioGroup',
defaultValue: '基于数量',
componentProps: { componentProps: {
treeData: treeList, options: [
{ label: '基于数量', value: '基于数量' },
{ label: '基于条件', value: '基于条件' },
],
}, },
}, },
]); {
console.log('treeList:', treeList); component: 'Divider',
},
];
const [registerForm, { updateSchema }] = useForm({
labelWidth: 90,
labelAlign: 'left',
baseColProps: { lg: 24, md: 24 },
schemas: deplysFormSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
}); });
const getTitle = computed(() => '移动'); //初始化弹框
const [registerModal, { closeModal }] = useModalInner(async (data) => {
tableTree.value = tableTreeData.filter((item) => data.myCheckedKeys.includes(item.key));
const flag = data.loadType !== '全量数据加载';
await updateSchema([{ field: 'incrementIdentificationColumn', ifShow: flag }]);
await updateSchema([{ field: 'incrementIdentificationColumnAlert', ifShow: flag }]);
await updateSchema([{ field: 'site', ifShow: flag }]);
await updateSchema([{ field: 'divider', ifShow: flag }]);
});
/**确定按钮*/ /**确定按钮*/
async function handleSubmit() { async function handleSubmit() {
// console.log('isMove.value', isMove.value);
if (isMove.value === 1) {
createMessage.success('移动成功!');
} else {
createMessage.success('复制成功!');
}
closeModal(); closeModal();
} }
/**数组对象转成树*/
function handleTree(data, id, parentId, children, rootId) {
id = id || 'id';
parentId = parentId || 'parentId';
children = children || 'children';
rootId =
rootId ||
Math.min.apply(
Math,
data.map((item) => {
return item[parentId];
}),
) ||
0;
// 对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data));
// 循环所有项
const treeData = cloneData.filter((father) => {
const branchArr = cloneData.filter((child) => {
// 返回每一项的子级数组
return father[id] === child[parentId];
});
branchArr.length > 0 ? (father.children = branchArr) : '';
// 返回第一层
return father[parentId] === rootId;
});
return treeData !== '' ? treeData : data;
}
</script> </script>
<style scoped lang="scss">
.getMetadataInput {
width: 120px;
}
</style>
...@@ -30,26 +30,41 @@ ...@@ -30,26 +30,41 @@
</template> </template>
<div> <div>
<Tabs> <Tabs>
<TabPane key="1" tab="源端配置" style="display: flex"> <TabPane key="1" tab="源端配置">
<div style="display: flex">
<BasicForm @register="registerSourceSideConfigurationForm" style="width: 30%"> <BasicForm @register="registerSourceSideConfigurationForm" style="width: 30%">
<template #getMetadata> <template #getMetadata>
<a-button @click="handleGetMetadata" type="primary">获取元数据</a-button> <a-button @click="handleGetMetadata" type="primary">获取元数据</a-button>
</template> </template>
</BasicForm> </BasicForm>
<div style="width: 20%"> <div style="width: 20%; padding: 0 5px 5px">
<BasicTree <BasicTree
toolbar toolbar
search search
v-if="!metadataAcquisitionModeFlag"
:checkable="true" :checkable="true"
:actionList="actionList" :actionList="actionList"
:treeData="tableTreeData" :treeData="tableTreeData"
v-model:checkedKeys="checkedKeys" v-model:checkedKeys="myCheckedKeys"
@select="handleSelect" @select="handleSelect"
> >
<template #headerTitle> <template #headerTitle>
表头 <a @click="handleDeplys" style="margin-left: 2px">批量配置</a> 表名
<a v-if="myCheckedKeys.length > 0" @click="handleDeplys" style="margin-left: 2px"
>批量配置</a
>
<a v-else style="color: grey; margin-left: 2px">批量配置</a>
</template> </template>
</BasicTree> </BasicTree>
<div v-else>
<div style="display: flex; justify-content: space-between">
<strong>自定义查询SQL</strong>
<a-button type="primary" style="margin-right: 5px" @click="handleParsingSQL"
>解析SQL</a-button
>
</div>
<CodeEditor v-model:value="sql" style="height: 100%" />
</div>
</div> </div>
<BasicForm @register="registerLoadingStrategyForm" style="width: 50%"> <BasicForm @register="registerLoadingStrategyForm" style="width: 50%">
<template #quantityBasedAlert> <template #quantityBasedAlert>
...@@ -82,6 +97,9 @@ ...@@ -82,6 +97,9 @@
<template #isCustomSQLTable> <template #isCustomSQLTable>
<BasicTable @register="registerIsCustomSQLTable" /> <BasicTable @register="registerIsCustomSQLTable" />
</template> </template>
<template #isBatchCustomSQLTable>
<BasicTable @register="registerIsBatchCustomSQLTable" />
</template>
<template #notCustomSQLTable> <template #notCustomSQLTable>
<BasicTable @register="registerNotCustomSQLTable"> <BasicTable @register="registerNotCustomSQLTable">
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
...@@ -102,6 +120,7 @@ ...@@ -102,6 +120,7 @@
</BasicTable> </BasicTable>
</template> </template>
</BasicForm> </BasicForm>
</div>
</TabPane> </TabPane>
<TabPane key="2" tab="映射规则配置"> <TabPane key="2" tab="映射规则配置">
<!-- <BasicTable>--> <!-- <BasicTable>-->
...@@ -128,43 +147,316 @@ ...@@ -128,43 +147,316 @@
</PageWrapper> </PageWrapper>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Tabs, TabPane, Select, Alert, Modal, notification } from 'ant-design-vue'; import { Tabs, TabPane, Alert, Modal } from 'ant-design-vue';
import { h, ref, onMounted, reactive } from 'vue'; import { h, ref, onMounted } from 'vue';
import { BasicTree } from '@/components/Tree'; import { BasicTree } from '@/components/Tree';
import { BasicForm, useForm } from '@/components/Form'; import { BasicForm, FormSchema, useForm } from '@/components/Form';
import { import { isCustomSQLColumns, notCustomSQLColumns } from './offlineLoading.data';
sourceSideConfigurationFormSchema, import Icon from '@/components/Icon/Icon.vue';
LoadingStrategyFormSchema, import { useMessage } from '@/hooks/web/useMessage';
isCustomSQLColumns, import { PageWrapper } from '@/components/Page';
notCustomSQLColumns, import { useRoute } from 'vue-router';
} from './offlineLoading.data'; import {
import Icon from '@/components/Icon/Icon.vue'; isCustomSQLTableList,
import { useMessage } from '@/hooks/web/useMessage'; isBatchCustomSQLTableList,
import { PageWrapper } from '@/components/Page'; notCustomSQLTableList,
import { useRoute } from 'vue-router'; tableTreeData,
import { isCustomSQLTableList, notCustomSQLTableList, tableTreeData } from './mock'; } from './mock';
import { router } from '@/router'; import { router } from '@/router';
import { DeleteOutlined } from '@ant-design/icons-vue'; import { DeleteOutlined } from '@ant-design/icons-vue';
import { BasicTable, useTable, TableAction } from '@/components/Table'; import { BasicTable, useTable, TableAction } from '@/components/Table';
import { useModal } from '@/components/Modal'; import { useModal } from '@/components/Modal';
import GetMetadataModal from '@/views/dataIntegration/dataLoading/dataEntryLake/getMetadataModal.vue'; import GetMetadataModal from '@/views/dataIntegration/dataLoading/dataEntryLake/getMetadataModal.vue';
import DeplysModal from '@/views/dataIntegration/dataLoading/dataEntryLake/getMetadataModal.vue'; import DeplysModal from '@/views/dataIntegration/dataLoading/dataEntryLake/DeplysModal.vue';
import CodeEditor from '@/components/CodeEditor/src/CodeEditor.vue';
const route = useRoute(); const route = useRoute();
const emit = defineEmits(['success', 'register']); const emit = defineEmits(['success', 'register']);
const { createMessage, createConfirm } = useMessage(); const { createMessage, createConfirm } = useMessage();
const checkedKeys = ref<string[]>(); const myCheckedKeys = ref([]);
let isCustomSQLTable = ref(isCustomSQLTableList); let isCustomSQLTable = ref(isCustomSQLTableList);
let notCustomSQLTable = ref(notCustomSQLTableList); let isBatchCustomSQLTable = ref(isBatchCustomSQLTableList);
const selectKey = ref('0'); let notCustomSQLTable = ref(notCustomSQLTableList);
// let metadataAcquisitionMode = ref();
let sql = ref('SELECT * FROM user_info,customer_details,order_history,product_inventory');
let metadataAcquisitionModeFlag = ref();
let customSQLFlag = ref();
let isParsingSQL = ref(false);
let loadType = ref('全量数据加载');
const selectKey = ref('0');
const [registerGetMetadataModal, { openModal: openGetMetadataModal }] = useModal(); const sourceSideConfigurationFormSchema: FormSchema[] = [
const [registerDeplysModal, { openModal: openDeplysModal }] = useModal(); {
field: 'loadType',
label: '加载方式',
component: 'RadioGroup',
defaultValue: '全量数据加载',
componentProps: ({ formModel, formActionType }) => ({
onChange: () => {
loadType.value = formModel.loadType;
},
options: [
{ label: '全量数据加载', value: '全量数据加载' },
{ label: '增量数据加载', value: '增量数据加载' },
],
}),
},
{
field: 'metadataAcquisitionMode',
label: '元数据获取方式',
component: 'RadioGroup',
defaultValue: '从JDBC获取元数据',
componentProps: ({ formModel, formActionType }) => ({
onChange: () => {
isParsingSQL.value = false;
metadataAcquisitionModeFlag.value = formModel.metadataAcquisitionMode === '自定义SQL';
const flag = !metadataAcquisitionModeFlag.value;
updateSchema([{ field: 'filterCondition', ifShow: flag && customSQLFlag.value }]);
updateSchema([{ field: 'notCustomSQLTable', ifShow: flag && customSQLFlag.value }]);
updateSchema([{ field: 'customSQL', ifShow: flag }]);
updateSchema([{ field: 'querySQL', ifShow: flag && !customSQLFlag.value }]);
updateSchema([{ field: 'parsingSQL', ifShow: flag && !customSQLFlag.value }]);
updateSchema([{ field: 'isCustomSQLAlert', ifShow: flag && !customSQLFlag.value }]);
updateSchema([
{
field: 'isCustomSQLTable',
ifShow: flag && !customSQLFlag.value && isParsingSQL.value,
},
]);
updateSchema([{ field: 'sourceDataTableName', ifShow: !flag }]);
updateSchema([{ field: 'isBatchCustomSQLTable', ifShow: !flag && isParsingSQL.value }]);
formActionType.updateSchema([{ field: 'dataBase', ifShow: flag }]);
formActionType.updateSchema([{ field: 'metadataType', ifShow: flag }]);
formActionType.updateSchema([{ field: 'getMetadata', ifShow: flag }]);
},
options: [
{ label: '从JDBC获取元数据', value: '从JDBC获取元数据' },
{ label: '自定义SQL', value: '自定义SQL' },
{ label: '导入元数据文件', value: '导入元数据文件' },
],
}),
},
{
field: 'dataSource',
label: '数据源',
component: 'Select',
required: true,
defaultValue: 'KunOB数据源',
componentProps: {
placeholder: '请选择数据源',
options: [
{ label: 'KunOB数据源', value: 'KunOB数据源' },
{ label: 'MongoDB数据源', value: 'MongoDB数据源' },
{ label: 'AmazonS3', value: 'AmazonS3' },
],
},
},
{
field: 'dataBase',
label: '数据库',
component: 'Cascader',
required: true,
componentProps: {
placeholder: '请选择数据源',
displayRender: ({ labels }) => {
return labels[labels.length - 1];
},
options: [
{
value: '数据库对象资源',
label: '数据库对象资源',
children: [
{
value: '数据中台工作区01',
label: '数据中台工作区01',
children: [
{
value: 'ArgoDB_Dev01',
label: 'ArgoDB_Dev01',
},
{
value: 'ArgoDB_Dev02',
label: 'ArgoDB_Dev02',
},
{
value: 'GbaseDB_Dev01',
label: 'GbaseDB_Dev01',
},
],
},
],
},
],
},
},
{
field: 'metadataType',
label: '元数据类型',
component: 'Input',
required: true,
componentProps: {
placeholder: '以,分隔输入元数据类型',
},
},
{
field: 'getMetadata',
label: ' ',
component: 'Slot',
slot: 'getMetadata',
},
{
field: 'maximumNumberOfDatabaseConnections',
label: '源库最大连接数',
component: 'Input',
componentProps: {
placeholder: '请输入源库最大连接数',
},
},
];
const [ const LoadingStrategyFormSchema: FormSchema[] = [
{
field: 'loadingStrategy',
label: '加载策略',
component: 'RadioGroup',
defaultValue: '基于数量',
componentProps: ({ formModel, formActionType }) => ({
onChange: () => {
const flag = formModel.loadingStrategy === '基于数量';
formActionType.updateSchema([{ field: 'quantityBasedAlert', ifShow: flag }]);
formActionType.updateSchema([{ field: 'conditionBasedAlert', ifShow: !flag }]);
formActionType.updateSchema([{ field: 'cutDivision', ifShow: !flag }]);
},
options: [
{ label: '基于数量', value: '基于数量' },
{ label: '基于条件', value: '基于条件' },
],
}),
},
{
field: 'quantityBasedAlert',
component: 'Slot',
slot: 'quantityBasedAlert',
},
{
field: 'conditionBasedAlert',
component: 'Slot',
slot: 'conditionBasedAlert',
ifShow: false,
},
{
field: 'cutDivision',
label: '切分列',
component: 'Input',
colProps: { lg: 11, md: 11 },
componentProps: {
placeholder: '',
},
ifShow: false,
required: true,
},
{
component: 'Divider',
},
{
field: 'customSQL',
label: '自定义SQL',
component: 'RadioGroup',
defaultValue: '否',
required: true,
componentProps: ({ formModel, formActionType }) => ({
onChange: () => {
isParsingSQL.value = false;
customSQLFlag.value = formModel.customSQL === '否';
formActionType.updateSchema([{ field: 'filterCondition', ifShow: customSQLFlag.value }]);
formActionType.updateSchema([
{ field: 'notCustomSQLTable', ifShow: customSQLFlag.value },
]);
formActionType.updateSchema([{ field: 'querySQL', ifShow: !customSQLFlag.value }]);
formActionType.updateSchema([{ field: 'parsingSQL', ifShow: !customSQLFlag.value }]);
formActionType.updateSchema([
{ field: 'isCustomSQLAlert', ifShow: !customSQLFlag.value },
]);
formActionType.updateSchema([
{ field: 'isCustomSQLTable', ifShow: !customSQLFlag.value && isParsingSQL.value },
]);
},
options: [
{ label: '是', value: '是' },
{ label: '否', value: '否' },
],
}),
},
{
field: 'filterCondition',
label: '过滤条件',
component: 'InputTextArea',
componentProps: {
placeholder: '请输入',
},
},
{
field: 'notCustomSQLTable',
component: 'Slot',
slot: 'notCustomSQLTable',
},
{
field: 'querySQL',
label: '查询SQL',
component: 'InputTextArea',
componentProps: {
placeholder: '请输入',
},
ifShow: false,
},
{
field: 'parsingSQL',
label: ' ',
component: 'Slot',
slot: 'parsingSQL',
ifShow: false,
},
{
field: 'isCustomSQLAlert',
component: 'Slot',
slot: 'isCustomSQLAlert',
ifShow: false,
},
{
field: 'isCustomSQLTable',
component: 'Slot',
slot: 'isCustomSQLTable',
ifShow: isParsingSQL.value,
},
{
field: 'sourceDataTableName',
label: '源端数据表名',
component: 'Input',
colProps: { lg: 11, md: 11 },
componentProps: {
placeholder: '',
},
ifShow: false,
},
{
field: 'isBatchCustomSQLTable',
component: 'Slot',
slot: 'isBatchCustomSQLTable',
ifShow: isParsingSQL.value,
},
];
const [registerGetMetadataModal, { openModal: openGetMetadataModal }] = useModal();
const [registerDeplysModal, { openModal: openDeplysModal }] = useModal();
const [
registerSourceSideConfigurationForm, registerSourceSideConfigurationForm,
{ validate: validateSourceSideConfigurationForm, submit: submitSourceSideConfiguration }, {
] = useForm({ getFieldsValue,
validate: validateSourceSideConfigurationForm,
submit: submitSourceSideConfiguration,
},
] = useForm({
labelWidth: 180, labelWidth: 180,
labelAlign: 'left', labelAlign: 'left',
baseColProps: { lg: 24, md: 24 }, baseColProps: { lg: 24, md: 24 },
...@@ -173,9 +465,9 @@ const [ ...@@ -173,9 +465,9 @@ const [
actionColOptions: { actionColOptions: {
span: 23, span: 23,
}, },
}); });
const [registerLoadingStrategyForm, { setFieldsValue }] = useForm({ const [registerLoadingStrategyForm, { updateSchema, setFieldsValue }] = useForm({
labelWidth: 180, labelWidth: 180,
labelAlign: 'left', labelAlign: 'left',
baseColProps: { lg: 24, md: 24 }, baseColProps: { lg: 24, md: 24 },
...@@ -184,9 +476,9 @@ const [registerLoadingStrategyForm, { setFieldsValue }] = useForm({ ...@@ -184,9 +476,9 @@ const [registerLoadingStrategyForm, { setFieldsValue }] = useForm({
actionColOptions: { actionColOptions: {
span: 23, span: 23,
}, },
}); });
const [registerIsCustomSQLTable, { reload: isCustomSQLTableReload }] = useTable({ const [registerIsCustomSQLTable, { reload: isCustomSQLTableReload }] = useTable({
api: async () => { api: async () => {
isCustomSQLTable.value = isCustomSQLTableList.filter((item) => { isCustomSQLTable.value = isCustomSQLTableList.filter((item) => {
return item.ownershipTableId[0] === selectKey.value; return item.ownershipTableId[0] === selectKey.value;
...@@ -208,9 +500,30 @@ const [registerIsCustomSQLTable, { reload: isCustomSQLTableReload }] = useTable( ...@@ -208,9 +500,30 @@ const [registerIsCustomSQLTable, { reload: isCustomSQLTableReload }] = useTable(
showTableSetting: false, showTableSetting: false,
showIndexColumn: false, showIndexColumn: false,
bordered: false, bordered: false,
}); });
const [registerIsBatchCustomSQLTable] = useTable({
api: async () => {
const response = {
pageNu: '1',
pageSize: '5',
pages: '1',
total: isBatchCustomSQLTable.value.length,
code: '',
message: '',
data: isBatchCustomSQLTable.value,
};
return { ...response };
},
scroll: { y: 300 },
rowKey: 'businessId',
columns: isCustomSQLColumns,
showTableSetting: false,
showIndexColumn: false,
bordered: false,
});
const [registerNotCustomSQLTable, { reload: notCustomSQLTableReload }] = useTable({ const [registerNotCustomSQLTable, { reload: notCustomSQLTableReload }] = useTable({
api: async () => { api: async () => {
notCustomSQLTable.value = notCustomSQLTableList.filter( notCustomSQLTable.value = notCustomSQLTableList.filter(
(item) => item.ownershipTableId[0] === selectKey.value, (item) => item.ownershipTableId[0] === selectKey.value,
...@@ -242,9 +555,9 @@ const [registerNotCustomSQLTable, { reload: notCustomSQLTableReload }] = useTabl ...@@ -242,9 +555,9 @@ const [registerNotCustomSQLTable, { reload: notCustomSQLTableReload }] = useTabl
dataIndex: 'action', dataIndex: 'action',
// slots: { customRender: 'action' }, // slots: { customRender: 'action' },
}, },
}); });
const actionList = [ const actionList = [
{ {
//删除 //删除
render: (node) => { render: (node) => {
...@@ -256,12 +569,16 @@ const actionList = [ ...@@ -256,12 +569,16 @@ const actionList = [
}); });
}, },
}, },
]; ];
onMounted(() => {}); onMounted(() => {
setFieldsValue({
sourceDataTableName: 'user_info,customer_details,order_history,product_inventory',
});
});
// 删除节点 // 删除节点
const handleDeleteTable = (node) => { const handleDeleteTable = (node) => {
Modal.confirm({ Modal.confirm({
title: '确认删除', title: '确认删除',
content: '确定要删除此表吗?', content: '确定要删除此表吗?',
...@@ -275,34 +592,48 @@ const handleDeleteTable = (node) => { ...@@ -275,34 +592,48 @@ const handleDeleteTable = (node) => {
createMessage.info('取消删除'); createMessage.info('取消删除');
}, },
}); });
}; };
function handleDelete() { function handleDelete() {
createConfirm({ Modal.confirm({
iconType: 'warning',
title: '确认删除', title: '确认删除',
content: '确认删除选中数据吗?', content: '确认删除选中字段吗?',
okText: '确认',
cancelText: '取消',
onOk() { onOk() {
createMessage.success('删除成功!'); createMessage.success('删除成功!');
}, },
onCancel() {
console.log('取消删除');
createMessage.info('取消删除');
},
}); });
} // createConfirm({
// iconType: 'warning',
// title: '确认删除',
// content: '确认删除选中数据吗?',
// onOk() {
// createMessage.success('删除成功!');
// },
// });
}
function handleSelect(keys) { function handleSelect(keys) {
// console.log('keys', keys); isParsingSQL.value = false;
console.log('keys', getFieldsValue());
selectKey.value = keys.toString(); selectKey.value = keys.toString();
const sql = tableTreeData.filter((item) => item.key === keys.toString())[0].sql; const querySQL = tableTreeData.filter((item) => item.key === keys.toString())[0].sql;
setFieldsValue({ querySQL: sql }); setFieldsValue({ querySQL: querySQL });
isCustomSQLTableReload(); isCustomSQLTableReload();
notCustomSQLTableReload(); notCustomSQLTableReload();
// emit('select', keys[0]); // emit('select', keys[0]);
} }
function goBack() { function goBack() {
router.back(); router.back();
} }
async function handleSave() { async function handleSave() {
try { try {
const isValid = await validateSourceSideConfigurationForm(); const isValid = await validateSourceSideConfigurationForm();
if (!isValid) { if (!isValid) {
...@@ -316,25 +647,44 @@ async function handleSave() { ...@@ -316,25 +647,44 @@ async function handleSave() {
console.error('保存失败:', error); console.error('保存失败:', error);
createMessage.error('表单校验未通过,请检查输入'); createMessage.error('表单校验未通过,请检查输入');
} }
} }
function handleDeplys() { function handleDeplys() {
console.log('checkedKeys', checkedKeys.value); console.log('myCheckedKeys', myCheckedKeys.value);
openDeplysModal(true) openDeplysModal(true, {
} loadType,
function handleGetMetadata() { myCheckedKeys,
});
}
function handleGetMetadata() {
openGetMetadataModal(true); openGetMetadataModal(true);
} }
function handleConversion(record) { function handleConversion(record) {
createMessage.success('数据转换成功' + record.fieldType); createMessage.success('数据转换成功' + record.fieldType);
} }
function handleParsingSQL() {
isParsingSQL.value = true;
updateSchema([
{
field: 'isCustomSQLTable',
ifShow: !metadataAcquisitionModeFlag.value && !customSQLFlag.value && isParsingSQL.value,
},
]);
updateSchema([
{
field: 'isBatchCustomSQLTable',
ifShow: metadataAcquisitionModeFlag.value && isParsingSQL.value,
},
]);
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.content-padding { .content-padding {
background-color: white; background-color: white;
} }
.modal_top { .modal_top {
padding: 0 0 20px 0; padding: 0 0 20px 0;
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -352,5 +702,5 @@ function handleConversion(record) { ...@@ -352,5 +702,5 @@ function handleConversion(record) {
gap: 5px; gap: 5px;
align-items: center; align-items: center;
} }
} }
</style> </style>
...@@ -7,20 +7,26 @@ ...@@ -7,20 +7,26 @@
minHeight="50" minHeight="50"
> >
<div style="display: flex; justify-content: space-between"> <div style="display: flex; justify-content: space-between">
<a-input-search style="width: 220px" /> <a-input-search style="width: 220px" @search="onSearch" />
<a-button @click="handleClick"> <a-button @click="handleClick">
通过序号批量选择 通过序号批量选择
<Icon v-if="unfold" icon="fe:arrow-up" /> <Icon v-if="unfold" icon="fe:arrow-up" />
<Icon v-else icon="fe:arrow-down" /> <Icon v-else icon="fe:arrow-down" />
</a-button> </a-button>
</div> </div>
<div v-if="unfold"> <div v-if="unfold" style="margin-top: 5px">
<a-input class="getMetadataInput" style="margin-right: 5px" /><a-input <a-input
v-model:value="startId"
class="getMetadataInput" class="getMetadataInput"
style="margin-right: 5px; margin-left: 5px" style="margin-right: 10px; margin-left: 10px"
/> />
<a-button style="margin-right: 5px">选择</a-button> <a-input
<a-button style="margin-right: 5px">清空</a-button> v-model:value="endId"
class="getMetadataInput"
style="margin-right: 10px; margin-left: 10px"
/>
<a-button @click="handleSelect" style="margin-right: 10px">选择</a-button>
<a-button @click="handleResetInputs" style="margin-right: 10px">清空</a-button>
</div> </div>
<BasicTable @register="registerTable" /> <BasicTable @register="registerTable" />
</BasicModal> </BasicModal>
...@@ -37,9 +43,11 @@ ...@@ -37,9 +43,11 @@
const emit = defineEmits(['success', 'register']); const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const unfold = ref(false); const unfold = ref(false);
let startId = ref();
let endId = ref();
let getMetadataTable = ref(getMetadataTableList); let getMetadataTable = ref(getMetadataTableList);
const [registerTable] = useTable({ const [registerTable, { reload, getDataSource, getRowSelection, setSelectedRowKeys }] = useTable({
api: async () => { api: async () => {
const response = { const response = {
pageNu: '1', pageNu: '1',
...@@ -72,6 +80,57 @@ ...@@ -72,6 +80,57 @@
async function handleSubmit() { async function handleSubmit() {
closeModal(); closeModal();
} }
function handleSelect() {
const selectedRowKeys = getRowSelection().selectedRowKeys;
const ids = ref([...selectedRowKeys]);
const dataIds = ref(getDataSource());
if (startId.value && endId.value) {
for (let i = startId.value - 1; i <= endId.value - 1 && i < getDataSource().length; i++) {
const businessId = dataIds.value[i].businessId;
if (!ids.value.includes(businessId)) {
ids.value.push(businessId);
}
}
}
setSelectedRowKeys(ids.value);
}
function handleResetInputs() {
const selectedRowKeys = getRowSelection().selectedRowKeys;
const ids = ref([...selectedRowKeys]);
const dataIds = ref(getDataSource());
if (startId.value && endId.value) {
const startIndex = startId.value - 1;
const endIndex = endId.value - 1;
// 过滤掉与 i 相等的值
const filteredIds = ids.value.filter((id) => {
for (let i = startIndex; i <= endIndex && i < getDataSource().length; i++) {
if (dataIds.value[i].businessId === id) {
return false;
}
}
return true;
});
// // 清空 startId 和 endId
// startId.value = null;
// endId.value = null;
setSelectedRowKeys(filteredIds);
}
}
function onSearch(searchValue) {
getMetadataTable.value = getMetadataTableList.filter((item) =>
item.tableName.includes(searchValue),
);
reload();
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.getMetadataInput { .getMetadataInput {
......
...@@ -206,61 +206,73 @@ export const tableTreeData = [ ...@@ -206,61 +206,73 @@ export const tableTreeData = [
{ {
title: 'bm_datasource', title: 'bm_datasource',
key: '0', key: '0',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, catalog_id FROM bm_datasource', sql: 'SELECT uuid, catalog_id FROM bm_datasource',
}, },
{ {
title: 'user_info', title: 'user_info',
key: '1', key: '1',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, catalog_id, name, description FROM user_info', sql: 'SELECT uuid, catalog_id, name, description FROM user_info',
}, },
{ {
title: 'customer_details', title: 'customer_details',
key: '2', key: '2',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, user_id, username, email FROM customer_details', sql: 'SELECT uuid, user_id, username, email FROM customer_details',
}, },
{ {
title: 'order_history', title: 'order_history',
key: '3', key: '3',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, order_id, total_amount FROM order_history', sql: 'SELECT uuid, order_id, total_amount FROM order_history',
}, },
{ {
title: 'product_inventory', title: 'product_inventory',
key: '4', key: '4',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, product_id, product_name, price FROM product_inventory', sql: 'SELECT uuid, product_id, product_name, price FROM product_inventory',
}, },
{ {
title: 'transaction_logs', title: 'transaction_logs',
key: '5', key: '5',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, category_id, category_name FROM transaction_logs', sql: 'SELECT uuid, category_id, category_name FROM transaction_logs',
}, },
{ {
title: 'employee_records', title: 'employee_records',
key: '6', key: '6',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, customer_id, customer_name FROM employee_records', sql: 'SELECT uuid, customer_id, customer_name FROM employee_records',
}, },
{ {
title: 'payment_details', title: 'payment_details',
key: '7', key: '7',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, customer_id, order_date FROM payment_details', sql: 'SELECT uuid, customer_id, order_date FROM payment_details',
}, },
{ {
title: 'shipping_addresses', title: 'shipping_addresses',
key: '8', key: '8',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, product_id, stock_quantity, last_updated FROM shipping_addresses', sql: 'SELECT uuid, product_id, stock_quantity, last_updated FROM shipping_addresses',
}, },
{ {
title: 'invoice_data', title: 'invoice_data',
key: '9', key: '9',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, user_id, address, phone_number FROM invoice_data', sql: 'SELECT uuid, user_id, address, phone_number FROM invoice_data',
}, },
{ {
title: 'customer_feedback', title: 'customer_feedback',
key: '10', key: '10',
icon: 'majesticons:table-line',
sql: 'SELECT uuid, category_id, category_description, parent_category_id FROM customer_feedback', sql: 'SELECT uuid, category_id, category_description, parent_category_id FROM customer_feedback',
}, },
{ {
title: 'supplier_info', title: 'supplier_info',
key: '11', key: '11',
icon: 'majesticons:table-line',
sql: 'SELECT * FROM supplier_info', // 假设 supplier_info 表没有在 isCustomSQLTableList 中定义字段 sql: 'SELECT * FROM supplier_info', // 假设 supplier_info 表没有在 isCustomSQLTableList 中定义字段
}, },
]; ];
...@@ -496,6 +508,99 @@ export const isCustomSQLTableList = [ ...@@ -496,6 +508,99 @@ export const isCustomSQLTableList = [
}, },
]; ];
export const isBatchCustomSQLTableList = [
{
businessId: '1',
ownershipTableId: '1',
fieldName: 'uuid',
fieldType: 'VARCHAR(50,0)',
},
{
businessId: '2',
ownershipTableId: '1',
fieldName: 'catalog_id',
fieldType: 'BIGINT(19,0)',
},
{
businessId: '3',
ownershipTableId: '1',
fieldName: 'name',
fieldType: 'VARCHAR(255,0)',
},
{
businessId: '4',
ownershipTableId: '1',
fieldName: 'description',
fieldType: 'TEXT',
},
{
businessId: '5',
ownershipTableId: '2',
fieldName: 'uuid',
fieldType: 'VARCHAR(50,0)',
},
{
businessId: '6',
ownershipTableId: '2',
fieldName: 'user_id',
fieldType: 'BIGINT(19,0)',
},
{
businessId: '7',
ownershipTableId: '2',
fieldName: 'username',
fieldType: 'VARCHAR(255,0)',
},
{
businessId: '8',
ownershipTableId: '2',
fieldName: 'email',
fieldType: 'VARCHAR(255,0)',
},
{
businessId: '9',
ownershipTableId: '3',
fieldName: 'uuid',
fieldType: 'VARCHAR(50,0)',
},
{
businessId: '10',
ownershipTableId: '3',
fieldName: 'order_id',
fieldType: 'BIGINT(19,0)',
},
{
businessId: '11',
ownershipTableId: '3',
fieldName: 'total_amount',
fieldType: 'DECIMAL(10,2)',
},
{
businessId: '12',
ownershipTableId: '4',
fieldName: 'uuid',
fieldType: 'VARCHAR(50,0)',
},
{
businessId: '13',
ownershipTableId: '4',
fieldName: 'product_id',
fieldType: 'BIGINT(19,0)',
},
{
businessId: '14',
ownershipTableId: '4',
fieldName: 'product_name',
fieldType: 'VARCHAR(255,0)',
},
{
businessId: '15',
ownershipTableId: '4',
fieldName: 'price',
fieldType: 'DECIMAL(10,2)',
},
];
export const notCustomSQLTableList = [ export const notCustomSQLTableList = [
// bm_datasource // bm_datasource
{ {
......
import { FormSchema } from '@/components/Form'; import { FormSchema } from '@/components/Form';
import { BasicColumn } from '@/components/Table'; import { BasicColumn } from '@/components/Table';
export const sourceSideConfigurationFormSchema: FormSchema[] = [
{
field: 'loadType',
label: '加载方式',
component: 'RadioGroup',
defaultValue: '全量数据加载',
componentProps: {
options: [
{ label: '全量数据加载', value: '全量数据加载' },
{ label: '增量数据加载', value: '增量数据加载' },
],
},
},
{
field: 'metadataAcquisitionMode',
label: '元数据获取方式',
component: 'RadioGroup',
defaultValue: '从JDBC获取元数据',
componentProps: ({ formModel, formActionType }) => ({
onChange: () => {
const flag = formModel.metadataAcquisitionMode === '从JDBC获取元数据';
formActionType.updateSchema([{ field: 'dataBase', ifShow: flag, required: flag }]);
formActionType.updateSchema([{ field: 'metadataType', ifShow: flag, required: flag }]);
formActionType.updateSchema([{ field: 'getMetadata', ifShow: flag }]);
},
options: [
{ label: '从JDBC获取元数据', value: '从JDBC获取元数据' },
{ label: '自定义SQL', value: '自定义SQL' },
{ label: '导入元数据文件', value: '导入元数据文件' },
],
}),
},
{
field: 'dataSource',
label: '数据源',
component: 'Select',
required: true,
defaultValue: 'KunOB数据源',
componentProps: {
placeholder: '请选择数据源',
options: [
{ label: 'KunOB数据源', value: 'KunOB数据源' },
{ label: 'MongoDB数据源', value: 'MongoDB数据源' },
{ label: 'AmazonS3', value: 'AmazonS3' },
],
},
},
{
field: 'dataBase',
label: '数据库',
component: 'Cascader',
required: true,
componentProps: {
placeholder: '请选择数据源',
displayRender: ({ labels }) => {
return labels[labels.length - 1];
},
options: [
{
value: '数据库对象资源',
label: '数据库对象资源',
children: [
{
value: '数据中台工作区01',
label: '数据中台工作区01',
children: [
{
value: 'ArgoDB_Dev01',
label: 'ArgoDB_Dev01',
},
{
value: 'ArgoDB_Dev02',
label: 'ArgoDB_Dev02',
},
{
value: 'GbaseDB_Dev01',
label: 'GbaseDB_Dev01',
},
],
},
],
},
],
},
},
{
field: 'metadataType',
label: '元数据类型',
component: 'Input',
required: true,
componentProps: {
placeholder: '以,分隔输入元数据类型',
},
},
{
field: 'getMetadata',
label: ' ',
component: 'Slot',
slot: 'getMetadata',
},
{
field: 'maximumNumberOfDatabaseConnections',
label: '源库最大连接数',
component: 'Input',
componentProps: {
placeholder: '请输入源库最大连接数',
},
},
];
export const LoadingStrategyFormSchema: FormSchema[] = [
{
field: 'loadingStrategy',
label: '加载策略',
component: 'RadioGroup',
defaultValue: '基于数量',
componentProps: ({ formModel, formActionType }) => ({
onChange: () => {
const flag = formModel.loadingStrategy === '基于数量';
formActionType.updateSchema([{ field: 'quantityBasedAlert', ifShow: flag }]);
formActionType.updateSchema([{ field: 'conditionBasedAlert', ifShow: !flag }]);
},
options: [
{ label: '基于数量', value: '基于数量' },
{ label: '基于条件', value: '基于条件' },
],
}),
},
{
field: 'quantityBasedAlert',
component: 'Slot',
slot: 'quantityBasedAlert',
},
{
field: 'conditionBasedAlert',
component: 'Slot',
slot: 'conditionBasedAlert',
ifShow: false,
},
{
component: 'Divider',
},
{
field: 'customSQL',
label: '自定义SQL',
component: 'RadioGroup',
defaultValue: '否',
required: true,
componentProps: ({ formModel, formActionType }) => ({
onChange: () => {
const flag = formModel.customSQL === '否';
formActionType.updateSchema([{ field: 'filterCondition', ifShow: flag }]);
formActionType.updateSchema([{ field: 'notCustomSQLTable', ifShow: flag }]);
formActionType.updateSchema([{ field: 'querySQL', ifShow: !flag }]);
formActionType.updateSchema([{ field: 'parsingSQL', ifShow: !flag }]);
formActionType.updateSchema([{ field: 'isCustomSQLAlert', ifShow: !flag }]);
formActionType.updateSchema([{ field: 'isCustomSQLTable', ifShow: !flag }]);
},
options: [
{ label: '是', value: '是' },
{ label: '否', value: '否' },
],
}),
},
{
field: 'filterCondition',
label: '过滤条件',
component: 'InputTextArea',
componentProps: {
placeholder: '请输入',
},
},
{
field: 'notCustomSQLTable',
component: 'Slot',
slot: 'notCustomSQLTable',
},
{
field: 'querySQL',
label: '查询SQL',
component: 'InputTextArea',
componentProps: {
placeholder: '请输入',
},
ifShow: false,
},
{
field: 'parsingSQL',
label: ' ',
component: 'Slot',
slot: 'parsingSQL',
ifShow: false,
},
{
field: 'isCustomSQLAlert',
component: 'Slot',
slot: 'isCustomSQLAlert',
ifShow: false,
},
{
field: 'isCustomSQLTable',
component: 'Slot',
slot: 'isCustomSQLTable',
ifShow: false,
},
];
export const isCustomSQLColumns: BasicColumn[] = [ export const isCustomSQLColumns: BasicColumn[] = [
{ {
title: '列名', title: '列名',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment