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
a27081b0
Commit
a27081b0
authored
Aug 05, 2022
by
shangtx
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' into 'master'
feat: 小程序消息 See merge request
!8
parents
fdf2a9ff
929efa84
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
111 additions
and
158 deletions
+111
-158
pom.xml
common/pom.xml
+5
-0
MiniAppMessageService.java
...m/onsiteservice/common/service/MiniAppMessageService.java
+84
-0
ServiceOrderService.java
.../com/onsiteservice/service/order/ServiceOrderService.java
+8
-24
application-third-service.yaml
constant/src/main/resources/application-third-service.yaml
+4
-16
ServiceWorkerAssign.java
...com/onsiteservice/entity/service/ServiceWorkerAssign.java
+5
-3
pom.xml
mini-app/pom.xml
+0
-17
UserConvert.java
...eservice/miniapp/controller/user/convert/UserConvert.java
+0
-1
UserInfoVO.java
.../onsiteservice/miniapp/controller/user/vo/UserInfoVO.java
+1
-3
OrderListener.java
...onsiteservice/miniapp/service/listener/OrderListener.java
+2
-13
WeiXinService.java
...m/onsiteservice/miniapp/service/weixin/WeiXinService.java
+2
-4
WeixinMessageService.java
...eservice/miniapp/service/weixin/WeixinMessageService.java
+0
-77
No files found.
common/pom.xml
View file @
a27081b0
...
@@ -147,6 +147,11 @@
...
@@ -147,6 +147,11 @@
<version>
1.7.5
</version>
<version>
1.7.5
</version>
</dependency>
</dependency>
<dependency>
<groupId>
com.github.binarywang
</groupId>
<artifactId>
wx-java-miniapp-spring-boot-starter
</artifactId>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
common/src/main/java/com/onsiteservice/common/service/MiniAppMessageService.java
0 → 100644
View file @
a27081b0
package
com
.
onsiteservice
.
common
.
service
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage
;
import
com.onsiteservice.dao.mapper.user.UserMapper
;
import
com.onsiteservice.entity.order.ServiceOrder
;
import
lombok.extern.slf4j.Slf4j
;
import
me.chanjar.weixin.common.error.WxErrorException
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
java.util.List
;
/**
* 小程序通知
*/
@Slf4j
@Service
public
class
MiniAppMessageService
{
@Resource
private
WxMaService
wxMaService
;
@Resource
private
UserMapper
userMapper
;
@Value
(
"${wx.miniapp.message-template.pay}"
)
private
String
payTmp
;
@Value
(
"${wx.miniapp.message-template.valuator}"
)
private
String
valuatorTmp
;
/**
* 小程序发送订阅消息
*/
public
void
sendSubscribeMsg
(
String
templateId
,
String
openId
,
List
<
WxMaSubscribeMessage
.
MsgData
>
data
)
{
try
{
wxMaService
.
getMsgService
().
sendSubscribeMsg
(
WxMaSubscribeMessage
.
builder
()
.
templateId
(
templateId
)
.
data
(
data
)
.
toUser
(
openId
)
.
build
());
}
catch
(
WxErrorException
e
)
{
log
.
error
(
"发送订阅消息异常"
,
e
);
}
}
/**
* 提醒支付消息
*
* @param order 订单对象
*/
@Async
public
void
sendPay
(
ServiceOrder
order
)
{
var
user
=
userMapper
.
selectByPrimaryKey
(
order
.
getAccountNo
());
// 计算剩余时间
var
left
=
order
.
getCancelTime
().
getTime
()
-
System
.
currentTimeMillis
();
var
leftStr
=
left
/
60000
+
"分"
+
(
left
/
1000
)
%
60
+
"秒"
;
List
<
WxMaSubscribeMessage
.
MsgData
>
data
=
List
.
of
(
new
WxMaSubscribeMessage
.
MsgData
(
"character_string1"
,
order
.
getOrderNo
()),
new
WxMaSubscribeMessage
.
MsgData
(
"phrase4"
,
"未支付"
),
new
WxMaSubscribeMessage
.
MsgData
(
"thing2"
,
order
.
getServiceName
()),
new
WxMaSubscribeMessage
.
MsgData
(
"amount3"
,
order
.
getPrice
()
+
"元"
),
new
WxMaSubscribeMessage
.
MsgData
(
"thing11"
,
leftStr
));
sendSubscribeMsg
(
payTmp
,
user
.
getOpenId
(),
data
);
}
@Async
public
void
sendValuator
(
ServiceOrder
order
,
String
remark
)
{
var
valuator
=
userMapper
.
selectByPrimaryKey
(
order
.
getValuatorId
());
var
user
=
userMapper
.
selectByPrimaryKey
(
order
.
getAccountNo
());
List
<
WxMaSubscribeMessage
.
MsgData
>
data
=
List
.
of
(
new
WxMaSubscribeMessage
.
MsgData
(
"character_string1"
,
order
.
getOrderNo
()),
new
WxMaSubscribeMessage
.
MsgData
(
"thing7"
,
order
.
getServiceName
()),
new
WxMaSubscribeMessage
.
MsgData
(
"thing11"
,
valuator
.
getUserName
()),
new
WxMaSubscribeMessage
.
MsgData
(
"phone_number16"
,
valuator
.
getPhone
()),
new
WxMaSubscribeMessage
.
MsgData
(
"thing5"
,
remark
));
sendSubscribeMsg
(
payTmp
,
user
.
getOpenId
(),
data
);
}
}
common/src/main/java/com/onsiteservice/service/order/ServiceOrderService.java
View file @
a27081b0
...
@@ -6,6 +6,7 @@ import com.onsiteservice.common.order.dto.FinishServiceOrderDTO;
...
@@ -6,6 +6,7 @@ import com.onsiteservice.common.order.dto.FinishServiceOrderDTO;
import
com.onsiteservice.common.order.dto.SendServiceOrderDTO
;
import
com.onsiteservice.common.order.dto.SendServiceOrderDTO
;
import
com.onsiteservice.common.order.dto.ValuationServiceOrderDTO
;
import
com.onsiteservice.common.order.dto.ValuationServiceOrderDTO
;
import
com.onsiteservice.common.service.CommonSmsService
;
import
com.onsiteservice.common.service.CommonSmsService
;
import
com.onsiteservice.common.service.MiniAppMessageService
;
import
com.onsiteservice.constant.constant.BizConstants
;
import
com.onsiteservice.constant.constant.BizConstants
;
import
com.onsiteservice.constant.constant.SysParamConstants
;
import
com.onsiteservice.constant.constant.SysParamConstants
;
import
com.onsiteservice.constant.enums.BizCodeEnum
;
import
com.onsiteservice.constant.enums.BizCodeEnum
;
...
@@ -27,6 +28,7 @@ import com.onsiteservice.entity.sys.SysParam;
...
@@ -27,6 +28,7 @@ import com.onsiteservice.entity.sys.SysParam;
import
com.onsiteservice.entity.sys.SysUser
;
import
com.onsiteservice.entity.sys.SysUser
;
import
com.onsiteservice.entity.user.User
;
import
com.onsiteservice.entity.user.User
;
import
com.onsiteservice.util.aliyun.SmsUtils
;
import
com.onsiteservice.util.aliyun.SmsUtils
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
...
@@ -45,39 +47,19 @@ import java.util.stream.Collectors;
...
@@ -45,39 +47,19 @@ import java.util.stream.Collectors;
@Service
@Service
@Slf4j
@Slf4j
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
@AllArgsConstructor
(
onConstructor_
=
{
@Autowired
})
public
class
ServiceOrderService
extends
AbstractMapper
<
ServiceOrder
>
{
public
class
ServiceOrderService
extends
AbstractMapper
<
ServiceOrder
>
{
/**
* 短信相关
*/
@Autowired
private
CommonSmsService
commonSmsService
;
private
CommonSmsService
commonSmsService
;
@Resource
private
ServiceOrderMapper
serviceOrderMapper
;
private
ServiceOrderMapper
serviceOrderMapper
;
@Resource
private
ServiceWorkerMapper
serviceWorkerMapper
;
private
ServiceWorkerMapper
serviceWorkerMapper
;
@Resource
private
ServiceWorkerAssignMapper
serviceWorkerAssignMapper
;
private
ServiceWorkerAssignMapper
serviceWorkerAssignMapper
;
@Resource
private
ServiceValuatorMapper
serviceValuatorMapper
;
@Resource
private
ServiceValuatorAssignMapper
serviceValuatorAssignMapper
;
private
ServiceValuatorAssignMapper
serviceValuatorAssignMapper
;
@Resource
private
UserMapper
userMapper
;
private
UserMapper
userMapper
;
@Autowired
private
RecordComponent
recordComponent
;
private
RecordComponent
recordComponent
;
@Resource
private
SysUserMapper
sysUserMapper
;
private
SysUserMapper
sysUserMapper
;
@Resource
private
SysParamMapper
sysParamMapper
;
private
SysParamMapper
sysParamMapper
;
private
MiniAppMessageService
miniAppMessageService
;
/**
/**
...
@@ -113,8 +95,9 @@ public class ServiceOrderService extends AbstractMapper<ServiceOrder> {
...
@@ -113,8 +95,9 @@ public class ServiceOrderService extends AbstractMapper<ServiceOrder> {
String
description
=
String
.
format
(
ServiceOrderStatusEnum
.
VALUATION
.
getMsg
(),
user
.
getName
(),
valuatorUser
.
getUserName
());
String
description
=
String
.
format
(
ServiceOrderStatusEnum
.
VALUATION
.
getMsg
(),
user
.
getName
(),
valuatorUser
.
getUserName
());
recordComponent
.
recordProcess
(
serviceOrder
.
getId
(),
ServiceOrderStatusEnum
.
VALUATION
.
getStatus
(),
description
,
recordComponent
.
recordProcess
(
serviceOrder
.
getId
(),
ServiceOrderStatusEnum
.
VALUATION
.
getStatus
(),
description
,
sourceEnum
,
valuatorUser
.
getId
(),
dto
.
getRemark
(),
dto
.
getExpectArrivalTime
());
sourceEnum
,
valuatorUser
.
getId
(),
dto
.
getRemark
(),
dto
.
getExpectArrivalTime
());
// 发送小程序通知
miniAppMessageService
.
sendValuator
(
serviceOrder
,
dto
.
getRemark
());
}
}
return
result
;
return
result
;
}
}
...
@@ -196,8 +179,9 @@ public class ServiceOrderService extends AbstractMapper<ServiceOrder> {
...
@@ -196,8 +179,9 @@ public class ServiceOrderService extends AbstractMapper<ServiceOrder> {
String
description
=
String
.
format
(
ServiceOrderStatusEnum
.
SEND
.
getMsg
(),
(
user
.
getIsAdmin
()
?
ServiceUserTypeEnum
.
ADMIN
.
getName
()
:
ServiceUserTypeEnum
.
VALUATOR
.
getName
())
+
user
.
getName
());
String
description
=
String
.
format
(
ServiceOrderStatusEnum
.
SEND
.
getMsg
(),
(
user
.
getIsAdmin
()
?
ServiceUserTypeEnum
.
ADMIN
.
getName
()
:
ServiceUserTypeEnum
.
VALUATOR
.
getName
())
+
user
.
getName
());
recordComponent
.
recordProcess
(
serviceOrder
.
getId
(),
ServiceOrderStatusEnum
.
SEND
.
getStatus
(),
description
,
sourceEnum
,
userId
,
null
,
null
);
recordComponent
.
recordProcess
(
serviceOrder
.
getId
(),
ServiceOrderStatusEnum
.
SEND
.
getStatus
(),
description
,
sourceEnum
,
userId
,
null
,
null
);
// 发送小程序消息
miniAppMessageService
.
sendPay
(
serviceOrder
);
}
}
return
result
;
return
result
;
}
}
...
...
constant/src/main/resources/application-third-service.yaml
View file @
a27081b0
...
@@ -37,21 +37,9 @@ wx:
...
@@ -37,21 +37,9 @@ wx:
token
:
#微信小程序消息服务器配置的token
token
:
#微信小程序消息服务器配置的token
aesKey
:
#微信小程序消息服务器配置的EncodingAESKey
aesKey
:
#微信小程序消息服务器配置的EncodingAESKey
msgDataFormat
:
JSON
msgDataFormat
:
JSON
# 公众号
message-template
:
mp
:
pay
:
ygS2cgt5SrFQ8yKe6VzF3tMYTTkbGDSHwXiJRPlExJE
# 待支付提醒
# TODO 暂时使用其他项目的
valuator
:
AFA-i9A_MrzxQzogJJot3EXY4j5bfOe4WFpl9VvA8Jg
# 指派估价员
appId
:
wxceb5bea07decc398
#公众号的appid
secret
:
d5e1aeae4fa4daa6328a6a02ddafb9ff
#公众号的appsecret
token
:
OfficialAccounts2020
#接口配置里的Token值
aesKey
:
EBFO9I8JUrLLYZxSd1QqO08LyheQX1ABGLeNylv8LoW
#接口配置里的EncodingAESKey值
# configs:
# - appId: wxceb5bea07decc398 #公众号的appid
# secret: d5e1aeae4fa4daa6328a6a02ddafb9ff #公众号的appsecret
# 微信支付
pay
:
appId
:
wx2c8a98f02c1a4258
#微信公众号或者小程序等的appid
mchId
:
1602411974
#微信支付商户号
# 公众号
###
entity/src/main/java/com/onsiteservice/entity/service/ServiceWorkerAssign.java
View file @
a27081b0
...
@@ -5,11 +5,13 @@ import io.swagger.annotations.ApiModelProperty;
...
@@ -5,11 +5,13 @@ import io.swagger.annotations.ApiModelProperty;
import
java.io.Serializable
;
import
java.io.Serializable
;
import
java.util.Date
;
import
java.util.Date
;
import
javax.persistence.*
;
import
javax.persistence.*
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.*
;
import
lombok.ToString
;
import
tk.mybatis.mapper.annotation.LogicDelete
;
import
tk.mybatis.mapper.annotation.LogicDelete
;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Getter
@Setter
@Setter
@ToString
@ToString
...
...
mini-app/pom.xml
View file @
a27081b0
...
@@ -20,23 +20,6 @@
...
@@ -20,23 +20,6 @@
<version>
1.0.0
</version>
<version>
1.0.0
</version>
</dependency>
</dependency>
<dependency>
<groupId>
com.github.binarywang
</groupId>
<artifactId>
wx-java-miniapp-spring-boot-starter
</artifactId>
</dependency>
<!--微信公众号-->
<dependency>
<groupId>
com.github.binarywang
</groupId>
<artifactId>
weixin-java-mp
</artifactId>
</dependency>
<!-- 微信公众号 -->
<dependency>
<groupId>
com.github.binarywang
</groupId>
<artifactId>
wx-java-mp-spring-boot-starter
</artifactId>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
mini-app/src/main/java/com/onsiteservice/miniapp/controller/user/convert/UserConvert.java
View file @
a27081b0
...
@@ -9,7 +9,6 @@ import org.mapstruct.Mappings;
...
@@ -9,7 +9,6 @@ import org.mapstruct.Mappings;
@Mapper
(
componentModel
=
"spring"
)
@Mapper
(
componentModel
=
"spring"
)
public
interface
UserConvert
{
public
interface
UserConvert
{
@Mappings
({
@Mapping
(
source
=
"sex"
,
target
=
"sexValue"
)})
UserInfoVO
toUserVO
(
User
user
);
UserInfoVO
toUserVO
(
User
user
);
}
}
mini-app/src/main/java/com/onsiteservice/miniapp/controller/user/vo/UserInfoVO.java
View file @
a27081b0
...
@@ -36,10 +36,8 @@ public class UserInfoVO {
...
@@ -36,10 +36,8 @@ public class UserInfoVO {
@ApiModelProperty
(
"头像"
)
@ApiModelProperty
(
"头像"
)
private
String
avatar
;
private
String
avatar
;
@ApiModelProperty
(
"性别"
)
private
Integer
sexValue
;
@ApiModelProperty
(
"性别
0: 未知 1: 男 2: 女
"
)
@ApiModelProperty
(
"性别"
)
private
String
sex
;
private
String
sex
;
@ApiModelProperty
(
"0 普通用户 1 客服 2 估价员 3 销售"
)
@ApiModelProperty
(
"0 普通用户 1 客服 2 估价员 3 销售"
)
...
...
mini-app/src/main/java/com/onsiteservice/miniapp/service/listener/OrderListener.java
View file @
a27081b0
package
com
.
onsiteservice
.
miniapp
.
service
.
listener
;
package
com
.
onsiteservice
.
miniapp
.
service
.
listener
;
import
com.onsiteservice.constant.constant.SysConstants
;
import
com.onsiteservice.miniapp.service.weixin.WeixinMessageService
;
import
org.springframework.amqp.rabbit.annotation.Queue
;
import
org.springframework.amqp.rabbit.annotation.RabbitHandler
;
import
org.springframework.amqp.rabbit.annotation.RabbitHandler
;
import
org.springframework.amqp.rabbit.annotation.RabbitListener
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.socket.TextMessage
;
import
javax.annotation.Resource
;
//@Component
//@RabbitListener(queuesToDeclare = @Queue(SysConstants.Queue.USER_ORDER))
@Component
@RabbitListener
(
queuesToDeclare
=
@Queue
(
SysConstants
.
Queue
.
USER_ORDER
))
public
class
OrderListener
{
public
class
OrderListener
{
@Resource
private
WeixinMessageService
weixinMessageService
;
@RabbitHandler
@RabbitHandler
public
void
notice
()
{
public
void
notice
()
{
weixinMessageService
.
sendMsg
(
null
);
}
}
...
...
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/WeiXinService.java
View file @
a27081b0
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
;
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.binarywang.wx.miniapp.api.WxMaService
;
import
cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor
;
import
cn.binarywang.wx.miniapp.bean.*
;
import
cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult
;
import
cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo
;
import
cn.binarywang.wx.miniapp.bean.WxMaUserInfo
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.ImmutableMap
;
import
com.onsiteservice.common.service.dto.MiniQrCodeDTO
;
import
com.onsiteservice.common.service.dto.MiniQrCodeDTO
;
import
com.onsiteservice.constant.enums.EnvironmentEnum
;
import
com.onsiteservice.constant.enums.EnvironmentEnum
;
...
@@ -27,6 +24,7 @@ import org.springframework.stereotype.Service;
...
@@ -27,6 +24,7 @@ import org.springframework.stereotype.Service;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.annotation.Transactional
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Optional
;
import
java.util.Optional
;
...
...
mini-app/src/main/java/com/onsiteservice/miniapp/service/weixin/WeixinMessageService.java
deleted
100644 → 0
View file @
fdf2a9ff
package
com
.
onsiteservice
.
miniapp
.
service
.
weixin
;
import
com.onsiteservice.util.DateUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
me.chanjar.weixin.mp.api.WxMpService
;
import
me.chanjar.weixin.mp.bean.template.WxMpTemplateData
;
import
me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.Date
;
import
java.util.LinkedList
;
import
java.util.List
;
/**
* 微信公众号消息服务
*/
@Service
@Slf4j
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
class
WeixinMessageService
{
@Autowired
private
WxMpService
wxService
;
/**
* 发送微信模板消息 批量发送处理
*/
public
void
sendMsg
(
List
<
WxMpTemplateMessage
>
wxMpTemplateMessages
)
{
for
(
WxMpTemplateMessage
msg
:
wxMpTemplateMessages
)
{
try
{
wxService
.
getTemplateMsgService
().
sendTemplateMsg
(
msg
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
String
errorMsg
=
e
.
getMessage
();
log
.
error
(
"微信模板推送异常:"
+
errorMsg
);
}
}
}
public
WxMpTemplateMessage
wxMpTemplateMessages
()
{
List
<
WxMpTemplateMessage
>
msgList
=
new
LinkedList
<>();
// 示例
WxMpTemplateData
keyword1
=
new
WxMpTemplateData
();
keyword1
.
setName
(
"keyword1"
);
// 报警来源
keyword1
.
setValue
(
""
);
keyword1
.
setColor
(
"#ff3334"
);
WxMpTemplateData
keyword2
=
new
WxMpTemplateData
();
keyword2
.
setName
(
"keyword2"
);
// 发生时间
keyword2
.
setValue
(
DateUtils
.
formatDate
(
new
Date
(),
"yyyy-MM-dd HH:mm:ss"
));
WxMpTemplateData
keyword3
=
new
WxMpTemplateData
();
keyword3
.
setName
(
"keyword3"
);
// 报警内容
keyword3
.
setValue
(
"dsadsd"
);
keyword3
.
setColor
(
"#ff3334"
);
WxMpTemplateData
remark
=
new
WxMpTemplateData
();
remark
.
setName
(
"remark"
);
remark
.
setValue
(
"请及时处理"
);
List
<
WxMpTemplateData
>
dataList
=
List
.
of
(
keyword1
,
keyword2
,
keyword3
,
remark
);
String
alarmNoticeTemplateId
=
""
;
// 消息模板id
String
openId
=
""
;
// 微信用户的公众号openId
String
appId
=
""
;
// appid
WxMpTemplateMessage
.
MiniProgram
miniProgram
=
new
WxMpTemplateMessage
.
MiniProgram
();
miniProgram
.
setAppid
(
appId
);
WxMpTemplateMessage
wxMpTemplateMessage
=
WxMpTemplateMessage
.
builder
()
.
templateId
(
alarmNoticeTemplateId
).
toUser
(
openId
).
miniProgram
(
miniProgram
)
.
data
(
dataList
).
build
();
// TODO
return
null
;
}
}
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