Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
safe-campus-bbs
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
万成波
safe-campus-bbs
Commits
d85c499b
Commit
d85c499b
authored
Aug 28, 2025
by
万成波
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
敏感词
parent
6a781be8
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
594 additions
and
1 deletion
+594
-1
pom.xml
pom.xml
+14
-0
safe-campus-admin/pom.xml
safe-campus-admin/pom.xml
+6
-0
safe-campus-common/src/main/java/com/tangguo/common/core/redis/RedisCache.java
...c/main/java/com/tangguo/common/core/redis/RedisCache.java
+28
-0
safe-campus-moment/src/main/java/com/tangguo/controller/BbsSensitiveWordController.java
...va/com/tangguo/controller/BbsSensitiveWordController.java
+114
-0
safe-campus-moment/src/main/java/com/tangguo/controller/BbsTopicController.java
.../main/java/com/tangguo/controller/BbsTopicController.java
+0
-1
safe-campus-moment/src/main/java/com/tangguo/domain/BbsSensitiveWord.java
...nt/src/main/java/com/tangguo/domain/BbsSensitiveWord.java
+50
-0
safe-campus-moment/src/main/java/com/tangguo/domain/result/DataImportResult.java
...main/java/com/tangguo/domain/result/DataImportResult.java
+69
-0
safe-campus-moment/src/main/java/com/tangguo/mapper/BbsSensitiveWordMapper.java
.../main/java/com/tangguo/mapper/BbsSensitiveWordMapper.java
+13
-0
safe-campus-moment/src/main/java/com/tangguo/service/IBbsSensitiveWordService.java
...in/java/com/tangguo/service/IBbsSensitiveWordService.java
+68
-0
safe-campus-moment/src/main/java/com/tangguo/service/impl/BbsSensitiveWordServiceImpl.java
...com/tangguo/service/impl/BbsSensitiveWordServiceImpl.java
+212
-0
safe-campus-moment/src/main/resources/mapper/BbsSensitiveWordMapper.xml
...ment/src/main/resources/mapper/BbsSensitiveWordMapper.xml
+20
-0
No files found.
pom.xml
View file @
d85c499b
...
...
@@ -151,6 +151,20 @@
<artifactId>
safe-campus-common
</artifactId>
<version>
${ruoyi.version}
</version>
</dependency>
<!-- 轻享模块-->
<dependency>
<groupId>
com.tangguo
</groupId>
<artifactId>
safe-campus-moment
</artifactId>
<version>
3.8.5
</version>
</dependency>
<!-- 积分模块-->
<dependency>
<groupId>
com.tangguo
</groupId>
<artifactId>
safe-campus-points
</artifactId>
<version>
3.8.5
</version>
</dependency>
</dependencies>
</dependencyManagement>
...
...
safe-campus-admin/pom.xml
View file @
d85c499b
...
...
@@ -31,6 +31,12 @@
<groupId>
com.tangguo
</groupId>
<artifactId>
safe-campus-generator
</artifactId>
</dependency>
<!-- 轻享模块 -->
<dependency>
<groupId>
com.tangguo
</groupId>
<artifactId>
safe-campus-moment
</artifactId>
</dependency>
</dependencies>
<build>
...
...
safe-campus-common/src/main/java/com/tangguo/common/core/redis/RedisCache.java
View file @
d85c499b
package
com
.
tangguo
.
common
.
core
.
redis
;
import
org.apache.poi.ss.formula.functions.T
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.BoundSetOperations
;
import
org.springframework.data.redis.core.HashOperations
;
...
...
@@ -154,6 +155,33 @@ public class RedisCache {
return
setOperation
;
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param values 缓存的数据
* @return 缓存数据的对象
*/
public
<
T
>
void
setAddValues
(
final
String
key
,
final
T
...
values
)
{
BoundSetOperations
<
String
,
T
>
setOperation
=
redisTemplate
.
boundSetOps
(
key
);
setOperation
.
add
(
values
);
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param values 缓存的数据
* @return 缓存数据的对象
*/
public
<
T
>
void
setDeleteValues
(
final
String
key
,
final
T
...
values
)
{
BoundSetOperations
<
String
,
T
>
setOperation
=
redisTemplate
.
boundSetOps
(
key
);
setOperation
.
remove
(
values
);
}
/**
* 获得缓存的set
*
...
...
safe-campus-moment/src/main/java/com/tangguo/controller/BbsSensitiveWordController.java
0 → 100644
View file @
d85c499b
package
com
.
tangguo
.
controller
;
import
com.tangguo.common.annotation.Log
;
import
com.tangguo.common.core.controller.BaseController
;
import
com.tangguo.common.core.domain.AjaxResult
;
import
com.tangguo.common.core.page.TableDataInfo
;
import
com.tangguo.common.enums.BusinessType
;
import
com.tangguo.common.utils.poi.ExcelUtil
;
import
com.tangguo.domain.BbsSensitiveWord
;
import
com.tangguo.domain.result.DataImportResult
;
import
com.tangguo.service.IBbsSensitiveWordService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletResponse
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* 敏感词库Controller
*
* @author ruoyi
* @date 2025-08-27
*/
@Api
(
tags
=
"敏感词库管理"
)
@RestController
@RequestMapping
(
"/bbs/moment/sensitive/word"
)
public
class
BbsSensitiveWordController
extends
BaseController
{
@Resource
private
IBbsSensitiveWordService
bbsSensitiveWordService
;
/**
* 查询敏感词库列表
*/
@ApiOperation
(
"查询敏感词库列表"
)
@PreAuthorize
(
"@ss.hasPermi('word:word:list')"
)
@GetMapping
(
"/list"
)
public
TableDataInfo
list
(
BbsSensitiveWord
bbsSensitiveWord
)
{
startPage
();
List
<
BbsSensitiveWord
>
list
=
bbsSensitiveWordService
.
selectBbsSensitiveWordList
(
bbsSensitiveWord
);
return
getDataTable
(
list
);
}
/**
* 获取敏感词库详细信息
*/
@ApiOperation
(
"获取敏感词库详细信息"
)
@PreAuthorize
(
"@ss.hasPermi('word:word:query')"
)
@GetMapping
(
value
=
"/{id}"
)
public
AjaxResult
getInfo
(
@PathVariable
(
"id"
)
Long
id
)
{
return
success
(
bbsSensitiveWordService
.
getById
(
id
));
}
/**
* 新增敏感词库
*/
@ApiOperation
(
"新增敏感词库"
)
@PreAuthorize
(
"@ss.hasPermi('word:word:add')"
)
@Log
(
title
=
"敏感词库"
,
businessType
=
BusinessType
.
INSERT
)
@PostMapping
public
AjaxResult
add
(
@RequestBody
BbsSensitiveWord
word
)
{
this
.
bbsSensitiveWordService
.
addWord
(
word
);
return
AjaxResult
.
success
();
}
/**
* 修改敏感词库
*/
@ApiOperation
(
"修改敏感词库"
)
@PreAuthorize
(
"@ss.hasPermi('word:word:edit')"
)
@Log
(
title
=
"敏感词库"
,
businessType
=
BusinessType
.
UPDATE
)
@PutMapping
public
AjaxResult
edit
(
@RequestBody
BbsSensitiveWord
word
)
{
this
.
bbsSensitiveWordService
.
editWord
(
word
);
return
AjaxResult
.
success
();
}
/**
* 删除敏感词库
*/
@ApiOperation
(
"删除敏感词库"
)
@PreAuthorize
(
"@ss.hasPermi('word:word:remove')"
)
@Log
(
title
=
"敏感词库"
,
businessType
=
BusinessType
.
DELETE
)
@DeleteMapping
(
"/{id}"
)
public
AjaxResult
remove
(
@PathVariable
Long
id
)
{
this
.
bbsSensitiveWordService
.
deleteWord
(
id
);
return
AjaxResult
.
success
();
}
/**
* 修改敏感词库
*/
@ApiOperation
(
"修改敏感词库"
)
@PreAuthorize
(
"@ss.hasPermi('word:word:edit')"
)
@Log
(
title
=
"敏感词库"
,
businessType
=
BusinessType
.
UPDATE
)
@PostMapping
(
"/import"
)
public
AjaxResult
importWords
(
MultipartFile
file
)
{
DataImportResult
<
String
>
result
=
this
.
bbsSensitiveWordService
.
importWords
(
file
);
return
AjaxResult
.
success
(
result
);
}
}
safe-campus-moment/src/main/java/com/tangguo/controller/BbsTopicController.java
View file @
d85c499b
...
...
@@ -13,7 +13,6 @@ import org.springframework.security.access.prepost.PreAuthorize;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
java.util.Arrays
;
import
java.util.List
;
/**
...
...
safe-campus-moment/src/main/java/com/tangguo/domain/BbsSensitiveWord.java
0 → 100644
View file @
d85c499b
package
com
.
tangguo
.
domain
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
com.tangguo.common.annotation.Excel
;
import
com.tangguo.common.core.domain.BaseEntity
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
lombok.ToString
;
import
lombok.experimental.Accessors
;
/**
* 敏感词库对象 bbs_sensitive_word
*
* @author ruoyi
* @date 2025-08-27
*/
@Data
@ToString
@NoArgsConstructor
@Accessors
(
chain
=
true
)
@TableName
(
"bbs_sensitive_word"
)
@ApiModel
(
value
=
"BbsSensitiveWord"
,
description
=
"敏感词库实体"
)
public
class
BbsSensitiveWord
extends
BaseEntity
{
private
static
final
long
serialVersionUID
=
1L
;
/** ID */
@TableId
(
type
=
IdType
.
AUTO
)
@ApiModelProperty
(
"ID"
)
private
Long
id
;
/** 敏感词名称 */
@Excel
(
name
=
"敏感词名称"
)
@ApiModelProperty
(
"敏感词名称"
)
private
String
name
;
/** 排序值 */
@Excel
(
name
=
"排序值"
)
@ApiModelProperty
(
"排序值"
)
private
Integer
sort
;
/** 启用状态:0 禁用、1 启用 */
@Excel
(
name
=
"启用状态:0 禁用、1 启用"
)
@ApiModelProperty
(
"启用状态:0 禁用、1 启用"
)
private
Integer
enableStatus
;
}
safe-campus-moment/src/main/java/com/tangguo/domain/result/DataImportResult.java
0 → 100644
View file @
d85c499b
package
com
.
tangguo
.
domain
.
result
;
import
lombok.Data
;
import
org.apache.poi.ss.formula.functions.T
;
import
java.io.Serializable
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* 数据导入结果
*
* @author 谈笑
* @createTime 2025-08-28 09:43:53 星期四
*/
@Data
public
class
DataImportResult
<
T
>
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
1544586244818112713L
;
/**
* 导入任务Id
*/
private
String
taskId
;
/**
* 导入数据总条数
*/
private
int
totalCount
;
/**
* 导入成功数据条数
*/
private
int
successCount
;
/**
* 导入失败数据条数
*/
private
int
failCount
;
/**
* 导入失败消息
*/
private
String
errorMessage
;
/**
* 导入数据失败数据明细
*/
private
List
<
Row
<
T
>>
failRows
=
new
ArrayList
<>(
0
);
@Data
public
static
class
Row
<
T
>
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
437773899860737658L
;
/**
* 原始数据
*/
private
T
rowData
;
/**
* 反馈消息
*/
private
String
message
;
}
}
safe-campus-moment/src/main/java/com/tangguo/mapper/BbsSensitiveWordMapper.java
0 → 100644
View file @
d85c499b
package
com
.
tangguo
.
mapper
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.tangguo.domain.BbsSensitiveWord
;
/**
* 敏感词库Mapper接口
*
* @author ruoyi
* @date 2025-08-27
*/
public
interface
BbsSensitiveWordMapper
extends
BaseMapper
<
BbsSensitiveWord
>
{
}
safe-campus-moment/src/main/java/com/tangguo/service/IBbsSensitiveWordService.java
0 → 100644
View file @
d85c499b
package
com
.
tangguo
.
service
;
import
java.util.List
;
import
java.util.Set
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.tangguo.domain.BbsSensitiveWord
;
import
com.tangguo.domain.result.DataImportResult
;
import
org.springframework.web.multipart.MultipartFile
;
/**
* 敏感词库Service接口
*
* @author ruoyi
* @date 2025-08-27
*/
public
interface
IBbsSensitiveWordService
extends
IService
<
BbsSensitiveWord
>
{
/**
* 查询敏感词
*
* @return 敏感词
*/
Set
<
String
>
getDbWords
();
/**
* 查询敏感词库列表
*
* @param bbsSensitiveWord 敏感词库
* @return 敏感词库集合
*/
List
<
BbsSensitiveWord
>
selectBbsSensitiveWordList
(
BbsSensitiveWord
bbsSensitiveWord
);
/**
* 新增敏感词
*
* @param word 敏感词
*/
void
addWord
(
BbsSensitiveWord
word
);
/**
* 修改敏感词
*
* @param word 敏感词
*/
void
editWord
(
BbsSensitiveWord
word
);
/**
* 删除敏感词
*
* @param wordId 敏感词Id
*/
void
deleteWord
(
Long
wordId
);
/**
* 导入敏感词
*
* @param file 铭感词文件
* @return 导入结果
*/
DataImportResult
<
String
>
importWords
(
MultipartFile
file
);
}
safe-campus-moment/src/main/java/com/tangguo/service/impl/BbsSensitiveWordServiceImpl.java
0 → 100644
View file @
d85c499b
package
com
.
tangguo
.
service
.
impl
;
import
cn.hutool.core.io.IoUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.tangguo.common.core.redis.RedisCache
;
import
com.tangguo.common.exception.ServiceException
;
import
com.tangguo.common.utils.StringUtils
;
import
com.tangguo.domain.BbsSensitiveWord
;
import
com.tangguo.domain.result.DataImportResult
;
import
com.tangguo.mapper.BbsSensitiveWordMapper
;
import
com.tangguo.service.IBbsSensitiveWordService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.PostConstruct
;
import
javax.annotation.Resource
;
import
java.io.*
;
import
java.nio.file.Files
;
import
java.util.*
;
/**
* 敏感词库Service业务层处理
*
* @author ruoyi
* @date 2025-08-27
*/
@Slf4j
@Service
public
class
BbsSensitiveWordServiceImpl
extends
ServiceImpl
<
BbsSensitiveWordMapper
,
BbsSensitiveWord
>
implements
IBbsSensitiveWordService
{
private
static
final
String
WORD_CACHE_KEY
=
"sensitive:words"
;
@Resource
private
BbsSensitiveWordMapper
bbsSensitiveWordMapper
;
@Resource
private
RedisCache
redisCache
;
@PostConstruct
private
void
initCacheWords
()
{
Set
<
String
>
dbWords
=
this
.
getDbWords
();
this
.
redisCache
.
setCacheSet
(
WORD_CACHE_KEY
,
new
HashSet
<>(
dbWords
));
log
.
info
(
"=> 数据库敏感词已缓存,敏感词数量:{}"
,
dbWords
.
size
());
}
/**
* 查询敏感词
*
* @return 敏感词
*/
@Override
public
Set
<
String
>
getDbWords
()
{
List
<
String
>
dbWords
=
this
.
listObjs
(
Wrappers
.
lambdaQuery
(
BbsSensitiveWord
.
class
).
select
(
BbsSensitiveWord:
:
getName
),
Objects:
:
toString
);
return
new
HashSet
<>(
dbWords
);
}
/**
* 查询敏感词库列表
*
* @param word 敏感词库
* @return 敏感词库
*/
@Override
public
List
<
BbsSensitiveWord
>
selectBbsSensitiveWordList
(
BbsSensitiveWord
word
)
{
LambdaQueryWrapper
<
BbsSensitiveWord
>
lqw
=
Wrappers
.
lambdaQuery
();
lqw
.
orderByDesc
(
BbsSensitiveWord:
:
getCreateTime
);
lqw
.
like
(
StringUtils
.
isNotBlank
(
word
.
getName
()),
BbsSensitiveWord:
:
getName
,
word
.
getName
());
return
bbsSensitiveWordMapper
.
selectList
(
lqw
);
}
/**
* 新增敏感词
*
* @param word 敏感词
*/
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Override
public
void
addWord
(
BbsSensitiveWord
word
)
{
long
wordCount
=
this
.
count
(
Wrappers
.
lambdaQuery
(
BbsSensitiveWord
.
class
).
eq
(
BbsSensitiveWord:
:
getName
,
word
.
getName
())
);
if
(
wordCount
>
0
)
{
throw
new
ServiceException
(
"添加失败,当前敏感词已存在。"
);
}
BbsSensitiveWord
addWord
=
new
BbsSensitiveWord
();
addWord
.
setName
(
word
.
getName
());
addWord
.
setSort
(
word
.
getSort
());
addWord
.
setEnableStatus
(
1
);
this
.
save
(
addWord
);
this
.
redisCache
.
setAddValues
(
WORD_CACHE_KEY
,
word
.
getName
());
}
/**
* 修改敏感词
*
* @param word 敏感词
*/
@Override
public
void
editWord
(
BbsSensitiveWord
word
)
{
BbsSensitiveWord
dbWord
=
this
.
getById
(
word
.
getId
());
if
(
Objects
.
isNull
(
dbWord
))
{
throw
new
ServiceException
(
"修改失败,未查询到当前敏感词数据。"
);
}
if
(!
dbWord
.
getName
().
equals
(
word
.
getName
()))
{
long
wordCount
=
this
.
count
(
Wrappers
.
lambdaQuery
(
BbsSensitiveWord
.
class
).
eq
(
BbsSensitiveWord:
:
getName
,
word
.
getName
())
);
if
(
wordCount
>
0
)
{
throw
new
ServiceException
(
"修改失败,当前敏感词已存在。"
);
}
}
BbsSensitiveWord
updWord
=
new
BbsSensitiveWord
();
updWord
.
setId
(
word
.
getId
());
updWord
.
setName
(
word
.
getName
());
updWord
.
setSort
(
word
.
getSort
());
this
.
updateById
(
updWord
);
this
.
redisCache
.
setDeleteValues
(
WORD_CACHE_KEY
,
dbWord
.
getName
());
this
.
redisCache
.
setAddValues
(
WORD_CACHE_KEY
,
word
.
getName
());
}
/**
* 删除敏感词
*
* @param wordId 敏感词Id
*/
@Override
public
void
deleteWord
(
Long
wordId
)
{
BbsSensitiveWord
dbWord
=
this
.
getById
(
wordId
);
if
(
Objects
.
nonNull
(
dbWord
))
{
this
.
removeById
(
wordId
);
this
.
redisCache
.
setDeleteValues
(
WORD_CACHE_KEY
,
dbWord
.
getName
());
}
}
/**
* 导入敏感词
*
* @param file 铭感词文件
* @return 导入结果
*/
@Override
public
DataImportResult
<
String
>
importWords
(
MultipartFile
file
)
{
DataImportResult
<
String
>
result
=
new
DataImportResult
<>();
BufferedReader
reader
=
null
;
try
{
// 读取敏感词
reader
=
new
BufferedReader
(
new
InputStreamReader
(
file
.
getInputStream
()));
String
word
;
Set
<
String
>
words
=
new
LinkedHashSet
<>(
10
);
while
(
Objects
.
nonNull
(
word
=
reader
.
readLine
()))
{
if
(
StrUtil
.
isNotBlank
(
word
))
{
words
.
add
(
word
);
}
}
// 校验敏感词
Set
<
String
>
cacheWords
=
this
.
redisCache
.
getCacheSet
(
WORD_CACHE_KEY
);
List
<
String
>
addWords
=
new
ArrayList
<>(
words
.
size
());
for
(
String
w
:
words
)
{
if
(
cacheWords
.
contains
(
w
))
{
DataImportResult
.
Row
<
String
>
row
=
new
DataImportResult
.
Row
<>();
row
.
setRowData
(
w
);
row
.
setMessage
(
"当前敏感词已存在"
);
result
.
getFailRows
().
add
(
row
);
}
else
{
addWords
.
add
(
w
);
}
}
// 添加敏感词
List
<
BbsSensitiveWord
>
newWords
=
new
ArrayList
<>(
addWords
.
size
());
for
(
String
addWord
:
addWords
)
{
BbsSensitiveWord
newWord
=
new
BbsSensitiveWord
();
newWord
.
setName
(
addWord
);
newWords
.
add
(
newWord
);
}
super
.
saveBatch
(
newWords
);
// 缓存敏感词
this
.
redisCache
.
setAddValues
(
WORD_CACHE_KEY
,
addWords
.
toArray
());
result
.
setTotalCount
(
words
.
size
());
result
.
setSuccessCount
(
addWords
.
size
());
result
.
setFailCount
(
words
.
size
()
-
addWords
.
size
());
}
catch
(
Exception
e
)
{
log
.
error
(
"=> 导入敏感词失败:"
,
e
);
}
finally
{
IoUtil
.
close
(
reader
);
}
return
result
;
}
}
safe-campus-moment/src/main/resources/mapper/BbsSensitiveWordMapper.xml
0 → 100644
View file @
d85c499b
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.tangguo.mapper.BbsSensitiveWordMapper"
>
<resultMap
type=
"BbsSensitiveWord"
id=
"BbsSensitiveWordResult"
>
<result
property=
"id"
column=
"id"
/>
<result
property=
"createBy"
column=
"create_by"
/>
<result
property=
"createTime"
column=
"create_time"
/>
<result
property=
"updateBy"
column=
"update_by"
/>
<result
property=
"updateTime"
column=
"update_time"
/>
<result
property=
"remark"
column=
"remark"
/>
<result
property=
"name"
column=
"name"
/>
<result
property=
"sort"
column=
"sort"
/>
<result
property=
"enableStatus"
column=
"enable_status"
/>
</resultMap>
</mapper>
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