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
4c1f1ce0
Commit
4c1f1ce0
authored
Dec 06, 2024
by
罗林杰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改自助建表
parent
9b9405d4
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
255 additions
and
145 deletions
+255
-145
DeptTree.vue
src/views/scriptDevelopment/functionManagement/DeptTree.vue
+1
-14
index.vue
src/views/scriptDevelopment/functionManagement/index.vue
+186
-107
mock.ts
src/views/scriptDevelopment/functionManagement/mock.ts
+13
-18
index.vue
...iews/scriptDevelopment/selfServiceTableCreation/index.vue
+24
-3
mock.ts
src/views/scriptDevelopment/selfServiceTableCreation/mock.ts
+31
-1
importModal.vue
...iptDevelopment/sqlDevelopment/importModal/importModal.vue
+0
-2
No files found.
src/views/scriptDevelopment/functionManagement/DeptTree.vue
View file @
4c1f1ce0
<
template
>
<
template
>
<div
class=
"m-4 mr-0 overflow-hidden bg-white"
>
<div
class=
"overflow-hidden bg-white"
>
<div
class=
"m-4 mr-0 overflow-hidden bg-white"
style=
"margin-bottom: -20px"
>
<BasicTree
ref=
"treeRef1"
toolbar
search
treeWrapperClassName=
"h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand=
"true"
:defaultExpandAll=
"true"
:treeData=
"treeData"
:fieldNames=
"
{ key: 'businessId', title: 'label'}"
@select="handleSelect"
/>
</div>
<a-input
placeholder=
""
style=
"margin: 10px 0;"
>
<a-input
placeholder=
""
style=
"margin: 10px 0;"
>
<template
#
prefix
>
<template
#
prefix
>
<Icon
icon=
"ant-design:search-outlined"
:size=
"20"
/>
<Icon
icon=
"ant-design:search-outlined"
:size=
"20"
/>
...
...
src/views/scriptDevelopment/functionManagement/index.vue
View file @
4c1f1ce0
<
template
>
<
template
>
<PageWrapper
dense
contentFullHeight
fixedHeight
contentClass=
"flex"
>
<PageWrapper
dense
contentFullHeight
fixedHeight
contentClass=
"flex"
>
<DeptTree
class=
"w-1/4 xl:w-1/5"
@
select=
"handleSelect"
/>
<DeptTree
class=
"w-1/4 xl:w-1/5"
@
select=
"handleSelect"
/>
<editAuditRulesModal
<editAuditRulesModal
style=
"background: #cc0000
;
"
style=
"background: #cc0000"
class=
"w-3/4 xl:w-4/5"
class=
"w-3/4 xl:w-4/5"
v-if=
"isSpecificDeptSelected"
v-if=
"isSpecificDeptSelected"
:deptId=
"selectedDeptId"
:deptId=
"selectedDeptId"
/>
/>
<BasicTable
<div
class=
"w-3/4 xl:w-4/5"
v-else
>
@
register=
"registerTable"
<div
style=
"display: flex; align-items: center; background-color: white"
>
class=
"w-3/4 xl:w-4/5"
<Icon
icon=
"majesticons:table-plus-line"
:size=
"40"
:color=
"'#e9a064'"
/>
:searchInfo=
"searchInfo"
<div
style=
"margin-left: 10px"
>
v-else
<span
class=
"title"
>
test
</span>
>
<div>
<template
#
bodyCell=
"
{ column }">
<span
class=
"path"
>
自助建表文件/test
</span>
<template
v-if=
"column.key === 'action'"
>
</div>
<TableAction
</div>
:actions=
"[
<a-button
style=
"margin-left: 700px"
type=
"primary"
@
click=
"handleDeleteIds"
>
删除
</a-button>
{
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleMove(1)"
>
移动
</a-button>
icon: 'ant-design:ellipsis-outlined',
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleExport('文件')"
>
导出
</a-button
>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleImport"
>
导入
</a-button>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleNewFolder"
>
新建文件夹
</a-button
>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleNewFile"
>
新建文件
</a-button
>
</div>
<BasicTable
@
register=
"registerTable"
:searchInfo=
"searchInfo"
>
<template
#
bodyCell=
"
{ column, record }">
<template
v-if=
"column.key === 'action'"
>
<TableAction
:actions=
"[
{
icon: 'bx:rename',
tooltip: '重命名',
onClick: resetName.bind(null, record),
},
{
icon: 'tdesign:folder-move',
tooltip: '移动',
onClick: handleMove.bind(null, 1),
},
{
icon: 'material-symbols-light:delete-outline',
tooltip: '删除',
popConfirm: {
title: '是否确认删除',
placement: 'left',
confirm: handleDelete.bind(null),
},
},
]"
},
/>
]"
/>
</
template
>
</template>
</template>
</template>
<
template
#
toolbar
>
<a-input
style=
"width: 200px; margin-right: auto"
placeholder=
"输入关键字搜索"
allowClear
/>
<a-button
type=
"primary"
>
导入
</a-button>
<a-button
type=
"primary"
>
导出
</a-button>
<a-button
type=
"primary"
>
删除
</a-button>
<a-button
type=
"primary"
>
移动
</a-button>
<a-button
type=
"primary"
>
新建文件夹
</a-button>
<a-button
type=
"primary"
>
新建
</a-button>
</
template
>
</BasicTable>
<
template
#
toolbar
>
<a-input
style=
"width: 200px; margin-right: auto"
placeholder=
"输入关键字搜索"
allowClear
/>
</
template
>
</BasicTable>
</div>
<MoveFile
@
register=
"registerMoveFile"
/>
<AddFile
@
register=
"registerAddFile"
/>
<Rename
@
register=
"registerRename"
/>
<importModal
@
register=
"registerImport"
/>
</PageWrapper>
</PageWrapper>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
reactive
,
computed
}
from
'vue'
;
import
{
reactive
,
computed
,
ref
}
from
'vue'
;
import
{
BasicTable
,
TableAction
,
useTable
}
from
'@/components/Table'
;
import
{
BasicTable
,
TableAction
,
useTable
}
from
'@/components/Table'
;
import
{
PageWrapper
}
from
'@/components/Page'
;
import
{
PageWrapper
}
from
'@/components/Page'
;
import
DeptTree
from
'./DeptTree.vue'
;
import
DeptTree
from
'./DeptTree.vue'
;
import
{
ref
}
from
'vue'
;
import
{
tableList
}
from
'./mock'
;
import
{
tableList
}
from
'./mock'
;
import
{
columns
}
from
'./mainBody.data'
;
import
{
columns
}
from
'./mainBody.data'
;
import
editAuditRulesModal
from
'./editAuditRulesModal.vue'
;
import
Icon
from
'@/components/Icon/Icon.vue'
;
import
EditAuditRulesModal
from
"./editAuditRulesModal.vue"
;
import
{
useMessage
}
from
'@/hooks/web/useMessage'
;
import
{
useModal
}
from
'@/components/Modal'
;
defineOptions
({
name
:
'AccountManagement'
});
import
MoveFile
from
'@/views/scriptDevelopment/selfServiceTableCreation/moveFile.vue'
;
import
AddFile
from
'@/views/scriptDevelopment/selfServiceTableCreation/addFile.vue'
;
import
Rename
from
'@/views/scriptDevelopment/selfServiceTableCreation/renameModal.vue'
;
const
isSpecificDeptSelected
=
computed
(()
=>
{
import
{
exportRoleList
}
from
'@/api/system/role/role'
;
return
[
23
,
24
,
25
].
includes
(
selectedDeptId
.
value
);
import
{
downloadByData
}
from
'@/utils/file/download'
;
});
import
importModal
from
'@/views/scriptDevelopment/sqlDevelopment/importModal/importModal.vue'
;
defineOptions
({
name
:
'AccountManagement'
});
// 选中的部门ID
const
selectedDeptId
=
ref
<
string
|
null
>
(
null
);
const
isSpecificDeptSelected
=
computed
(()
=>
{
return
[
23
,
24
,
25
].
includes
(
selectedDeptId
.
value
);
const
searchInfo
=
reactive
<
Recordable
>
({});
});
const
[
const
{
createMessage
,
createConfirm
}
=
useMessage
();
registerTable
,
// 选中的部门ID
{
},
const
selectedDeptId
=
ref
<
string
|
null
>
(
null
);
]
=
useTable
({
const
searchInfo
=
reactive
<
Recordable
>
({});
api
:
async
(
params
)
=>
{
const
[
registerMoveFile
,
{
openModal
:
openMoveFileModal
}]
=
useModal
();
console
.
log
(
'tableList'
,
tableList
);
const
[
registerAddFile
,
{
openModal
:
openAddFileModal
}]
=
useModal
();
const
response
=
{
const
[
registerRename
,
{
openModal
:
openRenameModal
}]
=
useModal
();
pageNu
:
'1'
,
const
[
registerImport
,
{
openModal
:
openImportModal
}]
=
useModal
();
pageSize
:
'10'
,
pages
:
'1'
,
const
[
registerTable
,
{}]
=
useTable
({
total
:
tableList
.
length
,
api
:
async
(
params
)
=>
{
code
:
''
,
console
.
log
(
'tableList'
,
tableList
);
message
:
''
,
const
response
=
{
data
:
tableList
,
pageNu
:
'1'
,
};
pageSize
:
'10'
,
pages
:
'1'
,
return
{
...
response
};
total
:
tableList
.
length
,
},
code
:
''
,
rowKey
:
'businessId'
,
message
:
''
,
data
:
tableList
,
};
columns
,
formConfig
:
{
return
{
...
response
};
labelWidth
:
10
,
},
autoSubmitOnEnter
:
true
,
rowKey
:
'businessId'
,
},
columns
,
rowSelection
:
true
,
formConfig
:
{
useSearchForm
:
false
,
labelWidth
:
10
,
showIndexColumn
:
false
,
autoSubmitOnEnter
:
true
,
showTableSetting
:
false
,
},
bordered
:
true
,
rowSelection
:
true
,
handleSearchInfoFn
(
info
)
{
useSearchForm
:
false
,
console
.
log
(
'handleSearchInfoFn'
,
info
);
showIndexColumn
:
false
,
return
info
;
showTableSetting
:
false
,
},
bordered
:
true
,
actionColumn
:
{
handleSearchInfoFn
(
info
)
{
console
.
log
(
'handleSearchInfoFn'
,
info
);
width
:
80
,
return
info
;
title
:
'操作'
,
},
dataIndex
:
'action'
,
actionColumn
:
{
},
width
:
80
,
});
title
:
'操作'
,
dataIndex
:
'action'
,
},
// 处理选择节点事件
});
const
handleSelect
=
(
deptId
)
=>
{
function
handleDeleteIds
()
{
selectedDeptId
.
value
=
deptId
;
createConfirm
({
iconType
:
'warning'
,
console
.
log
(
'选择节点selectedDeptId:'
,
deptId
);
title
:
'删除'
,
}
content
:
'确定要删除吗?'
,
onOk
:
async
()
=>
{
createMessage
.
success
(
'删除成功'
);
},
});
}
/** 移动按钮*/
function
handleMove
(
isMove
)
{
openMoveFileModal
(
true
,
{
isMove
:
isMove
,
});
}
function
handleDelete
()
{
createMessage
.
success
(
'删除成功!'
);
}
function
handleNewFolder
(
isBucket
)
{
openAddFileModal
(
true
,
{
isBucket
:
isBucket
,
title
:
'新建文件夹'
,
});
}
function
handleNewFile
(
isBucket
)
{
openAddFileModal
(
true
,
{
isBucket
:
isBucket
,
title
:
'新建文件'
,
});
}
function
resetName
(
record
)
{
openRenameModal
(
true
,
{
name
:
record
.
name
,
title
:
'重命名'
,
});
}
/** 导出按钮*/
async
function
handleExport
(
name
)
{
console
.
log
(
'导出----'
);
const
params
=
Object
.
assign
({});
const
data
=
await
exportRoleList
(
params
);
downloadByData
(
data
,
name
+
'.xlsx'
);
}
/** 导入按钮*/
function
handleImport
()
{
openImportModal
(
true
,
{});
}
// 处理选择节点事件
const
handleSelect
=
(
deptId
)
=>
{
selectedDeptId
.
value
=
deptId
;
console
.
log
(
'选择节点selectedDeptId:'
,
deptId
);
};
</
script
>
</
script
>
src/views/scriptDevelopment/functionManagement/mock.ts
View file @
4c1f1ce0
export
const
tableList
:
any
[]
=
[
export
const
tableList
:
any
[]
=
[
{
{
selectedDeptId
:
23
,
selectedDeptId
:
23
,
...
@@ -25,9 +22,7 @@ export const tableList: any[] = [
...
@@ -25,9 +22,7 @@ export const tableList: any[] = [
creationTime
:
'2019/12/12 21:21:21'
,
creationTime
:
'2019/12/12 21:21:21'
,
updateTime
:
'2019/12/12 21:21:21'
,
updateTime
:
'2019/12/12 21:21:21'
,
owner
:
'admin'
,
owner
:
'admin'
,
},
},
];
];
export
const
treeDataList
=
[
export
const
treeDataList
=
[
...
@@ -47,25 +42,25 @@ export const treeDataList = [
...
@@ -47,25 +42,25 @@ export const treeDataList = [
// { label: '共享工作区', businessId: 3 },
// { label: '共享工作区', businessId: 3 },
// { label: '商城工作区', businessId: 4 },
// { label: '商城工作区', businessId: 4 },
// { label: '指标工作区', businessId: 5 },
// { label: '指标工作区', businessId: 5 },
}
}
,
],
],
},
},
];
];
export
const
treeDataListTwo
=
[
export
const
treeDataListTwo
=
[
{
{
name
:
'
预置
函数'
,
name
:
'函数'
,
selectedDeptId
:
2
1
,
selectedDeptId
:
1
,
children
:
[
children
:
[
{
}
{
]
,
name
:
'预置函数'
,
}
,
selectedDeptId
:
21
,
{
children
:
[{
selectedDeptId
:
23
}],
name
:
'自定义函数'
,
}
,
selectedDeptId
:
22
,
{
children
:
[
name
:
'自定义函数'
,
{
selectedDeptId
:
23
}
,
selectedDeptId
:
22
,
{
selectedDeptId
:
24
}
,
children
:
[{
selectedDeptId
:
24
},
{
selectedDeptId
:
25
}]
,
{
selectedDeptId
:
25
},
},
],
],
},
},
];
];
src/views/scriptDevelopment/selfServiceTableCreation/index.vue
View file @
4c1f1ce0
...
@@ -19,9 +19,13 @@
...
@@ -19,9 +19,13 @@
<a-button
style=
"margin-left: 500px"
type=
"primary"
@
click=
"handleMove(0)"
>
复制到
</a-button>
<a-button
style=
"margin-left: 500px"
type=
"primary"
@
click=
"handleMove(0)"
>
复制到
</a-button>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleDeleteIds"
>
删除
</a-button>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleDeleteIds"
>
删除
</a-button>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleMove(1)"
>
移动
</a-button>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleMove(1)"
>
移动
</a-button>
<a-button
style=
"margin-left: 10px"
type=
"primary"
>
导出
</a-button>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleExport('文件')"
<a-button
style=
"margin-left: 10px"
type=
"primary"
>
导出模版
</a-button>
>
导出
</a-button
<a-button
style=
"margin-left: 10px"
type=
"primary"
>
导入
</a-button>
>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleExport('模板')"
>
导出模版
</a-button
>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleImport"
>
导入
</a-button>
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleNewFolder"
<a-button
style=
"margin-left: 10px"
type=
"primary"
@
click=
"handleNewFolder"
>
新建文件夹
</a-button
>
新建文件夹
</a-button
>
>
...
@@ -69,6 +73,7 @@
...
@@ -69,6 +73,7 @@
<MoveFile
@
register=
"registerMoveFile"
/>
<MoveFile
@
register=
"registerMoveFile"
/>
<AddFile
@
register=
"registerAddFile"
/>
<AddFile
@
register=
"registerAddFile"
/>
<Rename
@
register=
"registerRename"
/>
<Rename
@
register=
"registerRename"
/>
<importModal
@
register=
"registerImport"
/>
</PageWrapper>
</PageWrapper>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
...
@@ -85,6 +90,9 @@
...
@@ -85,6 +90,9 @@
import
AddFile
from
'./addFile.vue'
;
import
AddFile
from
'./addFile.vue'
;
import
Rename
from
'./renameModal.vue'
;
import
Rename
from
'./renameModal.vue'
;
import
Icon
from
'@/components/Icon/Icon.vue'
;
import
Icon
from
'@/components/Icon/Icon.vue'
;
import
{
exportRoleList
}
from
'@/api/system/role/role'
;
import
{
downloadByData
}
from
'@/utils/file/download'
;
import
importModal
from
'@/views/scriptDevelopment/sqlDevelopment/importModal/importModal.vue'
;
defineOptions
({
name
:
'AccountManagement'
});
defineOptions
({
name
:
'AccountManagement'
});
...
@@ -96,6 +104,7 @@
...
@@ -96,6 +104,7 @@
const
[
registerMoveFile
,
{
openModal
:
openMoveFileModal
}]
=
useModal
();
const
[
registerMoveFile
,
{
openModal
:
openMoveFileModal
}]
=
useModal
();
const
[
registerAddFile
,
{
openModal
:
openAddFileModal
}]
=
useModal
();
const
[
registerAddFile
,
{
openModal
:
openAddFileModal
}]
=
useModal
();
const
[
registerRename
,
{
openModal
:
openRenameModal
}]
=
useModal
();
const
[
registerRename
,
{
openModal
:
openRenameModal
}]
=
useModal
();
const
[
registerImport
,
{
openModal
:
openImportModal
}]
=
useModal
();
// 选中的部门ID
// 选中的部门ID
const
selectedDeptId
=
ref
<
string
|
null
>
(
null
);
const
selectedDeptId
=
ref
<
string
|
null
>
(
null
);
...
@@ -176,6 +185,18 @@
...
@@ -176,6 +185,18 @@
title
:
'重命名'
,
title
:
'重命名'
,
});
});
}
}
/** 导出按钮*/
async
function
handleExport
(
name
)
{
console
.
log
(
'导出----'
);
const
params
=
Object
.
assign
({});
const
data
=
await
exportRoleList
(
params
);
downloadByData
(
data
,
name
+
'.xlsx'
);
}
/** 导入按钮*/
function
handleImport
()
{
openImportModal
(
true
,
{});
}
// 处理选择节点事件
// 处理选择节点事件
const
handleSelect
=
(
deptId
)
=>
{
const
handleSelect
=
(
deptId
)
=>
{
selectedDeptId
.
value
=
deptId
;
selectedDeptId
.
value
=
deptId
;
...
...
src/views/scriptDevelopment/selfServiceTableCreation/mock.ts
View file @
4c1f1ce0
...
@@ -19,6 +19,36 @@ export const tableList: any[] = [
...
@@ -19,6 +19,36 @@ export const tableList: any[] = [
'CLUSTERED BY (`ID`) INTO 3 BUCKETS
\
n'
+
'CLUSTERED BY (`ID`) INTO 3 BUCKETS
\
n'
+
'STORED AS ORC;'
,
'STORED AS ORC;'
,
},
},
{
selectedDeptId
:
24
,
name
:
'text1'
,
database
:
'customerdb'
,
tableType
:
'ORC'
,
creationTime
:
'2019/11/17 10:34:48'
,
updateTime
:
'2019/11/17 11:17:00'
,
owner
:
'admin'
,
sql
:
'CREATE TABLE `customerdb.customertable`{
\
n'
+
' `ID` STRING COMMENT `用户ID`NOT NULL,
\
n'
+
' `name` VARCHAR(255) COMMENT `姓名`,
\
n'
+
'} COMMENT `客户信息表`
\
n'
+
'PARTITIONED BY RANGE {
\
n'
+
' `email` VARCHAR(255),
\
n'
+
'}
\
n'
+
'CLUSTERED BY (`ID`) INTO 3 BUCKETS
\
n'
+
'STORED AS ORC;'
,
},
{
selectedDeptId
:
25
,
name
:
'text2'
,
database
:
'customerdb'
,
tableType
:
'ORC'
,
creationTime
:
'2019/11/17 10:34:48'
,
updateTime
:
'2019/11/17 11:17:00'
,
owner
:
'admin'
,
sql
:
'CREATE TABLE `customerdb.customertable`{
\
n'
+
' `ID` STRING COMMENT `用户ID`NOT NULL,
\
n'
,
},
];
];
export
const
fieldConfigurationList
:
any
[]
=
[
export
const
fieldConfigurationList
:
any
[]
=
[
...
@@ -49,7 +79,7 @@ export const treeDataList = [
...
@@ -49,7 +79,7 @@ export const treeDataList = [
{
{
name
:
'自助建表文件'
,
name
:
'自助建表文件'
,
selectedDeptId
:
21
,
selectedDeptId
:
21
,
children
:
[{
selectedDeptId
:
23
}],
children
:
[{
selectedDeptId
:
23
}
,
{
selectedDeptId
:
24
},
{
selectedDeptId
:
25
}
],
},
},
];
];
export
const
TreeData
:
any
[]
=
[
export
const
TreeData
:
any
[]
=
[
...
...
src/views/scriptDevelopment/sqlDevelopment/importModal/importModal.vue
View file @
4c1f1ce0
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
import
{
BasicModal
,
useModalInner
}
from
'@/components/Modal'
;
import
{
BasicModal
,
useModalInner
}
from
'@/components/Modal'
;
import
{
BasicForm
,
useForm
}
from
'@/components/Form'
;
import
{
BasicForm
,
useForm
}
from
'@/components/Form'
;
import
{
importFormSchema
}
from
'./tempalte.data'
;
import
{
importFormSchema
}
from
'./tempalte.data'
;
import
{
onMountedOrActivated
}
from
"@vben/hooks"
;
const
emit
=
defineEmits
([
'success'
,
'register'
]);
const
emit
=
defineEmits
([
'success'
,
'register'
]);
const
isUpdate
=
ref
(
true
);
const
isUpdate
=
ref
(
true
);
...
@@ -61,7 +60,6 @@
...
@@ -61,7 +60,6 @@
// onMounted(){}
// onMounted(){}
// const getTitle = computed(() => '新建文件');
// const getTitle = computed(() => '新建文件');
const
getTitle
=
'导入文件选择'
;
const
getTitle
=
'导入文件选择'
;
...
...
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