Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
H
hg-smart
Overview
Overview
Details
Activity
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
platform
hg-smart
Commits
89227ed8
Commit
89227ed8
authored
Sep 24, 2024
by
宋祥
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev-sx' of
http://git.pseer.com:8800/platform/hg-smart
into dev
parents
2a121af0
c70c4a72
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
201 additions
and
57 deletions
+201
-57
ServiceHGWD003.java
.../java/com/baosight/hggp/hg/wd/service/ServiceHGWD003.java
+5
-1
ServiceHGWD003A.java
...java/com/baosight/hggp/hg/wd/service/ServiceHGWD003A.java
+3
-10
ServiceHGWD003B.java
...java/com/baosight/hggp/hg/wd/service/ServiceHGWD003B.java
+10
-1
HGWD001.xml
src/main/java/com/baosight/hggp/hg/wd/sql/HGWD001.xml
+8
-2
HGWDTools.java
src/main/java/com/baosight/hggp/hg/wd/tools/HGWDTools.java
+26
-3
HgWdUtils.java
src/main/java/com/baosight/hggp/hg/wd/utils/HgWdUtils.java
+47
-5
FileUtils.java
src/main/java/com/baosight/hggp/util/FileUtils.java
+4
-0
HGWD002A.js
src/main/webapp/HG/WD/HGWD002A.js
+95
-12
HGWD002A.jsp
src/main/webapp/HG/WD/HGWD002A.jsp
+2
-22
HGWD003.js
src/main/webapp/HG/WD/HGWD003.js
+1
-1
No files found.
src/main/java/com/baosight/hggp/hg/wd/service/ServiceHGWD003.java
View file @
89227ed8
...
...
@@ -147,6 +147,8 @@ public class ServiceHGWD003 extends ServiceEPBase {
// 获取FILE_ID
String
fileId
=
MapUtils
.
getString
(
queryMap
,
HGWD003
.
FIELD_FILE_ID
);
AssertUtils
.
isEmpty
(
fileId
,
"请选择目录"
);
// 判断是否是管理员或项目经理
AssertUtils
.
isTrue
(!
HgWdUtils
.
HgWd003
.
isManager
(
fileId
),
"操作失败,非项目经理不能进行删除"
);
List
<
HGWD003
>
fWd003s
=
MapUtils
.
toDaoEPBases
(
inInfo
,
HGWD003
.
class
);
for
(
HGWD003
fWd003
:
fWd003s
)
{
fWd003
.
setDeleteFlag
(
DeleteFlagEnum
.
REMOVE
.
getCode
());
...
...
@@ -174,6 +176,8 @@ public class ServiceHGWD003 extends ServiceEPBase {
// 获取FILE_ID
String
fileId
=
MapUtils
.
getString
(
queryMap
,
HGWD003
.
FIELD_FILE_ID
);
AssertUtils
.
isEmpty
(
fileId
,
"请选择目录"
);
// 判断是否是管理员或项目经理
AssertUtils
.
isTrue
(!
HgWdUtils
.
HgWd009
.
isManager
(),
"操作失败,非管理员不能进行修改"
);
List
<
HGWD003
>
fWd003s
=
MapUtils
.
toDaoEPBases
(
inInfo
,
HGWD003
.
class
);
for
(
HGWD003
fWd003
:
fWd003s
)
{
DaoUtils
.
update
(
HgWdSqlConstant
.
HgWd003
.
UPDATE_INFO
,
fWd003
);
...
...
@@ -197,7 +201,7 @@ public class ServiceHGWD003 extends ServiceEPBase {
try
{
Map
queryMap
=
EiInfoUtils
.
getFirstRow
(
inInfo
);
// 文档管理员不做校验
if
(
HgWdUtils
.
HgWd009
.
isManager
(
UserSessionUtils
.
getLoginName
()
))
{
if
(
HgWdUtils
.
HgWd009
.
isManager
())
{
inInfo
.
set
(
"isManager"
,
CommonConstant
.
YesNo
.
YES_1
);
return
inInfo
;
}
else
{
...
...
src/main/java/com/baosight/hggp/hg/wd/service/ServiceHGWD003A.java
View file @
89227ed8
package
com
.
baosight
.
hggp
.
hg
.
wd
.
service
;
import
com.baosight.hggp.aspect.annotation.OperationLogAnnotation
;
import
com.baosight.hggp.core.constant.CommonConstant
;
import
com.baosight.hggp.core.dao.DaoUtils
;
import
com.baosight.hggp.hg.pz.domain.HGPZ016
;
import
com.baosight.hggp.hg.sc.domain.HGSC001
;
import
com.baosight.hggp.hg.wd.domain.HGWD001
;
import
com.baosight.hggp.hg.wd.domain.HGWD002
;
import
com.baosight.hggp.hg.wd.domain.HGWD003
;
import
com.baosight.hggp.hg.wd.utils.HgWdUtils
;
import
com.baosight.hggp.hg.xs.domain.User
;
import
com.baosight.hggp.util.AssertUtils
;
import
com.baosight.hggp.util.EiInfoUtils
;
import
com.baosight.hggp.util.LogUtils
;
import
com.baosight.hggp.util.MapUtils
;
import
com.baosight.hggp.util.StringUtil
;
import
com.baosight.iplat4j.core.ei.EiBlockMeta
;
import
com.baosight.iplat4j.core.ei.EiConstant
;
import
com.baosight.iplat4j.core.ei.EiInfo
;
import
com.baosight.iplat4j.core.service.impl.ServiceEPBase
;
import
org.apache.commons.collections.CollectionUtils
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -77,6 +68,8 @@ public class ServiceHGWD003A extends ServiceEPBase {
// 获取FILE_ID
String
fileId
=
MapUtils
.
getString
(
queryMap
,
HGWD003
.
FIELD_FILE_ID
);
AssertUtils
.
isEmpty
(
fileId
,
"请选择目录"
);
// 判断是否是管理员或项目经理
AssertUtils
.
isTrue
(!
HgWdUtils
.
HgWd003
.
isManager
(
fileId
),
"操作失败,非项目经理不能授权人员"
);
List
<
HGWD003
>
fWd003s
=
MapUtils
.
toDaoEPBases
(
inInfo
,
HGWD003
.
class
);
for
(
HGWD003
fWd003
:
fWd003s
)
{
fWd003
.
setFileId
(
fileId
);
...
...
src/main/java/com/baosight/hggp/hg/wd/service/ServiceHGWD003B.java
View file @
89227ed8
...
...
@@ -2,10 +2,12 @@ package com.baosight.hggp.hg.wd.service;
import
com.baosight.hggp.aspect.annotation.OperationLogAnnotation
;
import
com.baosight.hggp.core.dao.DaoUtils
;
import
com.baosight.hggp.core.security.UserSessionUtils
;
import
com.baosight.hggp.hg.wd.constant.HgWdSqlConstant
;
import
com.baosight.hggp.hg.wd.domain.HGWD001
;
import
com.baosight.hggp.hg.wd.domain.HGWD003
;
import
com.baosight.hggp.hg.wd.tools.HGWDTools
;
import
com.baosight.hggp.hg.wd.utils.HgWdUtils
;
import
com.baosight.hggp.util.AssertUtils
;
import
com.baosight.hggp.util.EiInfoUtils
;
import
com.baosight.hggp.util.LogUtils
;
...
...
@@ -47,7 +49,7 @@ public class ServiceHGWD003B extends ServiceEPBase {
}
/**
*
树节点
查询
* 查询
*
* @param inInfo
* @return
...
...
@@ -55,6 +57,11 @@ public class ServiceHGWD003B extends ServiceEPBase {
public
EiInfo
query
(
EiInfo
inInfo
)
{
try
{
Map
queryMap
=
EiInfoUtils
.
getFirstRow
(
inInfo
);
// 仅查询自己是项目经理的目录
String
userId
=
UserSessionUtils
.
getLoginName
();
if
(!
HgWdUtils
.
HgWd009
.
isManager
(
userId
))
{
queryMap
.
put
(
"managerUserId"
,
userId
);
}
inInfo
=
super
.
query
(
inInfo
,
HGWD001
.
QUERY
,
new
HGWD001
());
}
catch
(
Exception
e
)
{
LogUtils
.
setMsg
(
inInfo
,
e
,
"查询节点失败"
);
...
...
@@ -74,6 +81,8 @@ public class ServiceHGWD003B extends ServiceEPBase {
Map
queryMap
=
EiInfoUtils
.
getFirstRow
(
inInfo
);
// 获取FILE_ID信息
String
mainFileId
=
MapUtils
.
getString
(
queryMap
,
"mainFileId"
);
// 判断是否是管理员或项目经理
AssertUtils
.
isTrue
(!
HgWdUtils
.
HgWd009
.
isManager
(),
"操作失败,非管理员不能进行复制"
);
HGWD001
dbWd001
=
HGWDTools
.
HgWd001
.
get
(
mainFileId
);
AssertUtils
.
isNull
(
dbWd001
,
String
.
format
(
"【%s】文档目录不存在"
,
mainFileId
));
// 获取FILE_ID授权信息
...
...
src/main/java/com/baosight/hggp/hg/wd/sql/HGWD001.xml
View file @
89227ed8
...
...
@@ -31,6 +31,7 @@
<sql
id=
"condition"
>
AND DELETE_FLAG = 0
<include
refid=
"HGXSDataAuth.authCondition"
/>
<include
refid=
"customCondition"
/>
<isNotEmpty
prepend=
" AND "
property=
"id"
>
ID = #id#
</isNotEmpty>
...
...
@@ -106,6 +107,11 @@
<isNotEmpty
prepend=
" AND "
property=
"parentIds"
>
PARENT_ID IN
<iterate
close=
")"
open=
"("
conjunction=
","
property=
"parentIds"
>
#parentIds[]#
</iterate>
</isNotEmpty>
<isNotEmpty
prepend=
" AND "
property=
"managerUserId"
>
EXISTS (SELECT FILE_ID FROM ${hggpSchema}.HGWD003 M WHERE T.FILE_ID = M.FILE_ID
AND M.USER_ID = #managerUserId#
AND M.IS_PROJECT_MANAGER = 1)
</isNotEmpty>
</sql>
<sql
id=
"orderBy"
>
...
...
@@ -122,14 +128,14 @@
<select
id=
"query"
resultClass=
"com.baosight.hggp.hg.wd.domain.HGWD001"
>
SELECT
<include
refid=
"column"
/>
FROM ${hggpSchema}.HGWD001
FROM ${hggpSchema}.HGWD001
T
WHERE 1=1
<include
refid=
"condition"
/>
<include
refid=
"orderBy"
/>
</select>
<select
id=
"count"
resultClass=
"int"
>
SELECT COUNT(*) FROM ${hggpSchema}.HGWD001
SELECT COUNT(*) FROM ${hggpSchema}.HGWD001
T
WHERE 1=1
<include
refid=
"condition"
/>
</select>
...
...
src/main/java/com/baosight/hggp/hg/wd/tools/HGWDTools.java
View file @
89227ed8
...
...
@@ -5,8 +5,6 @@ import com.baosight.hggp.core.dao.DaoUtils;
import
com.baosight.hggp.core.extapp.decheng.api.DcOpenApi
;
import
com.baosight.hggp.core.security.UserSessionUtils
;
import
com.baosight.hggp.hg.cw.domain.HGCW999
;
import
com.baosight.hggp.hg.sc.constant.HgScSqlConstant
;
import
com.baosight.hggp.hg.sc.domain.HGSC001
;
import
com.baosight.hggp.hg.wd.constant.HgWdSqlConstant
;
import
com.baosight.hggp.hg.wd.domain.HGWD001
;
import
com.baosight.hggp.hg.wd.domain.HGWD001A
;
...
...
@@ -21,7 +19,10 @@ import com.baosight.hggp.util.ObjectUtils;
import
org.apache.commons.collections.CollectionUtils
;
import
java.io.IOException
;
import
java.util.*
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.stream.Collectors
;
/**
...
...
@@ -181,6 +182,20 @@ public class HGWDTools {
public
static
class
HgWd003
{
/**
* 查询
*
* @param fileId
*/
public
static
HGWD003
getByUser
(
String
fileId
)
{
AssertUtils
.
isEmpty
(
fileId
,
"文件ID不能为空"
);
Map
queryMap
=
new
HashMap
();
queryMap
.
put
(
HGWD003
.
FIELD_FILE_ID
,
fileId
);
queryMap
.
put
(
HGWD003
.
FIELD_USER_ID
,
UserSessionUtils
.
getLoginName
());
List
<
HGWD003
>
results
=
DaoBase
.
getInstance
().
query
(
HgWdSqlConstant
.
HgWd003
.
GET_BY_USER
,
queryMap
);
return
CollectionUtils
.
isEmpty
(
results
)
?
null
:
results
.
get
(
0
);
}
/**
* @param fileId
* @return
*/
...
...
@@ -307,6 +322,14 @@ public class HGWDTools {
/**
* 查询
*
*/
public
static
HGWD009
getByUser
()
{
return
getByUser
(
UserSessionUtils
.
getLoginName
());
}
/**
* 查询
*
* @param userId
*/
public
static
HGWD009
getByUser
(
String
userId
)
{
...
...
src/main/java/com/baosight/hggp/hg/wd/utils/HgWdUtils.java
View file @
89227ed8
package
com
.
baosight
.
hggp
.
hg
.
wd
.
utils
;
import
com.baosight.hggp.hg.wd.domain.HGWD009
;
import
com.baosight.hggp.core.constant.CommonConstant
;
import
com.baosight.hggp.hg.wd.domain.HGWD003
;
import
com.baosight.hggp.hg.wd.tools.HGWDTools
;
/**
...
...
@@ -13,19 +14,60 @@ public class HgWdUtils {
* @author:songx
* @date:2024/8/19,14:57
*/
public
static
class
HgWd003
{
/**
* 是否项目经理
*
* @param fileId
* @return
*/
public
static
boolean
isProjectManager
(
String
fileId
)
{
HGWD003
dbWd003
=
HGWDTools
.
HgWd003
.
getByUser
(
fileId
);
if
(
dbWd003
==
null
)
{
return
false
;
}
return
CommonConstant
.
YesNo
.
YES_1
.
equals
(
dbWd003
.
getIsProjectManager
());
}
/**
* 是否项目经理或管理员
*
* @param fileId
* @return
*/
public
static
boolean
isManager
(
String
fileId
)
{
if
(
isProjectManager
(
fileId
))
{
return
true
;
}
return
HgWd009
.
isManager
();
}
}
/**
* @author:songx
* @date:2024/8/19,14:57
*/
public
static
class
HgWd009
{
/**
* 是否管理员
*
* @param userId
* @return
*/
public
static
boolean
isManager
(
String
userId
)
{
HGWD009
dbWd009
=
HGWDTools
.
HgWd009
.
getByUser
(
userId
);
return
dbWd009
!=
null
;
public
static
boolean
isManager
()
{
return
HGWDTools
.
HgWd009
.
getByUser
()
!=
null
;
}
/**
* 是否管理员
*
* @return
*/
public
static
boolean
isManager
(
String
userId
)
{
return
HGWDTools
.
HgWd009
.
getByUser
(
userId
)
!=
null
;
}
}
}
src/main/java/com/baosight/hggp/util/FileUtils.java
View file @
89227ed8
...
...
@@ -561,6 +561,10 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
response
.
setContentType
(
"application/pdf"
);
response
.
setHeader
(
"Content-Disposition"
,
"inline; filename="
+
URLEncoder
.
encode
(
fileName
,
"UTF-8"
));
}
else
if
(
"txt"
.
contains
(
fileType
))
{
response
.
setContentType
(
"text/plain; charset=UTF-8"
);
response
.
setHeader
(
"Content-Disposition"
,
"inline; filename="
+
URLEncoder
.
encode
(
fileName
,
"UTF-8"
));
}
else
{
response
.
setContentType
(
"application/octet-stream;charset=UTF-8"
);
response
.
setHeader
(
"Content-Disposition"
,
"attachment;filename="
...
...
src/main/webapp/HG/WD/HGWD002A.js
View file @
89227ed8
...
...
@@ -51,6 +51,7 @@ $(function () {
* 页面加载完后执行
*/
$
(
window
).
load
(
function
()
{
// 鼠标滚动
imageMouseListener
();
});
...
...
@@ -58,7 +59,7 @@ $(window).load(function () {
* 图片鼠标事件监听
*/
function
imageMouseListener
()
{
document
.
getElementById
(
'image'
).
addEventListener
(
'mousewheel'
,
function
(
event
)
{
document
.
getElementById
(
'image
Container
'
).
addEventListener
(
'mousewheel'
,
function
(
event
)
{
var
scale
=
event
.
wheelDelta
/
1000
;
var
newScale
=
Math
.
max
(
Math
.
min
(
this
.
scale
||
1
,
3
),
0.1
);
newScale
+=
scale
;
...
...
@@ -68,14 +69,6 @@ function imageMouseListener() {
});
}
function
zoomImage
(
scale
)
{
var
img
=
document
.
getElementById
(
'image'
);
var
width
=
img
.
naturalWidth
*
(
scale
/
100
);
var
height
=
img
.
naturalHeight
*
(
scale
/
100
);
img
.
style
.
width
=
width
+
'px'
;
img
.
style
.
height
=
height
+
'px'
;
}
/**
* 批量展开树节点
*
...
...
@@ -115,19 +108,25 @@ function add(docId, leafType, docType) {
otherDownload
(
true
,
null
);
return
;
}
IPLAT
.
progress
(
$
(
"body"
),
true
);
let
inInfo
=
new
EiInfo
();
inInfo
.
set
(
"result-0-fileId"
,
$
(
"#inqu_status-0-fileId"
).
val
());
inInfo
.
set
(
"result-0-docId"
,
docId
);
EiCommunicator
.
send
(
'HGWD001B'
,
'add'
,
inInfo
,
{
onSuccess
:
function
(
res
)
{
if
(
res
.
getStatus
()
>=
0
)
{
preview
(
docId
,
docType
);
try
{
preview
(
docId
,
docType
);
}
catch
(
e
)
{
}
}
else
{
message
(
res
.
getMsg
());
}
IPLAT
.
progress
(
$
(
"body"
),
false
);
},
onFail
:
function
(
res
)
{
NotificationUtil
(
"操作失败,原因["
+
res
.
getMsg
()
+
"]"
,
"error"
);
IPLAT
.
progress
(
$
(
"body"
),
false
);
}
});
}
...
...
@@ -141,10 +140,14 @@ function add(docId, leafType, docType) {
function
preview
(
docId
,
docType
)
{
// 隐藏文本描述
$
(
"#descDiv"
).
css
(
'display'
,
'none'
);
if
(
"docx"
==
docType
)
{
if
(
isText
(
docType
))
{
previewText
(
docId
);
}
else
if
(
isExcel
(
docType
))
{
previewExcel
(
docId
);
}
else
if
(
isWord
(
docType
))
{
previewDocx
(
docId
);
}
else
if
(
isImage
(
docType
))
{
preview
Imag
e
(
docId
);
preview
Fram
e
(
docId
);
}
else
if
(
isFrame
(
docType
))
{
previewFrame
(
docId
);
}
else
{
...
...
@@ -158,7 +161,87 @@ function preview(docId, docType) {
function
hideHtml
()
{
$
(
"#docxContainer"
).
css
(
'display'
,
'none'
);
$
(
"#imageContainer"
).
css
(
'display'
,
'none'
);
$
(
"#image"
).
attr
(
'src'
,
""
);
$
(
"#previewFrame"
).
css
(
'display'
,
'none'
);
$
(
"#previewFrame"
).
attr
(
"src"
,
""
);
}
/**
* 是否文本
*
* @param fileName
* @returns {boolean}
*/
function
isText
(
docType
)
{
if
(
isBlank
(
docType
))
{
return
false
;
}
const
extensions
=
[
'txt'
];
return
extensions
.
includes
(
docType
.
toLowerCase
());
}
/**
* 文件预览
*
* @param docId
*/
function
previewText
(
docId
)
{
fetch
(
downloadHref
(
docId
,
true
)).
then
(
res
=>
{
return
res
.
arrayBuffer
();
}).
then
(
arrayBuffer
=>
{
let
container
=
document
.
getElementById
(
"descDiv"
);
container
.
style
.
display
=
'block'
;
// 使用new TextDecoder()指定编码
const
utf8Decoder
=
new
TextDecoder
(
'GBK'
,
{
ignoreBOM
:
true
});
const
decodedText
=
utf8Decoder
.
decode
(
arrayBuffer
);
$
(
"#descSpan"
).
html
(
decodedText
.
replace
(
/
\r\n?
/g
,
'
\
n'
).
replace
(
/
\n
/g
,
'<br/>'
));
});
}
/**
* 是否excel
*
* @param fileName
* @returns {boolean}
*/
function
isExcel
(
docType
)
{
if
(
isBlank
(
docType
))
{
return
false
;
}
const
extensions
=
[
'xls'
,
'xlsx'
];
return
extensions
.
includes
(
docType
.
toLowerCase
());
}
/**
* 文件预览
*
* @param docId
*/
function
previewExcel
(
docId
)
{
fetch
(
downloadHref
(
docId
,
true
)).
then
(
res
=>
{
return
res
.
text
();
}).
then
(
text
=>
{
let
container
=
document
.
getElementById
(
"descDiv"
);
container
.
style
.
display
=
'block'
;
// 使用new TextDecoder()指定编码
const
utf8Decoder
=
new
TextDecoder
(
'GBK'
,
{
ignoreBOM
:
true
});
const
decodedText
=
utf8Decoder
.
decode
(
arrayBuffer
);
$
(
"#descSpan"
).
html
(
decodedText
.
replace
(
/
\r\n?
/g
,
'
\
n'
).
replace
(
/
\n
/g
,
'<br/>'
));
});
}
/**
* 是否WORD
*
* @param fileName
* @returns {boolean}
*/
function
isWord
(
docType
)
{
if
(
isBlank
(
docType
))
{
return
false
;
}
const
extensions
=
[
'docx'
];
return
extensions
.
includes
(
docType
.
toLowerCase
());
}
/**
...
...
src/main/webapp/HG/WD/HGWD002A.jsp
View file @
89227ed8
...
...
@@ -9,8 +9,8 @@
<script
src=
"${ctx}/common/docxjs/docx-preview.js"
></script>
<style>
.left-flex
{
display
:
flex
;
align-items
:
center
;
/*display: flex;*/
/*align-items: flex-start;*/
height
:
100%
;
width
:
100%
;
overflow
:
scroll
;
...
...
@@ -31,22 +31,6 @@
border
:
0px
;
}
.imageContainer
{
display
:
flex
;
flex-direction
:
column
;
height
:
100%
;
}
.wide-div
{
flex
:
1
;
flex-basis
:
90%
;
overflow
:
scroll
;
}
.narrow-div
{
flex
:
0
0
10%
;
}
img
{
max-width
:
100%
;
max-height
:
100%
;
...
...
@@ -58,10 +42,6 @@
cursor
:
zoom-out
;
}
.zoom-slider
{
width
:
100%
;
margin-top
:
10px
;
}
</style>
<EF:EFPage
title=
"文件预览"
>
<div
class=
"row"
style=
"margin: 0 -10px;"
>
...
...
src/main/webapp/HG/WD/HGWD003.js
View file @
89227ed8
...
...
@@ -264,7 +264,7 @@ let showAuthButton = function () {
}
else
if
(
status
>=
0
&&
res
.
extAttr
.
isProjectManager
==
1
)
{
$
(
"#AUTH"
).
show
();
$
(
"#REMOVE_USER"
).
show
();
$
(
"#COPY_USER"
).
hide
();
$
(
"#COPY_USER"
).
show
();
$
(
"#SAVE"
).
hide
();
}
else
{
$
(
"#AUTH"
).
hide
();
...
...
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