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
0bddfd95
Commit
0bddfd95
authored
Dec 06, 2024
by
chenjiahao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
数仓开发-数据加载-需求修正
parent
a9f61b9f
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
94 additions
and
56 deletions
+94
-56
BatchConfigurationModal.vue
...ion/dataLoading/dataEntryLake/BatchConfigurationModal.vue
+1
-0
DeplysModal.vue
...dataIntegration/dataLoading/dataEntryLake/DeplysModal.vue
+2
-1
dataEntry.data.ts
...taIntegration/dataLoading/dataEntryLake/dataEntry.data.ts
+30
-14
databaseOfflineLoading.vue
...tion/dataLoading/dataEntryLake/databaseOfflineLoading.vue
+9
-16
fieldNameMappingRuleModal.vue
...n/dataLoading/dataEntryLake/fieldNameMappingRuleModal.vue
+4
-2
fieldTypeMappingRuleModal.vue
...n/dataLoading/dataEntryLake/fieldTypeMappingRuleModal.vue
+4
-2
mock.ts
src/views/dataIntegration/dataLoading/dataEntryLake/mock.ts
+8
-1
newFieldRuleModal.vue
...tegration/dataLoading/dataEntryLake/newFieldRuleModal.vue
+4
-2
singleTableFieldMappingRuleModal.vue
...oading/dataEntryLake/singleTableFieldMappingRuleModal.vue
+7
-4
file.data.ts
...iews/dataIntegration/dataLoading/fileLoading/file.data.ts
+12
-8
GroupTree.vue
...llResourceDevelopment/dataSet/commonDataSet/GroupTree.vue
+1
-1
commonDataSet.data.ts
...ceDevelopment/dataSet/commonDataSet/commonDataSet.data.ts
+1
-1
index.vue
...s/mallResourceDevelopment/dataSet/commonDataSet/index.vue
+3
-4
mock.ts
...ews/mallResourceDevelopment/dataSet/commonDataSet/mock.ts
+8
-0
No files found.
src/views/dataIntegration/dataLoading/dataEntryLake/BatchConfigurationModal.vue
View file @
0bddfd95
...
...
@@ -275,6 +275,7 @@
{
field
:
'addOtherConfiguration'
,
label
:
' '
,
labelWidth
:
15
,
slot
:
'addOtherConfiguration'
,
},
];
...
...
src/views/dataIntegration/dataLoading/dataEntryLake/DeplysModal.vue
View file @
0bddfd95
...
...
@@ -14,7 +14,7 @@
<Alert
show-icon
style=
"font-size: 12px"
message=
"
基于数量的加载策略,要求在进行数据加载时,源端的表不要发生数据变更,否则可能会出现数据加载异常。
"
message=
"
增量标识列只支持日期类型和整数型字段
"
type=
"info"
/>
</
template
>
...
...
@@ -47,6 +47,7 @@
ifShow
:
false
,
},
{
label
:
' '
,
field
:
'incrementIdentificationColumnAlert'
,
slot
:
'incrementIdentificationColumnAlert'
,
ifShow
:
false
,
...
...
src/views/dataIntegration/dataLoading/dataEntryLake/dataEntry.data.ts
View file @
0bddfd95
...
...
@@ -253,10 +253,12 @@ export const NewFieldRuleFormSchema: FormSchema[] = [
component
:
'Select'
,
componentProps
:
{
options
:
[
{
label
:
'INT'
,
value
:
'INT'
},
{
label
:
'BIGINT'
,
value
:
'BIGINT'
},
{
label
:
'DECIMAL'
,
value
:
'DECIMAL'
},
{
label
:
'VARCHAR'
,
value
:
'VARCHAR'
},
{
label
:
'int'
,
value
:
'int'
},
{
label
:
'bigint'
,
value
:
'bigint'
},
{
label
:
'decimal'
,
value
:
'decimal'
},
{
label
:
'varchar'
,
value
:
'varchar'
},
{
label
:
'string'
,
value
:
'string'
},
{
label
:
'timestamp'
,
value
:
'timestamp'
},
],
},
required
:
true
,
...
...
@@ -286,10 +288,12 @@ export const FieldTypeMappingRuleFormSchema: FormSchema[] = [
component
:
'Select'
,
componentProps
:
{
options
:
[
{
label
:
'INT'
,
value
:
'INT'
},
{
label
:
'BIGINT'
,
value
:
'BIGINT'
},
{
label
:
'DECIMAL'
,
value
:
'DECIMAL'
},
{
label
:
'VARCHAR'
,
value
:
'VARCHAR'
},
{
label
:
'int'
,
value
:
'int'
},
{
label
:
'bigint'
,
value
:
'bigint'
},
{
label
:
'decimal'
,
value
:
'decimal'
},
{
label
:
'varchar'
,
value
:
'varchar'
},
{
label
:
'string'
,
value
:
'string'
},
{
label
:
'timestamp'
,
value
:
'timestamp'
},
],
},
required
:
true
,
...
...
@@ -297,7 +301,17 @@ export const FieldTypeMappingRuleFormSchema: FormSchema[] = [
{
field
:
'targetFieldType'
,
label
:
'目标字段类型'
,
component
:
'Input'
,
component
:
'Select'
,
componentProps
:
{
options
:
[
{
label
:
'int'
,
value
:
'int'
},
{
label
:
'bigint'
,
value
:
'bigint'
},
{
label
:
'decimal'
,
value
:
'decimal'
},
{
label
:
'varchar'
,
value
:
'varchar'
},
{
label
:
'string'
,
value
:
'string'
},
{
label
:
'timestamp'
,
value
:
'timestamp'
},
],
},
required
:
true
,
},
];
...
...
@@ -354,7 +368,7 @@ export const DataTransformationRuleFormSchema: FormSchema[] = [
],
},
required
:
true
,
ifShow
:
fals
e
,
ifShow
:
tru
e
,
},
{
field
:
'newFieldName'
,
...
...
@@ -369,10 +383,12 @@ export const DataTransformationRuleFormSchema: FormSchema[] = [
component
:
'Select'
,
componentProps
:
{
options
:
[
{
label
:
'INT'
,
value
:
'INT'
},
{
label
:
'BIGINT'
,
value
:
'BIGINT'
},
{
label
:
'DECIMAL'
,
value
:
'DECIMAL'
},
{
label
:
'VARCHAR'
,
value
:
'VARCHAR'
},
{
label
:
'int'
,
value
:
'int'
},
{
label
:
'bigint'
,
value
:
'bigint'
},
{
label
:
'decimal'
,
value
:
'decimal'
},
{
label
:
'varchar'
,
value
:
'varchar'
},
{
label
:
'string'
,
value
:
'string'
},
{
label
:
'timestamp'
,
value
:
'timestamp'
},
],
},
required
:
true
,
...
...
src/views/dataIntegration/dataLoading/dataEntryLake/databaseOfflineLoading.vue
View file @
0bddfd95
...
...
@@ -289,7 +289,7 @@
<Icon
v-if=
"unfoldConfigurationTableSelect"
icon=
"fe:arrow-up"
/>
<Icon
v-else
icon=
"fe:arrow-down"
/>
</a-button>
<a-input-search
style=
"width:
22
0px"
@
search=
"onSearch"
/>
<a-input-search
style=
"width:
16
0px"
@
search=
"onSearch"
/>
</div>
<!--配置按钮-->
<div
style=
"display: flex; gap: 5px"
>
...
...
@@ -1162,15 +1162,8 @@
placeholder
:
''
,
options
:
[
{
label
:
'ORC'
,
value
:
'ORC'
},
{
label
:
'Parquet'
,
value
:
'Parquet'
},
{
label
:
'CSV'
,
value
:
'CSV'
},
{
label
:
'JSON'
,
value
:
'JSON'
},
{
label
:
'Avro'
,
value
:
'Avro'
},
{
label
:
'TORC'
,
value
:
'ORC'
},
{
label
:
'Text'
,
value
:
'Text'
},
{
label
:
'SequenceFile'
,
value
:
'SequenceFile'
},
{
label
:
'RCFile'
,
value
:
'RCFile'
},
{
label
:
'HBase'
,
value
:
'HBase'
},
{
label
:
'Kafka'
,
value
:
'Kafka'
},
],
},
},
...
...
@@ -1916,23 +1909,23 @@
switch
(
record
.
ruleName
)
{
case
'[全局] 新增字段规则'
:
console
.
log
(
'Handling new field rule'
);
openNewFieldRuleModal
(
true
);
openNewFieldRuleModal
(
true
,
record
);
break
;
case
'[全局] 字段名称映射规则'
:
console
.
log
(
'Handling field name mapping rule'
);
openFieldNameMappingRuleModal
(
true
);
openFieldNameMappingRuleModal
(
true
,
record
);
break
;
case
'[全局] 字段类型映射规则'
:
console
.
log
(
'Handling field type mapping rule'
);
openFieldTypeMappingRuleModal
(
true
);
openFieldTypeMappingRuleModal
(
true
,
record
);
break
;
case
'数据转换规则'
:
console
.
log
(
'Handling data transformation rule'
);
openDataTransformationRuleModal
(
true
);
openDataTransformationRuleModal
(
true
,
record
);
break
;
case
'[单表] 字段映射规则'
:
console
.
log
(
'Handling single table field mapping rule'
);
openSingleTableFieldMappingRuleModal
(
true
);
openSingleTableFieldMappingRuleModal
(
true
,
record
);
break
;
default
:
console
.
log
(
'Unknown rule type'
);
...
...
@@ -1946,14 +1939,14 @@
title
:
'删除规则'
,
content
:
'是否确认删除规则?'
,
onOk
()
{
createMessage
.
success
(
'删除
规则成功
'
);
createMessage
.
success
(
'删除
成功!
'
);
},
});
}
function
handleDeleteRules
()
{
createMessage
.
success
(
'批量删除
数据转换规则成功
'
+
getMappingRuleConfigurationRowSelection
().
selectedRowKeys
,
'批量删除
成功!
'
+
getMappingRuleConfigurationRowSelection
().
selectedRowKeys
,
);
}
...
...
src/views/dataIntegration/dataLoading/dataEntryLake/fieldNameMappingRuleModal.vue
View file @
0bddfd95
...
...
@@ -48,7 +48,7 @@
const
fieldNameMappingRuleTable
=
ref
(
fieldNameMappingRuleTableList
);
const
emit
=
defineEmits
([
'success'
,
'register'
]);
const
[
registerForm
,
{
validate
}]
=
useForm
({
const
[
registerForm
,
{
validate
,
setFieldsValue
}]
=
useForm
({
labelWidth
:
100
,
labelAlign
:
'left'
,
baseColProps
:
{
span
:
24
},
...
...
@@ -59,7 +59,9 @@
},
});
//初始化弹框
const
[
registerModal
,
{
closeModal
,
setModalProps
}]
=
useModalInner
(
async
()
=>
{});
const
[
registerModal
,
{
closeModal
,
setModalProps
}]
=
useModalInner
(
async
(
data
)
=>
{
await
setFieldsValue
({
...
data
});
});
const
[
registerFieldNameMappingRuleTable
]
=
useTable
({
api
:
async
()
=>
{
...
...
src/views/dataIntegration/dataLoading/dataEntryLake/fieldTypeMappingRuleModal.vue
View file @
0bddfd95
...
...
@@ -27,7 +27,7 @@
import
{
FieldTypeMappingRuleFormSchema
}
from
'./dataEntry.data'
;
const
emit
=
defineEmits
([
'success'
,
'register'
]);
const
[
registerForm
,
{
validate
}]
=
useForm
({
const
[
registerForm
,
{
validate
,
setFieldsValue
}]
=
useForm
({
labelWidth
:
100
,
baseColProps
:
{
span
:
24
},
schemas
:
FieldTypeMappingRuleFormSchema
,
...
...
@@ -37,7 +37,9 @@
},
});
//初始化弹框
const
[
registerModal
,
{
closeModal
,
setModalProps
}]
=
useModalInner
(
async
()
=>
{});
const
[
registerModal
,
{
closeModal
,
setModalProps
}]
=
useModalInner
(
async
(
data
)
=>
{
await
setFieldsValue
({
...
data
});
});
async
function
handleSubmit
()
{
try
{
...
...
src/views/dataIntegration/dataLoading/dataEntryLake/mock.ts
View file @
0bddfd95
...
...
@@ -964,26 +964,33 @@ export const mappingRuleConfigurationTableList = [
businessId
:
'1'
,
ruleName
:
'[单表] 字段映射规则'
,
ruleContent
:
'源表名:table_1'
,
selectiveDataTable
:
'table_1'
,
},
{
businessId
:
'2'
,
ruleName
:
'[全局] 新增字段规则'
,
newFieldName
:
'a'
,
newFieldType
:
'string'
,
fieldExpression
:
'asd'
,
ruleContent
:
'新增字段名称:a, 字段类型:string, 字段表达式:asd'
,
},
{
businessId
:
'3'
,
ruleName
:
'[全局] 字段名称映射规则'
,
ruleContent
:
'
原
字段名称:未配置, 目标字段名称:未配置'
,
ruleContent
:
'
源
字段名称:未配置, 目标字段名称:未配置'
,
},
{
businessId
:
'4'
,
ruleName
:
'[全局] 字段类型映射规则'
,
ruleContent
:
'源字段类型:timestamp, 目标字段类型:string'
,
sourceFieldType
:
'timestamp'
,
targetFieldType
:
'string'
,
},
{
businessId
:
'5'
,
ruleName
:
'[单表] 字段映射规则'
,
ruleContent
:
'源表名:table_2'
,
selectiveDataTable
:
'table_2'
,
},
];
...
...
src/views/dataIntegration/dataLoading/dataEntryLake/newFieldRuleModal.vue
View file @
0bddfd95
...
...
@@ -26,7 +26,7 @@
import
{
NewFieldRuleFormSchema
}
from
'./dataEntry.data'
;
const
emit
=
defineEmits
([
'success'
,
'register'
]);
const
[
registerForm
,
{
validate
}]
=
useForm
({
const
[
registerForm
,
{
validate
,
setFieldsValue
}]
=
useForm
({
labelWidth
:
100
,
baseColProps
:
{
span
:
24
},
schemas
:
NewFieldRuleFormSchema
,
...
...
@@ -36,7 +36,9 @@
},
});
//初始化弹框
const
[
registerModal
,
{
closeModal
,
setModalProps
}]
=
useModalInner
(
async
()
=>
{});
const
[
registerModal
,
{
closeModal
,
setModalProps
}]
=
useModalInner
(
async
(
data
)
=>
{
await
setFieldsValue
({
...
data
});
});
async
function
handleSubmit
()
{
try
{
...
...
src/views/dataIntegration/dataLoading/dataEntryLake/singleTableFieldMappingRuleModal.vue
View file @
0bddfd95
...
...
@@ -29,14 +29,15 @@
import
BasicTable
from
'@/components/Table/src/BasicTable.vue'
;
import
{
useTable
}
from
'@/components/Table'
;
import
{
fieldNameMappingRuleColumns
,
singleGoalFieldNameMappingRuleColumns
,
singleSourceFieldNameMappingRuleColumns
fieldNameMappingRuleColumns
,
singleGoalFieldNameMappingRuleColumns
,
singleSourceFieldNameMappingRuleColumns
,
}
from
'@/views/dataIntegration/dataLoading/dataEntryLake/offlineLoading.data'
;
const
sourceFieldNameMappingRuleTable
=
ref
(
sourceFieldNameMappingRuleTableList
);
const
goalFieldNameMappingRuleTable
=
ref
(
goalFieldNameMappingRuleTableList
);
const
emit
=
defineEmits
([
'success'
,
'register'
]);
const
[
registerForm
,
{
validate
}]
=
useForm
({
const
[
registerForm
,
{
validate
,
setFieldsValue
}]
=
useForm
({
labelWidth
:
100
,
labelAlign
:
'left'
,
baseColProps
:
{
span
:
24
},
...
...
@@ -47,7 +48,9 @@
},
});
//初始化弹框
const
[
registerModal
,
{
closeModal
,
setModalProps
}]
=
useModalInner
(
async
()
=>
{});
const
[
registerModal
,
{
closeModal
,
setModalProps
}]
=
useModalInner
(
async
(
data
)
=>
{
await
setFieldsValue
({
...
data
});
});
const
[
registerSourceFieldNameMappingRuleTable
]
=
useTable
({
api
:
async
()
=>
{
...
...
src/views/dataIntegration/dataLoading/fileLoading/file.data.ts
View file @
0bddfd95
...
...
@@ -538,10 +538,12 @@ export const addFieldRuleModal: FormSchema[] = [
component
:
'Select'
,
componentProps
:
{
options
:
[
{
label
:
'INT'
,
value
:
'INT'
},
{
label
:
'BIGINT'
,
value
:
'BIGINT'
},
{
label
:
'DECIMAL'
,
value
:
'DECIMAL'
},
{
label
:
'VARCHAR'
,
value
:
'VARCHAR'
},
{
label
:
'int'
,
value
:
'int'
},
{
label
:
'bigint'
,
value
:
'bigint'
},
{
label
:
'decimal'
,
value
:
'decimal'
},
{
label
:
'varchar'
,
value
:
'varchar'
},
{
label
:
'string'
,
value
:
'string'
},
{
label
:
'timestamp'
,
value
:
'timestamp'
},
],
},
required
:
true
,
...
...
@@ -623,10 +625,12 @@ export const dataChangeRuleFormSchema: FormSchema[] = [
component
:
'Select'
,
componentProps
:
{
options
:
[
{
label
:
'INT'
,
value
:
'INT'
},
{
label
:
'BIGINT'
,
value
:
'BIGINT'
},
{
label
:
'DECIMAL'
,
value
:
'DECIMAL'
},
{
label
:
'VARCHAR'
,
value
:
'VARCHAR'
},
{
label
:
'int'
,
value
:
'int'
},
{
label
:
'bigint'
,
value
:
'bigint'
},
{
label
:
'decimal'
,
value
:
'decimal'
},
{
label
:
'varchar'
,
value
:
'varchar'
},
{
label
:
'string'
,
value
:
'string'
},
{
label
:
'timestamp'
,
value
:
'timestamp'
},
],
},
required
:
({
model
})
=>
{
...
...
src/views/mallResourceDevelopment/dataSet/commonDataSet/GroupTree.vue
View file @
0bddfd95
...
...
@@ -16,7 +16,7 @@
<
script
lang=
"ts"
setup
>
import
{
nextTick
,
onMounted
,
ref
,
unref
}
from
'vue'
;
import
{
BasicTree
,
TreeActionType
,
TreeItem
}
from
'@/components/Tree'
;
import
{
Nullable
}
from
'
packages/types/src/index
'
;
import
{
Nullable
}
from
'
@vben/types
'
;
import
{
TreeData
}
from
'./mock.ts'
;
import
{
useMessage
}
from
'@/hooks/web/useMessage'
;
import
{
useModal
}
from
'@/components/Modal'
;
...
...
src/views/mallResourceDevelopment/dataSet/commonDataSet/commonDataSet.data.ts
View file @
0bddfd95
...
...
@@ -69,7 +69,7 @@ export const schema: DescItem[] = [
labelMinWidth
:
60
,
},
{
field
:
'
isShar
e'
,
field
:
'
sensitiveStat
e'
,
label
:
'敏感状态'
,
labelMinWidth
:
60
,
},
...
...
src/views/mallResourceDevelopment/dataSet/commonDataSet/index.vue
View file @
0bddfd95
...
...
@@ -173,12 +173,11 @@
import
{
useMessage
}
from
'@/hooks/web/useMessage'
;
import
{
useRouter
}
from
'vue-router'
;
import
GroupTree
from
'./GroupTree.vue'
;
import
{
Columns
}
from
'
@/views/mallResourceDevelopment/dataSet/commonDataSet
/commonDataSet.data'
;
import
{
Columns
}
from
'
.
/commonDataSet.data'
;
import
{
router
}
from
'@/router'
;
import
{
useModal
}
from
'@/components/Modal'
;
import
ApplyForPushNotificationsModal
from
'@/views/mallResourceDevelopment/dataSet/commonDataSet/applyForPushNotificationsModal.vue'
;
import
Edit
from
'@/views/dataQuality/dataSheet/template/edit.vue'
;
import
EditModal
from
'@/views/mallResourceDevelopment/dataSet/commonDataSet/editModal.vue'
;
import
ApplyForPushNotificationsModal
from
'./applyForPushNotificationsModal.vue'
;
import
EditModal
from
'./editModal.vue'
;
const
{
createMessage
,
createConfirm
}
=
useMessage
();
const
route
=
useRouter
();
...
...
src/views/mallResourceDevelopment/dataSet/commonDataSet/mock.ts
View file @
0bddfd95
...
...
@@ -282,6 +282,7 @@ export const cardList = [
scene
:
'databaseOfflineLoading'
,
parentWorkSpaceName
:
'党建建设'
,
path
:
'资源编目 / 党建建设 / 基本信息'
,
sensitiveState
:
'非敏感'
,
icon
:
'majesticons:table'
,
color
:
'#71c8d5'
,
dept
:
'数据资源管理部'
,
...
...
@@ -299,6 +300,7 @@ export const cardList = [
scene
:
'partyDevelopmentPlan'
,
parentWorkSpaceName
:
'党建建设'
,
path
:
'资源编目 / 党建建设 / 党员发展计划'
,
sensitiveState
:
'敏感'
,
icon
:
'majesticons:table'
,
color
:
'#71c8d5'
,
renewalFrequency
:
'每天'
,
...
...
@@ -316,6 +318,7 @@ export const cardList = [
scene
:
'themeEducationActivity'
,
parentWorkSpaceName
:
'党建建设'
,
path
:
'资源编目 / 党建建设 / 主题教育活动'
,
sensitiveState
:
'敏感'
,
icon
:
'majesticons:table'
,
color
:
'#71c8d5'
,
renewalFrequency
:
'每周'
,
...
...
@@ -333,6 +336,7 @@ export const cardList = [
scene
:
'partyWorkSummary'
,
parentWorkSpaceName
:
'党建建设'
,
path
:
'资源编目 / 党建建设 / 党建工作总结'
,
sensitiveState
:
'非敏感'
,
icon
:
'majesticons:table'
,
color
:
'#71c8d5'
,
renewalFrequency
:
'每天'
,
...
...
@@ -350,6 +354,7 @@ export const cardList = [
scene
:
'partyHistoryQuiz'
,
parentWorkSpaceName
:
'党建建设'
,
path
:
'资源编目 / 党建建设 / 党史知识竞赛'
,
sensitiveState
:
'敏感'
,
icon
:
'majesticons:table'
,
color
:
'#71c8d5'
,
renewalFrequency
:
'每天'
,
...
...
@@ -367,6 +372,7 @@ export const cardList = [
scene
:
'urbanBusOptimization'
,
parentWorkSpaceName
:
'交通信息'
,
path
:
'资源编目 / 交通信息 / 公交优化方案'
,
sensitiveState
:
'非敏感'
,
icon
:
'majesticons:bus'
,
color
:
'#71c8d5'
,
dept
:
'交通规划部'
,
...
...
@@ -383,6 +389,7 @@ export const cardList = [
title
:
'交通系统部署'
,
scene
:
'intelligentTransportSystemDeployment'
,
path
:
'资源编目 / 交通信息 / 交通系统部署'
,
sensitiveState
:
'敏感'
,
icon
:
'majesticons:bus'
,
parentWorkSpaceName
:
'交通信息'
,
color
:
'#71c8d5'
,
...
...
@@ -402,6 +409,7 @@ export const cardList = [
scene
:
'greenCommuteInitiative'
,
icon
:
'majesticons:bus'
,
path
:
'资源编目 / 交通信息 / 绿色出行倡议'
,
sensitiveState
:
'非敏感'
,
parentWorkSpaceName
:
'交通信息'
,
color
:
'#71c8d5'
,
renewalFrequency
:
'每周'
,
...
...
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