Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Springboot Plus
Commits
143d37ee
"vscode:/vscode.git/clone" did not exist on "b08d349b45605e464c83ae7ca748355a35297f10"
Commit
143d37ee
authored
Nov 27, 2021
by
trumansdo
Browse files
更换至beetlsql3最新版本
parent
398a4c6b
Changes
170
Hide whitespace changes
Inline
Side-by-side
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/beetl/resultmap/GridMapping.java
View file @
143d37ee
...
...
@@ -3,12 +3,10 @@ package com.ibeetl.admin.core.conf.beetl.resultmap;
import
static
cn
.
hutool
.
core
.
util
.
StrUtil
.
EMPTY
;
import
static
java
.
util
.
Optional
.
ofNullable
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.json.JSON
;
import
cn.hutool.json.JSONUtil
;
import
java.io.Serializable
;
import
java.util.List
;
import
java.util.Map
;
/** 网格映射数据结构: 包含一个网格头 {@link GridHeader}和一个虚拟网格单元格 */
...
...
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/jackson/serializer/CustomJsonResultSerializer.java
View file @
143d37ee
...
...
@@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.JsonSerializer;
import
com.fasterxml.jackson.databind.SerializerProvider
;
import
com.ibeetl.admin.core.web.JsonResult
;
import
java.io.IOException
;
import
org.beetl.sql.core.
engin
e.Page
Query
;
import
org.beetl.sql.core.
pag
e.Page
Result
;
/**
* layui 前端要求后台返回的数据格式
...
...
@@ -14,18 +14,21 @@ import org.beetl.sql.core.engine.PageQuery;
*/
public
class
CustomJsonResultSerializer
extends
JsonSerializer
<
JsonResult
>
{
public
CustomJsonResultSerializer
()
{}
public
CustomJsonResultSerializer
()
{
}
/** 处理 JsonResult 返回结果。自动分离分页信息,不需要手动在controller中分离 */
@Override
public
void
serialize
(
JsonResult
value
,
JsonGenerator
gen
,
SerializerProvider
serializers
)
throws
IOException
{
gen
.
writeStartObject
();
gen
.
writeObjectField
(
"code"
,
Integer
.
parseInt
(
value
.
getCode
()));
gen
.
writeStringField
(
"message"
,
value
.
getMessage
());
Object
data
=
value
.
getData
();
if
(
data
instanceof
Page
Query
)
{
Page
Query
query
=
(
Page
Query
)
(
data
);
if
(
data
instanceof
Page
Result
)
{
Page
Result
query
=
(
Page
Result
)
(
data
);
/*不同js前端插件会有不一样数据格式,所以返回两种命名*/
gen
.
writeNumberField
(
"count"
,
query
.
getTotalRow
());
gen
.
writeNumberField
(
"total"
,
query
.
getTotalRow
());
...
...
@@ -35,4 +38,5 @@ public class CustomJsonResultSerializer extends JsonSerializer<JsonResult> {
}
gen
.
writeEndObject
();
}
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/jackson/serializer/DictTypeEnumDeserializer.java
View file @
143d37ee
package
com.ibeetl.admin.core.conf.jackson.serializer
;
import
cn.hutool.core.util.ReflectUtil
;
import
com.fasterxml.jackson.core.JsonGenerator
;
import
com.fasterxml.jackson.core.JsonParser
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.databind.DeserializationContext
;
import
com.fasterxml.jackson.databind.JsonDeserializer
;
import
com.fasterxml.jackson.databind.JsonSerializer
;
import
com.fasterxml.jackson.databind.SerializerProvider
;
import
com.ibeetl.admin.core.util.enums.DictTypeEnum
;
import
java.io.IOException
;
...
...
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/springmvc/interceptor/HttpRequestInterceptor.java
View file @
143d37ee
package
com.ibeetl.admin.core.conf.springmvc.interceptor
;
import
com.ibeetl.admin.core.util.
Http
RequestLocal
;
import
com.ibeetl.admin.core.util.Request
ContextThread
Local
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.springframework.web.servlet.HandlerInterceptor
;
...
...
@@ -10,13 +10,13 @@ public class HttpRequestInterceptor implements HandlerInterceptor {
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
{
Http
RequestLocal
.
set
(
request
);
Request
ContextThread
Local
.
set
Request
(
request
);
return
true
;
}
@Override
public
void
afterCompletion
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
,
Exception
ex
)
{
Http
RequestLocal
.
destory
();
Request
ContextThread
Local
.
destory
();
}
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/springmvc/interceptor/SessionInterceptor.java
View file @
143d37ee
package
com.ibeetl.admin.core.conf.springmvc.interceptor
;
import
com.ibeetl.admin.core.service.CoreUserService
;
import
com.ibeetl.admin.core.util.
Http
RequestLocal
;
import
com.ibeetl.admin.core.util.Request
ContextThread
Local
;
import
com.ibeetl.admin.core.util.JoseJwtUtil
;
import
java.util.Map
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.web.servlet.HandlerInterceptor
;
public
class
SessionInterceptor
implements
HandlerInterceptor
{
...
...
@@ -19,13 +21,16 @@ public class SessionInterceptor implements HandlerInterceptor {
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
{
String
token
=
Http
RequestLocal
.
getAuthorization
();
String
token
=
Request
ContextThread
Local
.
getAuthorization
();
boolean
isExpiration
=
JoseJwtUtil
.
verifyJwtJson
(
token
);
if
(
isExpiration
)
{
/*验证失败,无效jwt*/
response
.
setStatus
(
HttpStatus
.
UNAUTHORIZED
.
value
());
return
false
;
}
else
{
token
=
JoseJwtUtil
.
refreshIssuedAtTime
(
token
);
Map
<
String
,
Object
>
claimsMap
=
JoseJwtUtil
.
parsePayload
(
token
);
RequestContextThreadLocal
.
reset
(
claimsMap
.
get
(
"uid"
));
response
.
setHeader
(
HttpHeaders
.
AUTHORIZATION
,
token
);
}
return
true
;
...
...
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreAuditDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreAudit
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
/*
*
* gen by starter mapper 2017-08-01
*/
@SqlResource
(
"core.coreAudit"
)
public
interface
CoreAuditDao
extends
BaseMapper
<
CoreAudit
>
{}
public
interface
CoreAuditDao
extends
BaseMapper
<
CoreAudit
>
{
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreDictDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
com.ibeetl.admin.core.entity.CoreDict
;
import
com.ibeetl.admin.core.entity.DictType
;
import
java.util.List
;
import
java.util.Map
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.annotatoin.SqlStatement
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreDict
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
/** 字典DAO接口 */
@SqlResource
(
"core.coreDict"
)
...
...
@@ -17,8 +14,8 @@ public interface CoreDictDao extends BaseMapper<CoreDict> {
/**
* 查询某个类型下的字典集合
*
* @param type
字典类型
*
@return
* @param type
*
字典类型
*/
List
<
CoreDict
>
findAllList
(
String
type
);
...
...
@@ -26,27 +23,27 @@ public interface CoreDictDao extends BaseMapper<CoreDict> {
* 查询某个类型下的字典集合<br/>
* 主要用于提供给前端的下拉选择菜单使用,业务上请使用返回值为{@link CoreDict}的方法
*
* @param type
字典类型
*
@return
* @param type
*
字典类型
*/
List
<
DictType
>
findAllDictType
(
String
type
);
/**
* 查询字段类型列表
*
* @param delFlag
删除标记
*
@return
* @param delFlag
*
删除标记
*/
@SqlStatement
(
returnType
=
Map
.
class
)
List
<
Map
<
String
,
String
>>
findTypeList
(
int
delFlag
);
/**
* 根据父节点Id查询子节点数据
*
* @param id
父节点id
*
@return
* @param id
*
父节点id
*/
List
<
CoreDict
>
findChildByParent
(
Long
id
);
int
bathDelByValue
(
List
<
String
>
values
);
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreFileDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
org.beetl.sql.core.annotatoin.Sql
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreFile
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.Sql
;
public
interface
CoreFileDao
extends
BaseMapper
<
CoreFile
>
{
@Sql
(
"update core_file set biz_type=?,biz_id=? where file_batch_id=?"
)
public
void
updateBatchIdInfo
(
String
bizType
,
String
bizId
,
String
fileBatchId
);
void
updateBatchIdInfo
(
String
bizType
,
String
bizId
,
String
fileBatchId
);
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreFunctionDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
com.ibeetl.admin.core.entity.CoreFunction
;
import
com.ibeetl.admin.core.entity.CoreRoute
;
import
java.util.List
;
import
org.beetl.sql.core.annotatoin.Param
;
import
org.beetl.sql.core.annotatoin.Sql
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreFunction
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.Param
;
import
org.beetl.sql.mapper.annotation.Sql
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
@SqlResource
(
"core.coreFunction"
)
public
interface
CoreFunctionDao
extends
BaseMapper
<
CoreFunction
>
{
@Sql
(
"select * from core_function where code = ?"
)
CoreFunction
getFunctionByCode
(
@Param
(
value
=
"code"
)
String
code
);
List
<
CoreRoute
>
getAllRoutes
();
List
<
CoreRoute
>
getAllRoutes
(
@Param
(
value
=
"roleIds"
)
List
<
Long
>
roleIds
);
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreMenuDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
org.beetl.sql.core.annotatoin.Param
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.annotatoin.SqlStatement
;
import
org.beetl.sql.core.engine.PageQuery
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreMenu
;
import
java.util.List
;
import
org.beetl.sql.core.page.PageRequest
;
import
org.beetl.sql.core.page.PageResult
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
@SqlResource
(
"core.coreMenu"
)
public
interface
CoreMenuDao
extends
BaseMapper
<
CoreMenu
>
{
public
void
queryByCondtion
(
PageQuery
query
);
PageResult
queryByCondtion
(
PageRequest
query
);
void
clearMenuFunction
(
List
<
Long
>
functionIds
);
public
void
clearMenuFunction
(
List
<
Long
>
functionIds
);
List
<
CoreMenu
>
allMenuWithURL
(
);
public
List
<
CoreMenu
>
allMenuWithURL
();
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreOrgDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
java.util.List
;
import
org.beetl.sql.core.annotatoin.Sql
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreOrg
;
import
java.util.List
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.Sql
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
@SqlResource
(
"core.coreOrg"
)
public
interface
CoreOrgDao
extends
BaseMapper
<
CoreOrg
>
{
...
...
@@ -17,4 +15,5 @@ public interface CoreOrgDao extends BaseMapper<CoreOrg> {
@Sql
(
"select * from core_org where parent_org_id=0"
)
CoreOrg
getRoot
();
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreRoleDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
org.beetl.sql.core.annotatoin.Param
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.engine.PageQuery
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreRole
;
import
java.util.List
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.Param
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
@SqlResource
(
"core.coreRole"
)
public
interface
CoreRoleDao
extends
BaseMapper
<
CoreRole
>
{}
public
interface
CoreRoleDao
extends
BaseMapper
<
CoreRole
>
{
List
<
CoreRole
>
geRoles
(
@Param
(
"userId"
)
Long
userId
);
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreRoleFunctionDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
org.beetl.sql.core.annotatoin.Param
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.annotatoin.SqlStatement
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreRoleFunction
;
import
java.util.List
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
@SqlResource
(
"core.coreRoleFunction"
)
public
interface
CoreRoleFunctionDao
extends
BaseMapper
<
CoreRoleFunction
>
{
...
...
@@ -15,4 +12,5 @@ public interface CoreRoleFunctionDao extends BaseMapper<CoreRoleFunction> {
List
<
CoreRoleFunction
>
getRoleFunction
(
Long
userId
,
Long
orgId
,
String
code
);
List
<
String
>
getRoleChildrenFunction
(
Long
userId
,
Long
orgId
,
Long
parentId
);
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreRoleMenuDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
org.beetl.sql.core.annotatoin.Param
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.annotatoin.SqlStatement
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreRoleMenu
;
import
java.util.List
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
@SqlResource
(
"core.coreRoleMenu"
)
public
interface
CoreRoleMenuDao
extends
BaseMapper
<
CoreRoleMenu
>
{
...
...
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreUserDao.java
View file @
143d37ee
...
...
@@ -2,8 +2,8 @@ package com.ibeetl.admin.core.dao;
import
com.ibeetl.admin.core.entity.CoreUser
;
import
java.util.List
;
import
org.beetl.sql.
core.annotatoin.SqlResource
;
import
org.beetl.sql.
core.
mapper.
BaseMapper
;
import
org.beetl.sql.
mapper.BaseMapper
;
import
org.beetl.sql.mapper.
annotation.SqlResource
;
@SqlResource
(
"core.coreUser"
)
public
interface
CoreUserDao
extends
BaseMapper
<
CoreUser
>
{
...
...
@@ -11,8 +11,9 @@ public interface CoreUserDao extends BaseMapper<CoreUser> {
/**
* 根据角色编码查询用户集合
*
* @param roleCode
角色编码
*
@return
* @param roleCode
*
角色编码
*/
List
<
CoreUser
>
getUserByRole
(
String
roleCode
);
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreUserRoleDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.engine.PageQuery
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreUserRole
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
@SqlResource
(
"core.coresUserRole"
)
public
interface
CoreUserRoleDao
extends
BaseMapper
<
CoreUserRole
>
{}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/CoreWorkflowDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
org.beetl.sql.core.annotatoin.SqlResource
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
com.ibeetl.admin.core.entity.CoreUser
;
import
java.util.List
;
import
org.beetl.sql.mapper.BaseMapper
;
import
org.beetl.sql.mapper.annotation.SqlResource
;
/**
* 业务侧工作流的基本功能,工作流的一些功能将在业务侧完成,比如选人操作
...
...
@@ -18,9 +17,11 @@ public interface CoreWorkflowDao extends BaseMapper {
/**
* 根据角色id,机构id查询用户集合
*
* @param roleId 角色id
* @param orgs 机构id
* @return
* @param roleId
* 角色id
* @param orgs
* 机构id
*/
List
<
CoreUser
>
queryUsersByRole
(
Long
roleId
,
List
<
Long
>
orgs
);
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/dao/SQLManagerBaseDao.java
View file @
143d37ee
package
com.ibeetl.admin.core.dao
;
import
org.beetl.sql.core.mapper.BaseMapper
;
import
org.beetl.sql.mapper.BaseMapper
;
/** 只是作为专门获取数据源的SQLmanager的接口,避免多数据源中,每次使用名称指定注入SQLmanager。 泛型不可少 */
public
interface
SQLManagerBaseDao
extends
BaseMapper
<
Object
>
{}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/entity/BaseEntity.java
View file @
143d37ee
package
com.ibeetl.admin.core.entity
;
import
com.fasterxml.jackson.annotation.JsonAnyGetter
;
import
java.util.Map
;
import
org.beetl.sql.core.TailBean
;
import
com.fasterxml.jackson.annotation.JsonAnyGetter
;
import
com.fasterxml.jackson.annotation.JsonAnySetter
;
/**
* 描述:用于辅助序列化beetlsql 的TailBean
*
...
...
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/entity/CoreAudit.java
View file @
143d37ee
package
com.ibeetl.admin.core.entity
;
import
java.util.Date
;
import
java.util.Map
;
import
javax.validation.constraints.NotNull
;
import
org.beetl.sql.core.annotatoin.AutoID
;
import
org.beetl.sql.core.annotatoin.SeqID
;
import
com.fasterxml.jackson.annotation.JsonAnyGetter
;
import
com.fasterxml.jackson.annotation.JsonIgnore
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.ibeetl.admin.core.util.ValidateConfig
;
import
java.util.Date
;
import
javax.validation.constraints.NotNull
;
import
org.beetl.sql.annotation.entity.AutoID
;
import
org.beetl.sql.annotation.entity.SeqID
;
public
class
CoreAudit
extends
BaseEntity
{
...
...
@@ -22,89 +15,118 @@ public class CoreAudit extends BaseEntity {
protected
Long
id
;
// 删除标识
@JsonIgnore
protected
Integer
delFlag
;
@JsonIgnore
protected
Integer
delFlag
;
// 创建时间
private
Integer
success
;
private
String
functionCode
;
private
String
functionName
;
private
String
ip
;
private
String
message
;
private
String
userName
;
private
Long
userId
;
protected
Date
createTime
;
public
CoreAudit
()
{}
public
CoreAudit
()
{
}
public
Integer
getSuccess
()
{
return
success
;
}
public
void
setSuccess
(
Integer
success
)
{
this
.
success
=
success
;
}
public
String
getFunctionCode
()
{
return
functionCode
;
}
public
void
setFunctionCode
(
String
functionCode
)
{
this
.
functionCode
=
functionCode
;
}
public
String
getFunctionName
()
{
return
functionName
;
}
public
void
setFunctionName
(
String
functionName
)
{
this
.
functionName
=
functionName
;
}
public
String
getIp
()
{
return
ip
;
}
public
void
setIp
(
String
ip
)
{
this
.
ip
=
ip
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
public
String
getUserName
()
{
return
userName
;
}
public
void
setUserName
(
String
userName
)
{
this
.
userName
=
userName
;
}
public
Long
getUserId
()
{
return
userId
;
}
public
void
setUserId
(
Long
userId
)
{
this
.
userId
=
userId
;
}
public
Long
getId
()
{
return
id
;
}
public
void
setId
(
Long
id
)
{
this
.
id
=
id
;
}
public
Date
getCreateTime
()
{
return
createTime
;
}
public
void
setCreateTime
(
Date
createTime
)
{
this
.
createTime
=
createTime
;
}
}
Prev
1
2
3
4
5
6
7
8
9
Next
Write
Preview
Supports
Markdown
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