Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
bigDataSystem
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张伯涛
bigDataSystem
Commits
106d7371
Commit
106d7371
authored
Dec 04, 2024
by
LiXuyang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
文件加载-映射规则配置改
parent
1da26f8b
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
284 additions
and
72 deletions
+284
-72
addDataConversionRuleModal.vue
...on/dataLoading/fileLoading/addDataConversionRuleModal.vue
+102
-0
dataFilterRuleModal.vue
...tegration/dataLoading/fileLoading/dataFilterRuleModal.vue
+59
-0
file.data.ts
...iews/dataIntegration/dataLoading/fileLoading/file.data.ts
+19
-13
fileData.ts
...views/dataIntegration/dataLoading/fileLoading/fileData.ts
+69
-50
index.vue
src/views/dataIntegration/dataLoading/fileLoading/index.vue
+35
-9
No files found.
src/views/dataIntegration/dataLoading/fileLoading/addDataConversionRuleModal.vue
0 → 100644
View file @
106d7371
<
template
>
<BasicModal
width=
"40%"
v-bind=
"$attrs"
@
register=
"registerModal"
@
ok=
"handleSubmit"
>
<template
#
title
>
<span
style=
"font-size: 23px; font-weight: lighter"
>
新建规则
</span>
</
template
>
<Span
style=
"font-size: 18px"
>
<Icon
style=
"margin-right: 5px; font-size: 18px"
:color=
"'#5cb3ff'"
icon=
"material-symbols:table-convert-outline"
/>
数据转换规则
</Span>
<List>
<Row
:gutter=
"16"
>
<
template
v-for=
"item in cardRuleList"
:key=
"item.title"
>
<Col
:span=
"12"
>
<ListItem>
<Card
:hoverable=
"true"
class=
"sceneSelectionCard"
@
click=
"handleNewModal(item.type)"
>
<div
class=
"sceneSelectionTitle"
>
{{
item
.
title
}}
</div>
<div
class=
"sceneSelectionDescription"
>
{{
item
.
description
}}
</div>
</Card>
</ListItem>
</Col>
</
template
>
</Row>
</List>
</BasicModal>
<NewFieldRuleModal
@
register=
"registerNewFieldRuleModal"
/>
<DataTransformationRuleModal
@
register=
"registerDataTransformationRuleModal"
/>
<DataFilterRuleModal
@
register=
"dataFilterRuleModal"
/>
</template>
<
script
lang=
"ts"
setup
>
import
{
onMounted
}
from
'vue'
;
import
Icon
from
'@/components/Icon/Icon.vue'
;
import
{
BasicModal
,
useModal
,
useModalInner
}
from
'@/components/Modal'
;
import
{
Card
,
Row
,
Col
,
List
,
ListItem
}
from
'ant-design-vue'
;
import
{
cardRuleList
}
from
'./fileData'
;
import
NewFieldRuleModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/newFieldRuleModal.vue'
;
import
DataTransformationRuleModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/dataTransformationRuleModal.vue'
;
import
SingleTableFieldMappingRuleModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/singleTableFieldMappingRuleModal.vue'
;
import
DataFilterRuleModal
from
'./dataFilterRuleModal.vue'
;
const
[
registerModal
,
{
setModalProps
,
closeModal
}]
=
useModalInner
(
async
()
=>
{});
const
[
registerNewFieldRuleModal
,
{
openModal
:
openNewFieldRuleModal
}]
=
useModal
();
const
[
registerDataTransformationRuleModal
,
{
openModal
:
openDataTransformationRuleModal
}]
=
useModal
();
const
[
dataFilterRuleModal
,
{
openModal
:
openDataFilterRuleModal
}]
=
useModal
();
function
handleNewModal
(
type
)
{
console
.
log
(
type
);
switch
(
type
)
{
case
'newFieldRule'
:
openNewFieldRuleModal
(
true
);
break
;
case
'dataTransformationRule'
:
openDataTransformationRuleModal
(
true
);
break
;
case
'dataFilterRule'
:
openDataFilterRuleModal
(
true
);
break
;
default
:
console
.
log
(
'Unknown rule type'
);
}
}
function
handleSubmit
()
{
closeModal
();
}
onMounted
(()
=>
{
setModalProps
({
canFullscreen
:
false
,
okText
:
'下一步'
});
});
</
script
>
<
style
lang=
"scss"
scoped
>
.sceneSelectionCard
{
height
:
120px
;
flex-direction
:
column
;
}
.sceneSelectionIcon
{
font-size
:
40px
!
important
;
margin-bottom
:
16px
;
}
.sceneSelectionTitle
{
font-size
:
18px
;
font-weight
:
bold
;
margin-bottom
:
8px
;
}
.sceneSelectionDescription
{
font-size
:
14px
;
color
:
#78787c
;
text-align
:
left
;
line-height
:
1
.2
;
}
</
style
>
src/views/dataIntegration/dataLoading/fileLoading/dataFilterRuleModal.vue
0 → 100644
View file @
106d7371
<
template
>
<BasicModal
width=
"40%"
v-bind=
"$attrs"
@
register=
"registerModal"
:title=
"getTitle"
@
ok=
"handleSubmit"
@
cancel=
"handleCancel"
>
<BasicForm
@
register=
"registerForm"
/>
</BasicModal>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
ref
,
unref
}
from
'vue'
;
import
{
BasicModal
,
useModalInner
}
from
'@/components/Modal'
;
import
{
BasicForm
,
useForm
}
from
'@/components/Form'
;
import
{
dataFilterRuleModalFormSchema
}
from
'@/views/dataIntegration/dataLoading/fileLoading/file.data'
;
const
isUpdate
=
ref
(
false
);
const
isMove
=
ref
(
false
);
const
rowId
=
ref
(
''
);
const
getTitle
=
'数据过滤规则'
;
//获取接口数据并放在下拉框里(这里是打开了一个弹框)
//初始化表单
const
[
registerForm
,
{
getFieldsValue
,
setFieldsValue
,
updateSchema
,
resetFields
,
validate
,
clearValidate
}]
=
useForm
({
labelWidth
:
100
,
baseColProps
:
{
span
:
24
},
schemas
:
dataFilterRuleModalFormSchema
,
showActionButtonGroup
:
false
,
actionColOptions
:
{
span
:
23
,
},
});
//初始化弹框
const
[
registerModal
,
{
setModalProps
,
closeModal
}]
=
useModalInner
(
async
(
data
)
=>
{
await
resetFields
();
setModalProps
({
confirmLoading
:
false
});
isUpdate
.
value
=
!!
data
?.
isUpdate
;
isMove
.
value
=
!!
data
?.
isMove
;
if
(
unref
(
isUpdate
))
{
// 获取行数据的id
rowId
.
value
=
data
.
record
.
businessId
;
// 塞值
await
setFieldsValue
({
...
data
.
record
,
});
}
});
/**确定按钮*/
async
function
handleSubmit
()
{
await
validate
();
closeModal
();
}
function
handleCancel
()
{
clearValidate
();
}
</
script
>
src/views/dataIntegration/dataLoading/fileLoading/file.data.ts
View file @
106d7371
import
{
FormSchema
}
from
"@/components/Form"
;
import
{
FormSchema
}
from
"@/components/Form"
;
import
{
BasicColumn
}
from
"@/components/Table"
;
import
{
BasicColumn
}
from
"@/components/Table"
;
import
{
InputProps
}
from
"ant-design-vue"
;
export
const
fileUploadSchema
:
FormSchema
[]
=
[
export
const
fileUploadSchema
:
FormSchema
[]
=
[
{
{
...
@@ -51,19 +52,7 @@ export const fileUploadSchema: FormSchema[] = [
...
@@ -51,19 +52,7 @@ export const fileUploadSchema: FormSchema[] = [
return
model
.
type
===
'文件系统'
;
return
model
.
type
===
'文件系统'
;
},
},
defaultValue
:
'全量文件加载'
,
defaultValue
:
'全量文件加载'
,
component
:
'RadioGroup'
,
slot
:
'loadingType'
,
componentProps
:
{
options
:
[
{
label
:
'全量文件加载'
,
value
:
'全量文件加载'
,
},
{
label
:
'增量文件加载'
,
value
:
'增量文件加载'
,
},
],
},
},
},
{
{
label
:
'数据源'
,
label
:
'数据源'
,
...
@@ -475,3 +464,20 @@ export const showTableColumn: BasicColumn[] = [
...
@@ -475,3 +464,20 @@ export const showTableColumn: BasicColumn[] = [
slots
:
{
customRender
:
'targetColumnName'
},
slots
:
{
customRender
:
'targetColumnName'
},
},
},
];
];
export
const
dataFilterRuleModalFormSchema
:
FormSchema
[]
=
[
{
label
:
'规则名称'
,
field
:
'name'
,
required
:
true
,
component
:
'Input'
,
},
{
label
:
'自定义规则'
,
field
:
'rule'
,
component
:
'InputTextArea'
,
componentProps
:
{
placeholder
:
'请输入自定义过滤规则'
,
rows
:
4
,
}
as
InputProps
,
},
];
src/views/dataIntegration/dataLoading/fileLoading/fileData.ts
View file @
106d7371
export
const
fileData
=
[
import
Mock
,
{
Random
}
from
'mockjs'
;
{
c1
:
'100'
,
// 自定义函数:生成在指定日期范围内的随机日期
c2
:
'1132'
,
function
getRandomDate
(
start
,
end
)
{
c3
:
''
,
const
startTime
=
new
Date
(
start
).
getTime
();
c4
:
''
,
const
endTime
=
new
Date
(
end
).
getTime
();
c5
:
'1.1'
,
const
randomTime
=
new
Date
(
startTime
+
Math
.
random
()
*
(
endTime
-
startTime
));
c6
:
''
,
return
randomTime
.
toISOString
().
slice
(
0
,
19
).
replace
(
'T'
,
' '
);
// 格式化为 "yyyy-MM-dd HH:mm:ss"
c7
:
''
,
}
c8
:
''
,
const
startDate
=
'2023-01-01 00:00:00'
;
// 起始日期
c9
:
''
,
const
endDate
=
'2024-12-31 23:59:59'
;
// 结束日期
c10
:
''
,
},
export
const
fileData
=
(
num
)
=>
{
{
return
Mock
.
mock
({
c1
:
'101'
,
[
`list|
${
num
}
`
]:
[
c2
:
'1200'
,
// 根据 num 动态生成用户数量
c3
:
''
,
{
c4
:
''
,
'c1|+1'
:
1
,
c5
:
'1.1'
,
'c2|18-60'
:
1
,
c6
:
''
,
c3
:
'@cname'
,
c7
:
''
,
c4
:
'@pick(["男", "女"])'
,
c8
:
''
,
'c5|170-190'
:
1
,
c9
:
''
,
c6
:
function
()
{
c10
:
''
,
return
getRandomDate
(
startDate
,
endDate
);
},
},
{
c7
:
function
()
{
c1
:
'102'
,
return
getRandomDate
(
startDate
,
endDate
);
c2
:
'1200'
,
},
c3
:
''
,
c8
:
'@cname'
,
c4
:
''
,
c9
:
'@cname'
,
c5
:
'1.1'
,
c10
:
'@sentence(5, 10)'
,
c6
:
''
,
},
c7
:
''
,
],
c8
:
''
,
}).
list
;
c9
:
''
,
};
c10
:
''
,
},
{
c1
:
'103'
,
c2
:
'1200'
,
c3
:
''
,
c4
:
''
,
c5
:
'1.1'
,
c6
:
''
,
c7
:
''
,
c8
:
''
,
c9
:
''
,
c10
:
''
,
},
];
export
const
dataSourceData
=
[
export
const
dataSourceData
=
[
{
{
businessId
:
1
,
businessId
:
1
,
...
@@ -77,3 +62,37 @@ export const dataSourceFieldData = [
...
@@ -77,3 +62,37 @@ export const dataSourceFieldData = [
fieldRemark
:
null
,
fieldRemark
:
null
,
},
},
];
];
export
const
cardRuleList
=
[
{
title
:
'【全局】新增字段规则'
,
type
:
'newFieldRule'
,
description
:
'为源端所有数据表都新增一个字段,例如为每张表增加一个入库时间列'
,
},
{
title
:
'数据转换规则'
,
type
:
'dataTransformationRule'
,
description
:
'根据业务需求,对源端单张数据表的单个字段进行数据转换操作'
,
},
{
title
:
'数据过滤规则'
,
type
:
'dataFilterRule'
,
description
:
'根据业务需求,对源端单张数据表的数据进行过滤操作'
,
},
];
export
const
mappingRuleConfigurationTableList
=
[
{
businessId
:
1
,
ruleName
:
'[全局] 新增字段规则'
,
ruleContent
:
'新增字段名称:a, 字段类型:string, 字段表达式:asd'
,
},
{
businessId
:
2
,
ruleName
:
'数据转换规则'
,
ruleContent
:
'数据表: table1, 已有字段: field1, 转换规则: 配置规则'
,
},
{
businessId
:
3
,
ruleName
:
'数据过滤规则'
,
ruleContent
:
"自定义规则:field1 != 'axxc'"
,
},
];
src/views/dataIntegration/dataLoading/fileLoading/index.vue
View file @
106d7371
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
<template
#
footer
>
<template
#
footer
>
<Tabs
v-model:activeKey=
"activeKey"
>
<Tabs
v-model:activeKey=
"activeKey"
>
<TabPane
key=
"1"
tab=
"源端配置"
>
<TabPane
key=
"1"
tab=
"源端配置"
>
<div
style=
"display: flex"
>
<div
style=
"display: flex
; padding-top: 20px; gap: 20px
"
>
<BasicForm
class=
"w-1/3"
@
register=
"fileForm"
>
<BasicForm
class=
"w-1/3"
@
register=
"fileForm"
>
<template
#
file=
"
{ field, model }">
<template
#
file=
"
{ field, model }">
<Upload
<Upload
...
@@ -20,6 +20,15 @@
...
@@ -20,6 +20,15 @@
</Upload>
</Upload>
<span
style=
"color: #dbdcdd; font-size: 12px"
>
仅支持上传单个文件或zip包
</span>
<span
style=
"color: #dbdcdd; font-size: 12px"
>
仅支持上传单个文件或zip包
</span>
</
template
>
</
template
>
<
template
#
loadingType=
"{ field, model }"
>
<RadioGroup
v-model:value=
"model[field]"
:options=
"loadingTypeOptions"
/>
<Alert
v-if=
"model[field] === '增量文件加载'"
show-icon
message=
"仅支持HDFS类型的文件系统"
style=
"margin-top: 15px"
/>
</
template
>
<
template
#
path=
"{ field, model }"
>
<
template
#
path=
"{ field, model }"
>
<div
style=
"display: flex"
>
<div
style=
"display: flex"
>
<Input
v-model:value=
"model[field]"
/>
<Input
v-model:value=
"model[field]"
/>
...
@@ -59,8 +68,12 @@
...
@@ -59,8 +68,12 @@
</BasicForm>
</BasicForm>
<div
class=
"w-2/3"
>
<div
class=
"w-2/3"
>
<Alert
show-icon
message=
"由于数据量太大,只展示前10行数据"
/>
<Alert
show-icon
message=
"由于数据量太大,只展示前10行数据"
/>
<Alert
show-icon
message=
"当前服务将会表头中把除了下划线以外其他特殊字符转为下划线"
/>
<Alert
<BasicTable
v-if=
"showFileTable"
@
register=
"fileTable"
>
style=
"margin-top: 10px"
show-icon
message=
"当前服务将会表头中把除了下划线以外其他特殊字符转为下划线"
/>
<BasicTable
style=
"margin-top: 15px"
v-if=
"showFileTable"
@
register=
"fileTable"
>
<
template
#
toolbar
>
<
template
#
toolbar
>
<div
style=
"flex: 1; display: flex; justify-content: space-between"
>
<div
style=
"flex: 1; display: flex; justify-content: space-between"
>
<Input
style=
"width: 200px"
v-model:value=
"key"
placeholder=
"关键字搜索"
/>
<Input
style=
"width: 200px"
v-model:value=
"key"
placeholder=
"关键字搜索"
/>
...
@@ -400,7 +413,8 @@
...
@@ -400,7 +413,8 @@
import
{
import
{
compareColumns
,
compareColumns
,
compareSearchFormSchema
,
compareSearchFormSchema
,
getMetadataColumns
,
mappingRuleConfigurationColumns
,
getMetadataColumns
,
mappingRuleConfigurationColumns
,
tabularPresentationColumns
,
tabularPresentationColumns
,
tabularPresentationSearchFormSchema
,
tabularPresentationSearchFormSchema
,
}
from
'@/views/dataIntegration/dataLoading/dataEntryLake/offlineLoading.data'
;
}
from
'@/views/dataIntegration/dataLoading/dataEntryLake/offlineLoading.data'
;
...
@@ -412,18 +426,19 @@
...
@@ -412,18 +426,19 @@
dataSourceData
,
dataSourceData
,
dataSourceFieldData
,
dataSourceFieldData
,
fileData
,
fileData
,
mappingRuleConfigurationTableList
,
}
from
'@/views/dataIntegration/dataLoading/fileLoading/fileData'
;
}
from
'@/views/dataIntegration/dataLoading/fileLoading/fileData'
;
import
{
useMessage
}
from
'@/hooks/web/useMessage'
;
import
{
useMessage
}
from
'@/hooks/web/useMessage'
;
import
type
{
UploadChangeParam
}
from
'ant-design-vue'
;
import
type
{
UploadChangeParam
}
from
'ant-design-vue'
;
import
{
import
{
compareTableList
,
mappingRuleConfigurationTableList
,
compareTableList
,
tabularPresentationTableList
,
tabularPresentationTableList
,
}
from
'@/views/dataIntegration/dataLoading/dataEntryLake/mock'
;
}
from
'@/views/dataIntegration/dataLoading/dataEntryLake/mock'
;
import
ViewLogModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/ViewLogModal.vue'
;
import
ViewLogModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/ViewLogModal.vue'
;
import
PartitionedDataProcessingModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/PartitionedDataProcessingModal.vue'
;
import
PartitionedDataProcessingModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/PartitionedDataProcessingModal.vue'
;
import
ClearConfigurationModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/ClearConfigurationModal.vue'
;
import
ClearConfigurationModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/ClearConfigurationModal.vue'
;
import
BatchScaleNameMappingModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/BatchScaleNameMappingModal.vue'
;
import
BatchScaleNameMappingModal
from
'@/views/dataIntegration/dataLoading/dataEntryLake/BatchScaleNameMappingModal.vue'
;
import
AddDataConversionRuleModal
from
'@/views/dataIntegration/dataLoading/
dataEntryLake
/addDataConversionRuleModal.vue'
;
import
AddDataConversionRuleModal
from
'@/views/dataIntegration/dataLoading/
fileLoading
/addDataConversionRuleModal.vue'
;
const
key
=
ref
(
''
);
const
key
=
ref
(
''
);
const
activeKey
=
ref
(
'1'
);
const
activeKey
=
ref
(
'1'
);
...
@@ -444,6 +459,16 @@
...
@@ -444,6 +459,16 @@
model
.
fileName
=
fileList
.
value
[
0
].
name
;
model
.
fileName
=
fileList
.
value
[
0
].
name
;
model
.
sheetName
=
'Sheet1,Sheet2,Sheet3'
;
model
.
sheetName
=
'Sheet1,Sheet2,Sheet3'
;
};
};
const
loadingTypeOptions
=
[
{
label
:
'全量文件加载'
,
value
:
'全量文件加载'
,
},
{
label
:
'增量文件加载'
,
value
:
'增量文件加载'
,
},
];
const
[
fileForm
,
{
validate
:
fileValidate
,
getFieldsValue
:
getFileFormValue
}]
=
useForm
({
const
[
fileForm
,
{
validate
:
fileValidate
,
getFieldsValue
:
getFileFormValue
}]
=
useForm
({
labelWidth
:
100
,
labelWidth
:
100
,
baseColProps
:
{
lg
:
24
,
md
:
24
},
baseColProps
:
{
lg
:
24
,
md
:
24
},
...
@@ -461,6 +486,7 @@
...
@@ -461,6 +486,7 @@
content
:
'确认覆盖之前的解析结果吗?'
,
content
:
'确认覆盖之前的解析结果吗?'
,
onOk
()
{
onOk
()
{
createMessage
.
success
(
'覆盖成功!'
);
createMessage
.
success
(
'覆盖成功!'
);
fileReload
();
},
},
});
});
}
}
...
@@ -668,16 +694,16 @@
...
@@ -668,16 +694,16 @@
},
},
];
];
const
showFileTable
=
ref
(
false
);
const
showFileTable
=
ref
(
false
);
const
[
fileTable
]
=
useTable
({
const
[
fileTable
,
{
reload
:
fileReload
}
]
=
useTable
({
api
:
async
()
=>
{
api
:
async
()
=>
{
const
response
=
{
const
response
=
{
pageNu
:
'1'
,
pageNu
:
'1'
,
pageSize
:
'5'
,
pageSize
:
'5'
,
pages
:
'1'
,
pages
:
'1'
,
total
:
fileData
.
length
,
total
:
fileData
(
10
)
.
length
,
code
:
''
,
code
:
''
,
message
:
''
,
message
:
''
,
data
:
fileData
,
data
:
fileData
(
10
)
,
};
};
return
{
...
response
};
return
{
...
response
};
},
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment