Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
O
on-site-service
Project
Project
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
external
on-site-service
Commits
f51e2893
Commit
f51e2893
authored
Jul 13, 2022
by
shangtx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 用户管理
parent
7dc7bc51
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
379 additions
and
177 deletions
+379
-177
UserController.java
...m/onsiteservice/admin/controller/user/UserController.java
+60
-0
UserPageDTO.java
.../onsiteservice/admin/controller/user/dto/UserPageDTO.java
+32
-0
UserBizMapper.java
...va/com/onsiteservice/admin/mapper/user/UserBizMapper.java
+18
-0
UserService.java
...ava/com/onsiteservice/admin/service/user/UserService.java
+47
-0
application.yaml
admin/src/main/resources/application.yaml
+3
-1
UserBizMapper.xml
admin/src/main/resources/mapper/user/UserBizMapper.xml
+45
-0
Dict.java
...n/java/com/onsiteservice/common/annotation/dict/Dict.java
+22
-0
DictAspect.java
.../com/onsiteservice/common/annotation/dict/DictAspect.java
+150
-0
DictConstants.java
...va/com/onsiteservice/constant/constant/DictConstants.java
+2
-176
No files found.
admin/src/main/java/com/onsiteservice/admin/controller/user/UserController.java
0 → 100644
View file @
f51e2893
package
com
.
onsiteservice
.
admin
.
controller
.
user
;
import
com.onsiteservice.admin.controller.user.dto.UserPageDTO
;
import
com.onsiteservice.common.annotation.dict.Dict
;
import
com.onsiteservice.common.annotation.user.CurrentUserId
;
import
com.onsiteservice.constant.constant.DictConstants
;
import
com.onsiteservice.entity.user.User
;
import
com.onsiteservice.admin.service.user.UserService
;
import
com.onsiteservice.core.result.Result
;
import
com.onsiteservice.dao.common.page.PageInfoVO
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.NonNull
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
import
springfox.documentation.annotations.ApiIgnore
;
import
javax.annotation.Resource
;
import
javax.validation.constraints.Positive
;
import
static
com
.
onsiteservice
.
core
.
result
.
ResultGenerator
.
success
;
/**
* @author 商天翔
* @date 2022-07-13 14:44
* @description UserController控制类
*/
@ApiIgnore
@Api
(
tags
=
"UserController"
)
@RestController
@RequestMapping
(
"/user"
)
@Validated
public
class
UserController
{
@Resource
private
UserService
userService
;
@Dict
(
code
=
DictConstants
.
ROLE_TYPE
,
name
=
"roleType"
)
@ApiOperation
(
value
=
"分页查询列表"
,
notes
=
"作者: 商天翔"
)
@PostMapping
(
"/page"
)
public
Result
<
PageInfoVO
>
getPage
(
@RequestBody
@NonNull
@Validated
UserPageDTO
dto
)
{
return
success
(
userService
.
getPage
(
dto
),
"获取分页列表"
);
}
@ApiOperation
(
value
=
"根据id查询"
,
notes
=
"作者: 商天翔"
)
@GetMapping
(
"/{id}"
)
public
Result
<
User
>
getDetails
(
@PathVariable
@Positive
Long
id
)
{
return
success
(
userService
.
selectByPrimaryKey
(
id
),
"根据id获取详情"
);
}
@ApiOperation
(
value
=
"新增或修改"
,
notes
=
"作者: 商天翔"
)
@PutMapping
public
Result
saveOrUpdate
(
@RequestBody
@NonNull
@Validated
User
user
,
@CurrentUserId
Long
userId
)
{
return
success
(
userService
.
update
(
user
,
userId
),
user
.
getId
()
==
null
?
"新增成功"
:
"修改成功"
);
}
}
admin/src/main/java/com/onsiteservice/admin/controller/user/dto/UserPageDTO.java
0 → 100644
View file @
f51e2893
package
com
.
onsiteservice
.
admin
.
controller
.
user
.
dto
;
import
com.alibaba.fastjson.annotation.JSONField
;
import
com.onsiteservice.dao.common.page.PageParams
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
java.util.Date
;
/**
* 用户分页DTO
*/
@Data
public
class
UserPageDTO
extends
PageParams
{
@ApiModelProperty
(
"名称"
)
private
String
name
;
private
String
phone
;
@ApiModelProperty
(
"角色类型"
)
private
Integer
roleType
;
@ApiModelProperty
(
"注册时间 开始"
)
@JSONField
(
format
=
"yyyy-MM-dd"
)
private
Date
createTimeBegin
;
@ApiModelProperty
(
"注册时间 结束"
)
@JSONField
(
format
=
"yyyy-MM-dd"
)
private
Date
createTimeEnd
;
}
admin/src/main/java/com/onsiteservice/admin/mapper/user/UserBizMapper.java
0 → 100644
View file @
f51e2893
package
com
.
onsiteservice
.
admin
.
mapper
.
user
;
import
com.onsiteservice.admin.controller.user.dto.UserPageDTO
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author 商天翔
* @date 2022-07-13 14:44
* @description UserBizMapper业务接口
*/
public
interface
UserBizMapper
{
List
<
Map
<
String
,
Object
>>
getPage
(
@Param
(
"param"
)
UserPageDTO
dto
);
}
admin/src/main/java/com/onsiteservice/admin/service/user/UserService.java
0 → 100644
View file @
f51e2893
package
com
.
onsiteservice
.
admin
.
service
.
user
;
import
com.onsiteservice.admin.controller.user.dto.UserPageDTO
;
import
com.onsiteservice.dao.util.EntityUtils
;
import
com.onsiteservice.entity.user.User
;
import
com.onsiteservice.dao.mapper.user.UserMapper
;
import
com.onsiteservice.admin.mapper.user.UserBizMapper
;
import
com.onsiteservice.dao.common.AbstractMapper
;
import
com.onsiteservice.dao.common.page.PageParams
;
import
com.onsiteservice.dao.common.page.PageInfoVO
;
import
com.github.pagehelper.PageHelper
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
javax.annotation.Resource
;
/**
* @author 商天翔
* @date 2022-07-13 14:44
* @description UserService服务类
*/
@Service
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
class
UserService
extends
AbstractMapper
<
User
>
{
@Resource
private
UserMapper
userMapper
;
@Resource
private
UserBizMapper
userBizMapper
;
/**
* 分页查询列表
*/
public
PageInfoVO
getPage
(
UserPageDTO
dto
)
{
PageHelper
.
startPage
(
dto
.
getPage
(),
dto
.
getSize
());
return
new
PageInfoVO
(
userBizMapper
.
getPage
(
dto
));
}
/**
* 保存或更新方法
*/
public
int
update
(
User
user
,
Long
userId
)
{
EntityUtils
.
update
(
user
,
userId
);
return
this
.
updateByPrimaryKeySelective
(
user
);
}
}
admin/src/main/resources/application.yaml
View file @
f51e2893
...
...
@@ -26,4 +26,6 @@ spring:
include
:
-
common
application
:
name
:
onsite-service-admin
\ No newline at end of file
name
:
onsite-service-admin
knife4j
:
enable
:
true
\ No newline at end of file
admin/src/main/resources/mapper/user/UserBizMapper.xml
0 → 100644
View file @
f51e2893
<?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.onsiteservice.admin.mapper.user.UserBizMapper"
>
<select
id=
"getPage"
resultType=
"map"
>
select t.id,
t.user_name,
t.nick_name,
t.phone,
t.email,
t.avatar,
t.union_id,
t.open_id,
t.official_account_open_id,
t.is_push_msg,
t.role_type,
t.create_time
from user t
<where>
<if
test=
"param.name != null"
>
and (t.nick_name like "%"#{param.name}"%" or t.user_name like "%"#{param.name}"%" )
</if>
<if
test=
"param.phone != null"
>
and t.phone like "%"#{param.phone}"%"
</if>
<if
test=
"param.roleType != null"
>
and t.role_type = #{param.roleType}
</if>
<if
test=
"param.createTimeBegin != null and param.createTimeEnd != null"
>
and t.create_time
<![CDATA[>]]>
#{param.createTimeBegin}
and t.create_time
<![CDATA[<]]>
date_add(#{param.createTimeEnd}, INTERVAL 1 DAY)
</if>
</where>
order by
<choose>
<when
test=
"param.sort != null and param.sort != ''"
>
${param.sort} ${param.order}
</when>
<otherwise>
t.id desc
</otherwise>
</choose>
</select>
</mapper>
common/src/main/java/com/onsiteservice/common/annotation/dict/Dict.java
0 → 100644
View file @
f51e2893
package
com
.
onsiteservice
.
common
.
annotation
.
dict
;
import
java.lang.annotation.*
;
/**
* @author 潘维吉
* @date 2020/3/13 16:56
* @email 406798106@qq.com
* @description 字典翻译注解
* 在Controller方法使用
* 单字典值翻译 @Dict(code = "SYS0001", name = "status") 翻译结果可以为 平级 {status: 1 , statusValue: "启用"} 或 层级 {status: {code: 0 , value: "禁用"}}
* 多字典值翻译 @Dict(code = {"SYS0001","SYS0002"}, name = {"status","sex"})
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
})
@Documented
public
@interface
Dict
{
String
[]
code
();
// 主表编码
String
[]
name
();
// 属性名 不是数据库字段名 map类型为key
}
common/src/main/java/com/onsiteservice/common/annotation/dict/DictAspect.java
0 → 100644
View file @
f51e2893
package
com
.
onsiteservice
.
common
.
annotation
.
dict
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.onsiteservice.common.runner.InitDataRunner
;
import
com.onsiteservice.core.exception.ServiceException
;
import
com.onsiteservice.core.result.Result
;
import
com.onsiteservice.dao.common.page.PageInfoVO
;
import
com.onsiteservice.util.ArrayUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.BooleanUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.aspectj.lang.JoinPoint
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.annotation.Pointcut
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.stereotype.Component
;
import
java.lang.reflect.Method
;
import
java.util.*
;
import
java.util.stream.Collectors
;
/**
* @author 潘维吉
* @date 2020/3/13 16:59
* @email 406798106@qq.com
* @description 字典code value响应数据切面 实现字典值的自动翻译
*/
@ConditionalOnProperty
(
prefix
=
"project.dict"
,
name
=
{
"enabled"
},
matchIfMissing
=
true
)
@Slf4j
@Aspect
@Component
public
class
DictAspect
{
@Pointcut
(
"@annotation(com.onsiteservice.common.annotation.dict.Dict)"
)
public
void
dict
()
{
}
@Around
(
"dict()"
)
public
Object
around
(
ProceedingJoinPoint
joinPoint
)
throws
Throwable
{
Object
result
=
joinPoint
.
proceed
();
if
(
result
instanceof
Result
)
{
Dict
dict
=
getDict
(
joinPoint
);
Object
data
=
((
Result
)
result
).
getData
();
if
(
data
instanceof
List
)
{
// 普通列表
List
newResult
=
new
ArrayList
();
((
List
)
data
).
stream
().
forEach
(
item
->
newResult
.
add
(
handleData
(
dict
,
((
JSONObject
)
JSON
.
toJSON
(
item
))))
);
return
((
Result
)
result
).
setData
(
newResult
);
}
else
if
(
data
instanceof
PageInfoVO
)
{
// 分页列表
List
newResult
=
new
ArrayList
();
((
PageInfoVO
)
data
).
getList
().
stream
().
forEach
(
item
->
newResult
.
add
(
handleData
(
dict
,
((
JSONObject
)
JSON
.
toJSON
(
item
))))
);
((
PageInfoVO
)
data
).
setList
(
newResult
);
return
((
Result
)
result
).
setData
(
data
);
}
else
{
// 单条数据
JSONObject
jsonObject
=
handleData
(
dict
,
(
JSONObject
)
JSON
.
toJSON
(
data
));
return
((
Result
)
result
).
setData
(
jsonObject
);
}
}
return
result
;
}
/**
* 非注解方式翻译字典数据
*
* @param typeCode 主表编码
* @param dictCode 字典表编码
*/
public
static
String
translateDictData
(
String
typeCode
,
String
dictCode
)
{
List
<
Map
>
list
=
InitDataRunner
.
dictData
.
get
(
typeCode
).
stream
()
.
filter
(
item
->
item
.
get
(
"code"
).
equals
(
dictCode
))
.
collect
(
Collectors
.
toList
());
// 字典值
return
ArrayUtils
.
isEmpty
(
list
)
?
null
:
list
.
get
(
0
).
get
(
"value"
).
toString
();
}
/**
* 字典表翻译值
*
* @param dict
* @param jsonObject
*/
private
JSONObject
handleData
(
Dict
dict
,
JSONObject
jsonObject
)
{
List
codeList
=
Arrays
.
asList
(
dict
.
code
());
List
nameList
=
Arrays
.
asList
(
dict
.
name
());
List
<
Map
>
dictList
=
new
ArrayList
(
2
);
for
(
int
i
=
0
;
i
<
codeList
.
size
();
i
++)
{
dictList
.
add
(
Map
.
of
(
"code"
,
codeList
.
get
(
i
),
"value"
,
nameList
.
get
(
i
)));
}
dictList
.
forEach
(
item
->
{
String
codeName
=
item
.
get
(
"value"
).
toString
();
Object
nameValue
=
jsonObject
.
get
(
item
.
get
(
"value"
));
if
(
Objects
.
isNull
(
nameValue
))
{
return
;
}
if
(
nameValue
instanceof
Boolean
)
{
nameValue
=
BooleanUtils
.
toInteger
((
Boolean
)
nameValue
);
jsonObject
.
put
(
codeName
,
nameValue
);
}
else
if
(
nameValue
instanceof
Integer
)
{
nameValue
=
nameValue
;
}
else
if
(
nameValue
instanceof
String
)
{
nameValue
=
nameValue
;
}
else
{
throw
new
ServiceException
(
String
.
format
(
"字典值 %s:%s 类型错误, String或Integer或Boolean类型"
,
codeName
,
nameValue
));
}
try
{
Object
finalNameValue
=
nameValue
+
""
;
List
<
Map
>
list
=
InitDataRunner
.
dictData
.
get
(
item
.
get
(
"code"
)).
stream
()
.
filter
(
items
->
items
.
get
(
"code"
).
equals
(
finalNameValue
))
.
collect
(
Collectors
.
toList
());
// 平级结构 简化开发
jsonObject
.
put
(
codeName
+
"Value"
,
ArrayUtils
.
isEmpty
(
list
)
?
null
:
list
.
get
(
0
).
get
(
"value"
));
/* jsonObject.put(codeName, Map.of("code", jsonObject.get(codeName),
"value", ArrayUtils.isEmpty(list) ? null : list.get(0).get("value")));*/
}
catch
(
NullPointerException
e
)
{
throw
new
ServiceException
(
String
.
format
(
"字典数据%s不存在"
,
codeName
));
}
catch
(
Exception
e
)
{
throw
new
ServiceException
(
"字典数据翻译异常"
);
}
});
return
jsonObject
;
}
/**
* 获取注解对象
*
* @param joinPoint 对象
*/
private
Dict
getDict
(
final
JoinPoint
joinPoint
)
{
Method
[]
methods
=
joinPoint
.
getTarget
().
getClass
().
getDeclaredMethods
();
String
name
=
joinPoint
.
getSignature
().
getName
();
if
(!
StringUtils
.
isEmpty
(
name
))
{
for
(
Method
method
:
methods
)
{
Dict
annotation
=
method
.
getAnnotation
(
Dict
.
class
);
if
(!
Objects
.
isNull
(
annotation
)
&&
name
.
equals
(
method
.
getName
()))
{
return
annotation
;
}
}
}
return
null
;
}
}
constant/src/main/java/com/onsiteservice/constant/constant/DictConstants.java
View file @
f51e2893
package
com
.
onsiteservice
.
constant
.
constant
;
/**
* @author 潘维吉
* @date 2020/3/3 10:10
* @email 406798106@qq.com
* @description 字典表常量
* 0 1 表示布尔类型状态 可不定义内部类 定义字典紧贴主编码下方 除布尔值 其他编码从值 1 开始
* mybatis的xml中的引用语法规则:${@package$subClass@Attr.getMethod}
* 字典表常量
*/
public
class
DictConstants
{
...
...
@@ -71,181 +66,12 @@ public class DictConstants {
public
static
final
int
SUCCESS
=
1
;
// 成功
}
/**
* 管理平台
*/
public
final
static
String
MANAGE_PLATFORM
=
"SYS0007"
;
public
class
ManagePlatform
{
public
static
final
int
OPERATION
=
1
;
// 运营平台
public
static
final
int
ORGANIZATION
=
2
;
// 公司平台
}
/**
* ------------------业务自定义字典数据------------------
*/
/**
* 平台类型
*/
public
final
static
String
PLATFORM
=
"BIZ0001"
;
/**
* mybatis xml中使用常量 ${@com.monorepo.constant.DictConstants$Platform@USER_APP}
*/
public
class
Platform
{
public
static
final
int
USER_APP
=
1
;
// 用户端小程序
public
static
final
int
MANAGE_APP
=
2
;
// 管理端小程序
}
/**
* 推送Job发送状态
*/
public
final
static
String
PUSH_JOB_STATUS
=
"BIZ0002"
;
public
class
PushJobStatus
{
public
static
final
int
PENDING
=
1
;
// 待发送
public
static
final
int
SENDING
=
2
;
// 发送中
public
static
final
int
FINISH
=
3
;
// 发送完成
}
/**
* 订单状态 10待付款 20待派单 30待接单 40服务中 50已结束"
*/
public
final
static
String
ORDER_STATUS
=
"BIZ0009"
;
public
class
OrderStatus
{
public
static
final
int
WAIT_PAY
=
10
;
// 待支付
public
static
final
int
PAYING
=
11
;
// 支付中
public
static
final
int
WAIT_APPOINT
=
20
;
// 待派单
public
static
final
int
WAIT_ACCEPT
=
30
;
// 待接单
public
static
final
int
SERVICING
=
40
;
// 服务中
public
static
final
int
FINISH
=
50
;
// 已结束
}
/**
* 数据来源 1小程序 2日照通
*/
public
final
static
String
ADD_SOURCE
=
"BIZ0004"
;
public
class
AddSource
{
public
static
final
int
WX
=
1
;
// 微信小程序
public
static
final
int
RZT
=
2
;
// 日照通
}
/**
* 取消订单 0未取消 1支付超时取消 2用户发起手动取消 3手动取消已确认 4取消支付取消 5管理员拒单
*/
public
final
static
String
ORDER_CANCEL_STATUS
=
""
;
public
class
OrderCancelStatus
{
public
static
final
int
NO
=
0
;
// 0未取消
public
static
final
int
UNPAY
=
1
;
// 1支付超时取消
public
static
final
int
MANUAL
=
2
;
// 2用户发起手动取消
public
static
final
int
CONFIRM
=
3
;
// 3手动取消已确认
public
static
final
int
CANCEL_PAY
=
4
;
// 4取消支付取消
public
static
final
int
REFUSE
=
5
;
// 5管理员拒单
}
/**
* 退款状态 1发起 2退款中 3退款成功
*/
public
final
static
String
ORDER_REFUND_STATUS
=
"BIZ0005"
;
public
class
OrderRefundStatus
{
public
static
final
int
NONE
=
0
;
// 未发起
public
static
final
int
BEGIN_REFUND
=
1
;
// 发起
public
static
final
int
REFUNDING
=
2
;
// 退款中
public
static
final
int
FINISH
=
3
;
// 退款成功
}
/**
* 资讯状态:1新建 2发布 3撤销
*/
public
final
static
String
NEWS_STATUS
=
"BIZ0007"
;
public
class
NewsStatus
{
public
static
final
int
NEW
=
1
;
// 新建
public
static
final
int
RELEASE
=
2
;
// 发布
public
static
final
int
CANCEL
=
3
;
// 撤销
}
/**
* 评价状态 0未评价 1未审核 2已审核
*/
public
final
static
String
COMMENT_STATUS
=
""
;
public
class
CommentStatus
{
public
static
final
int
NO
=
0
;
// 0未评价
public
static
final
int
UN_CONFIRM
=
1
;
// 1未审核
public
static
final
int
CONFIRM
=
2
;
// 2已审核
}
/**
* 订单环节状态 1未处理 2已处理 3已拒绝 4已取消
*/
public
final
static
String
ORDER_NODE_STATUS
=
""
;
public
class
OrderNodeStatus
{
public
static
final
int
UNDO
=
1
;
// 1未处理
public
static
final
int
DONE
=
2
;
// 2已处理
public
static
final
int
REFUSE
=
3
;
// 3已拒绝
public
static
final
int
CANCEL
=
4
;
// 4已取消
}
/**
* 客户(被服务人自理)状态 1:客户完全不能自理 2:客户半自理
*/
public
final
static
String
ClientStatus
=
"BIZ0003"
;
public
class
ClientStatus
{
public
static
final
int
CANT_SELF_CARE
=
1
;
// 完全不能自理
public
static
final
int
SEMI_SELF_CARE
=
2
;
// 半自理
}
/**
* 护工等级
*/
public
final
static
String
CAREGIVER_LEVEL
=
"BIZ0006"
;
public
class
CaregiverLevel
{
public
static
final
int
ONE
=
1
;
// 初级护工
public
static
final
int
TWO
=
2
;
// 中级护工
public
static
final
int
THREE
=
3
;
// 高级护工
public
static
final
int
FOUR
=
4
;
// 金牌护工
}
/**
* 护工提现审批状态
*/
public
final
static
String
CAREGIVER_ACCOUNT_APPROVE_STATUS
=
"BIZ0010"
;
public
class
CaregiverAccountApproveStatus
{
public
static
final
int
UNDO
=
1
;
// 未审批
public
static
final
int
PASS
=
2
;
// 已通过
public
static
final
int
REFUSE
=
3
;
// 未通过
}
/**
* 护工钱包流水类型
*/
public
final
static
String
CAREGIVER_ACCOUNT_FLOW_TYPE
=
"BIZ0011"
;
public
class
CaregiverAccountFlowType
{
public
static
final
int
COMMISSION
=
1
;
// 结佣
public
static
final
int
WITHDRAWAL
=
2
;
// 提现
}
/**
* 账单表类型
*/
public
final
static
String
SERVICES_BILL_TYPE
=
"BIZ0012"
;
public
class
ServicesBillType
{
public
static
final
int
INCOME
=
1
;
// 收入
public
static
final
int
EXPEND
=
2
;
// 支出
}
public
final
static
String
ROLE_TYPE
=
"BIZ0001"
;
}
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