Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
8
8timerapiv200
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
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
8timerv2
8timerapiv200
Commits
d9e6f880
Commit
d9e6f880
authored
Apr 18, 2022
by
龙于生
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
新增h5颜色测评接口 模板消息 公众号绑定
parent
8e1c60c3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
524 additions
and
7 deletions
+524
-7
pom.xml
+6
-0
src/main/java/cn/timer/api/bean/zpgl/ZpglRcxx.java
+7
-0
src/main/java/cn/timer/api/bean/zpgl/ZpglWxgzptEmpRcxx.java
+1
-1
src/main/java/cn/timer/api/config/interceptor/WebSecurityConfig.java
+6
-1
src/main/java/cn/timer/api/controller/LoginController.java
+50
-2
src/main/java/cn/timer/api/controller/oss/OSSController.java
+34
-2
src/main/java/cn/timer/api/controller/verify/VerifyController.java
+39
-0
src/main/java/cn/timer/api/controller/zpgl/ZpglEvaluationController.java
+50
-0
src/main/java/cn/timer/api/controller/zpgl/ZpglWxgzptController.java
+0
-0
src/main/java/cn/timer/api/controller/zpgl/sevice/ZpglWxgzptService.java
+27
-0
src/main/java/cn/timer/api/dto/template/Miniprogram.java
+26
-0
src/main/java/cn/timer/api/dto/template/TemplateData.java
+39
-0
src/main/java/cn/timer/api/dto/template/TemplateMessage.java
+69
-0
src/main/java/cn/timer/api/dto/wxgzh/LoginDto.java
+30
-0
src/main/java/cn/timer/api/dto/wxgzh/MessageQueueDto.java
+115
-0
src/main/java/cn/timer/api/dto/zpgl/InterviewApplicationDto.java
+8
-0
src/main/resources/application-test.yml
+17
-1
No files found.
pom.xml
View file @
d9e6f880
...
...
@@ -436,6 +436,12 @@
<groupId>
org.springframework
</groupId>
<artifactId>
spring-test
</artifactId>
</dependency>
<dependency>
<groupId>
com.thoughtworks.xstream
</groupId>
<artifactId>
xstream
</artifactId>
<version>
1.4.9
</version>
</dependency>
</dependencies>
<repositories>
...
...
src/main/java/cn/timer/api/bean/zpgl/ZpglRcxx.java
View file @
d9e6f880
...
...
@@ -212,6 +212,13 @@ public class ZpglRcxx extends Model<ZpglRcxx> {
*/
@ApiModelProperty
(
value
=
"招聘渠道ID"
)
private
Integer
zpglZpqdId
;
/**
* 签名图片
*/
@ApiModelProperty
(
value
=
"签名图片"
)
private
String
signatureImg
;
/**
* 文件名
*/
...
...
src/main/java/cn/timer/api/bean/zpgl/ZpglWxgzptEmpRcxx.java
View file @
d9e6f880
...
...
@@ -67,7 +67,7 @@ public class ZpglWxgzptEmpRcxx extends Model<ZpglWxgzptEmpRcxx> {
* 组织机构代码
*/
@ApiModelProperty
(
value
=
"组织机构代码"
)
private
String
orgCode
;
private
Integer
orgCode
;
/**
* 逻辑删除标记0.未删除 1.删除
*/
...
...
src/main/java/cn/timer/api/config/interceptor/WebSecurityConfig.java
View file @
d9e6f880
...
...
@@ -52,7 +52,12 @@ public class WebSecurityConfig implements WebMvcConfigurer {
.
excludePathPatterns
(
"/webjars/**"
)
.
excludePathPatterns
(
"/zpgl/h5/**"
)
.
excludePathPatterns
(
"/yggl/mz/*"
)
.
excludePathPatterns
(
"/yggl/sysRegion"
);
.
excludePathPatterns
(
"/yggl/sysRegion"
)
.
excludePathPatterns
(
"/wxgzh/**"
)
.
excludePathPatterns
(
"/wxgzpt/**"
)
.
excludePathPatterns
(
"/MP_verify_VohzppEKB3VfeKxw.txt"
)
.
excludePathPatterns
(
"/evaluation/**"
)
.
excludePathPatterns
(
"/oss/uploadImg"
);
// registry.addInterceptor(getSessionInterceptor()).addPathPatterns("/**").excludePathPatterns("/swagger-ui*");
}
...
...
src/main/java/cn/timer/api/controller/LoginController.java
View file @
d9e6f880
...
...
@@ -7,11 +7,13 @@ import java.util.Date;
import
java.util.HashMap
;
import
java.util.List
;
import
javax.annotation.Resource
;
import
javax.servlet.ServletOutputStream
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpSession
;
import
cn.timer.api.utils.redis.RedisUtil
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
...
...
@@ -169,6 +171,9 @@ public class LoginController {
@Autowired
private
AliyunSMS
aliyunSMS
;
@Resource
private
RedisUtil
redisUtil
;
// @Autowired
// private DataSourceTransactionManager transactionManager;
...
...
@@ -253,9 +258,52 @@ public class LoginController {
String
message
=
j
.
getString
(
"Message"
);
if
(
"OK"
.
equals
(
message
))
{
session
.
setAttribute
(
phone
,
code
);
// redisTemplate.set(phone, code);
// redisTemplate.expire(phone, 60);
// redisTemplate.set(phone, code);
// redisTemplate.expire(phone, 60);
return
ResultUtil
.
data
(
"发送验证码成功"
);
}
else
{
return
ResultUtil
.
error
(
"发送验证码失败"
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
ResultUtil
.
error
(
"发送验证码失败"
);
}
}
/**
* 发送验证码
*
* @param entRegisterDto
* @return
*/
@PostMapping
(
value
=
"/sendcode1"
)
@ApiOperation
(
value
=
"1.发送验证码"
,
httpMethod
=
"POST"
,
notes
=
"接口发布说明"
)
@ApiOperationSupport
(
order
=
1
)
@Log
(
title
=
"发送验证码"
,
businessType
=
BusinessType
.
SEND_CODE
)
public
Result
<
String
>
sendCode1
(
@RequestBody
EntRegisterDto
entRegisterDto
)
{
String
phone
=
entRegisterDto
.
getPhone
();
if
(
phone
==
null
||
StrUtil
.
hasBlank
(
phone
))
{
return
ResultUtil
.
error
(
"请输入手机号"
);
}
// 6位随机数验证码
try
{
Integer
code
=
(
int
)
((
Math
.
random
()
*
9
+
1
)
*
100000
);
if
(
phone
==
null
||
""
.
equals
(
phone
))
{
phone
=
entRegisterDto
.
getUsername
();
entRegisterDto
.
setPhone
(
phone
);
}
List
<
Object
>
list
=
aliyunSMS
.
authCode
(
entRegisterDto
,
entRegisterDto
.
getTc
(),
code
);
Integer
useId
=
(
Integer
)
list
.
get
(
0
);
JSONObject
j
=
(
JSONObject
)
list
.
get
(
1
);
// 获取当前日期的字符串格式
String
message
=
j
.
getString
(
"Message"
);
if
(
"OK"
.
equals
(
message
))
{
session
.
setAttribute
(
phone
,
code
);
redisUtil
.
set
(
phone
,
code
,
60
*
5
);
return
ResultUtil
.
data
(
"发送验证码成功"
);
}
else
{
return
ResultUtil
.
error
(
"发送验证码失败"
);
...
...
src/main/java/cn/timer/api/controller/oss/OSSController.java
View file @
d9e6f880
package
cn
.
timer
.
api
.
controller
.
oss
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.*
;
import
cn.timer.api.service.OSSService
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
org.apache.ibatis.annotations.Param
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.transaction.annotation.Transactional
;
...
...
@@ -20,6 +21,8 @@ import cn.timer.api.utils.aliyun.OSSUtil;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
javax.servlet.http.HttpServletRequest
;
@Api
(
tags
=
"9.0阿里云OSS操作"
)
@Transactional
@RequestMapping
(
value
=
"/oss"
,
produces
=
{
"application/json"
})
...
...
@@ -176,4 +179,33 @@ public class OSSController {
return
data
;
}
@PostMapping
(
value
=
"/uploadImg"
)
@ApiOperation
(
value
=
"上传图片"
,
httpMethod
=
"POST"
,
notes
=
"接口发布说明"
)
@ResponseBody
public
Result
<
String
>
uploadImg
(
@RequestParam
(
required
=
true
)
String
param
,
@RequestParam
(
required
=
false
)
String
moudle
,
@Param
(
"file"
)
MultipartFile
file
)
throws
Exception
{
if
(
file
==
null
||
file
.
getSize
()
<=
0
)
{
return
ResultUtil
.
error
(
"上传的文件为空,请重新选择!"
);
}
Set
<
String
>
typeSet
=
new
HashSet
<>();
typeSet
.
add
(
".jpg"
);
typeSet
.
add
(
".png"
);
typeSet
.
add
(
".gif"
);
String
fileName
=
file
.
getOriginalFilename
();
int
index
=
fileName
.
lastIndexOf
(
"."
);
String
fileType
=
fileName
.
substring
(
index
);
//校验图片类型是否有效
if
(!
typeSet
.
contains
(
fileType
))
{
return
ResultUtil
.
error
(
"只能上传图片文件!"
);
}
JSONObject
jsonObject
=
JSON
.
parseObject
(
param
);
Integer
id
=
jsonObject
.
getInteger
(
"id"
);
String
orgid
=
jsonObject
.
getString
(
"orgid"
);
moudle
=
id
+
""
;
Result
<
String
>
data
=
ossService
.
upload
(
1
,
moudle
,
file
);
return
data
;
}
}
src/main/java/cn/timer/api/controller/verify/VerifyController.java
0 → 100644
View file @
d9e6f880
package
cn
.
timer
.
api
.
controller
.
verify
;
import
cn.timer.api.utils.wxgzh.SignUtil
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
/**
*
* @author longys
* @date 2022/3/30 15:35
*/
@RestController
@RequestMapping
(
"/"
)
public
class
VerifyController
{
/**
* 网页授权域名
* 验证文件
* @param response
*/
@GetMapping
(
"/MP_verify_VohzppEKB3VfeKxw.txt"
)
public
void
verify
(
HttpServletResponse
response
){
PrintWriter
out
=
null
;
try
{
out
=
response
.
getWriter
();
out
.
write
(
"VohzppEKB3VfeKxw"
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
finally
{
out
.
close
();
}
}
}
src/main/java/cn/timer/api/controller/zpgl/ZpglEvaluationController.java
0 → 100644
View file @
d9e6f880
package
cn
.
timer
.
api
.
controller
.
zpgl
;
import
cn.timer.api.bean.zpgl.ZpglCptk
;
import
cn.timer.api.bean.zpgl.ZpglDtk
;
import
cn.timer.api.utils.Result
;
import
cn.timer.api.utils.ResultUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
/**
* @author longys
* @date 2022/4/14 15:48
*/
@Api
(
tags
=
"性格颜色测评"
)
@RestController
@RequestMapping
(
value
=
"/evaluation"
)
public
class
ZpglEvaluationController
{
@ApiOperation
(
value
=
"获取测评题库"
,
httpMethod
=
"GET"
,
notes
=
"获取测评题库"
)
@RequestMapping
(
"/get_cptk_list"
)
public
Result
<
List
<
ZpglCptk
>>
getCptkList
(){
List
<
ZpglCptk
>
zpglCptks
=
ZpglCptk
.
builder
().
build
()
.
selectList
(
new
QueryWrapper
<
ZpglCptk
>().
lambda
().
orderByAsc
(
ZpglCptk:
:
getSort
));
return
ResultUtil
.
data
(
zpglCptks
);
}
@ApiOperation
(
value
=
"提交测评"
,
httpMethod
=
"POST"
,
notes
=
"提交测评"
)
@RequestMapping
(
"/add_evaluation"
)
public
Result
<
Object
>
addEvaluation
(
@RequestBody
ZpglDtk
zpglDtk
){
ZpglDtk
dtk
=
zpglDtk
.
selectOne
(
new
QueryWrapper
<
ZpglDtk
>()
.
lambda
().
eq
(
ZpglDtk:
:
getZpglRcxxId
,
zpglDtk
.
getZpglRcxxId
()));
if
(
dtk
!=
null
){
return
ResultUtil
.
error
(
"你已提交测评!"
);
}
try
{
zpglDtk
.
insert
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
ResultUtil
.
error
();
}
return
ResultUtil
.
success
();
}
}
src/main/java/cn/timer/api/controller/zpgl/ZpglWxgzptController.java
0 → 100644
View file @
d9e6f880
This diff is collapsed.
Click to expand it.
src/main/java/cn/timer/api/controller/zpgl/sevice/ZpglWxgzptService.java
0 → 100644
View file @
d9e6f880
package
cn
.
timer
.
api
.
controller
.
zpgl
.
sevice
;
import
cn.hutool.http.HttpUtil
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
java.util.Map
;
/**
* @author longys
* @date 2022/3/25 18:08
*/
@Service
public
class
ZpglWxgzptService
{
@Value
(
"${youling.serverUrl}"
)
private
String
serverUrl
;
/**
* 添加消息队列
* @param map
* @return
*/
public
String
addMessageQueue
(
Map
<
String
,
Object
>
map
){
return
HttpUtil
.
post
(
serverUrl
+
"/wxgzh/addMessageQueue"
,
map
);
}
}
src/main/java/cn/timer/api/dto/template/Miniprogram.java
0 → 100644
View file @
d9e6f880
package
cn
.
timer
.
api
.
dto
.
template
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
java.io.Serializable
;
/**
* 跳小程序所需数据
* @author longys
* @date 2022/3/23 15:48
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
Miniprogram
implements
Serializable
{
/**
*所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系)
*/
private
String
appid
;
/**
* 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),要求该小程序已发布
*/
private
String
pagepath
;
}
src/main/java/cn/timer/api/dto/template/TemplateData.java
0 → 100644
View file @
d9e6f880
package
cn
.
timer
.
api
.
dto
.
template
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author longys
* @date 2022/3/22 16:52
*/
@Data
public
class
TemplateData
implements
Serializable
{
// 参数名称
private
String
name
;
// 参数值
private
String
value
;
// 颜色
private
String
color
;
public
TemplateData
(
String
name
,
String
value
,
String
color
)
{
this
.
name
=
name
;
this
.
value
=
value
;
this
.
color
=
color
;
}
public
TemplateData
(
List
<
TemplateData
>
dateList
){
Map
<
String
,
Map
<
String
,
Object
>>
nameMap
=
new
HashMap
<>();
for
(
TemplateData
date
:
dateList
){
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"value"
,
date
.
getValue
());
map
.
put
(
"color"
,
date
.
getColor
());
nameMap
.
put
(
date
.
getName
(),
map
);
}
}
}
src/main/java/cn/timer/api/dto/template/TemplateMessage.java
0 → 100644
View file @
d9e6f880
package
cn
.
timer
.
api
.
dto
.
template
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* 模版消息发送对象
* @author longys
* @date 2022/3/22 16:51
*/
@Data
public
class
TemplateMessage
implements
Serializable
{
/**
* 接收者openid
*/
private
String
touser
;
/**
* 模版ID
*/
private
String
template_id
;
/**
* 跳转URL
*/
private
String
url
;
/**
* 跳小程序所需数据 不需跳小程序可不用传该数据
*/
private
Miniprogram
miniprogram
;
/**
* 模板数据
*/
private
Map
<
String
,
Map
<
String
,
Object
>>
data
;
public
TemplateMessage
(
List
<
TemplateData
>
dateList
,
String
touser
,
String
templateId
,
String
url
,
Miniprogram
miniprogram
){
Map
<
String
,
Map
<
String
,
Object
>>
nameMap
=
new
HashMap
<>();
for
(
TemplateData
date
:
dateList
){
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"value"
,
date
.
getValue
());
map
.
put
(
"color"
,
date
.
getColor
());
nameMap
.
put
(
date
.
getName
(),
map
);
}
this
.
data
=
nameMap
;
this
.
touser
=
touser
;
this
.
template_id
=
templateId
;
//以下不需要跳转传 null
this
.
url
=
url
;
this
.
miniprogram
=
miniprogram
;
};
public
TemplateMessage
(
Map
<
String
,
Map
<
String
,
Object
>>
data
,
String
touser
,
String
templateId
,
String
url
,
Miniprogram
miniprogram
){
this
.
data
=
data
;
this
.
touser
=
touser
;
this
.
template_id
=
templateId
;
//以下不需要跳转传 null
this
.
url
=
url
;
this
.
miniprogram
=
miniprogram
;
};
}
\ No newline at end of file
src/main/java/cn/timer/api/dto/wxgzh/LoginDto.java
0 → 100644
View file @
d9e6f880
package
cn
.
timer
.
api
.
dto
.
wxgzh
;
import
cn.timer.api.dto.login.QysDto
;
import
lombok.Data
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author longys
* @date 2022/3/30 16:46
*/
@Data
public
class
LoginDto
{
private
String
phone
;
private
String
code
;
private
String
openid
;
/**
* 姓名
*/
private
String
userName
;
/**
* 个人头像
*/
private
String
avatar
;
}
src/main/java/cn/timer/api/dto/wxgzh/MessageQueueDto.java
0 → 100644
View file @
d9e6f880
package
cn
.
timer
.
api
.
dto
.
wxgzh
;
import
cn.timer.api.dto.template.Miniprogram
;
import
cn.timer.api.dto.template.TemplateData
;
import
com.alibaba.fastjson.JSON
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author longys
* @date 2022/4/2 17:31
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
MessageQueueDto
{
/**
* id
*/
@TableId
(
type
=
IdType
.
AUTO
)
private
Long
id
;
/**
* 内容 、 公众号模板消息内容 是JSON格式
*/
private
String
content
;
/**
* 类型(1 短信,2 邮件,3 微信模板消息)
*/
private
Integer
type
;
/**
* 状态(0 发送成功,1 未发送,2 发送失败)
*/
private
Integer
status
;
/**
* 手机号码
*/
private
String
mobile
;
/**
* 邮箱
*/
private
String
email
;
/**
* 微信openid
*/
private
String
openid
;
/**
* 模版消息id (发送公众号模板消息用到)
*/
private
String
templateId
;
/**
* 业务类型
*/
private
Integer
tos
;
/**
* 公众号配置表id
*/
private
Integer
wxgzhType
;
/**
* 网页地址
*/
private
String
url
;
/**
* 小程序页面配置表id
*/
private
Long
wxxcxPageId
;
/**
* 创建时间
*/
private
Date
createTime
;
/**
* 更新时间
*/
private
Date
updateTime
;
@TableField
(
exist
=
false
)
private
static
final
long
serialVersionUID
=
1L
;
/**
* 转json格式模板消息内容
* @param dateList
* @return
*/
public
String
getContentJson
(
List
<
TemplateData
>
dateList
){
Map
<
String
,
Map
<
String
,
Object
>>
nameMap
=
new
HashMap
<>();
for
(
TemplateData
date
:
dateList
){
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"value"
,
date
.
getValue
());
map
.
put
(
"color"
,
date
.
getColor
());
nameMap
.
put
(
date
.
getName
(),
map
);
}
return
JSON
.
toJSONString
(
nameMap
);
};
}
src/main/java/cn/timer/api/dto/zpgl/InterviewApplicationDto.java
View file @
d9e6f880
...
...
@@ -240,6 +240,12 @@ public class InterviewApplicationDto implements Serializable {
private
Integer
zpglZpqdId
;
/**
* 签名图片
*/
@ApiModelProperty
(
value
=
"签名图片"
)
private
String
signatureImg
;
/**
* 职位信息ID
*/
@ApiModelProperty
(
value
=
"职位信息ID"
)
...
...
@@ -268,4 +274,6 @@ public class InterviewApplicationDto implements Serializable {
@ApiModelProperty
(
value
=
"家庭资料"
)
private
List
<
ZpglRcxxJtzl
>
zpglRcxxJtzls
;
}
src/main/resources/application-test.yml
View file @
d9e6f880
...
...
@@ -239,4 +239,20 @@ sftp:
serverUrl
:
'
https://test-img.8timer.cn'
targetPath
:
'
/disk'
reservedName
:
false
#微信公众号(服务号)
wxgzh
:
appid
:
'
wxd331ab19a67e2319'
appSecret
:
'
31259f6fee0c0771d6f48c3d5159c551'
#我方token 在微信公众号基本配置里面配置( token = 8timer123 md5加密得)
token
:
'
af37997effca937229453180e830b164'
#消息加解密密钥
encodingAesKey
:
'
chAbt69dLAtk8HH0oGMuZwHzK2SuhnxZI5Jbzc4nNzX'
youling
:
serverUrl
:
'
http://227387db45.51vip.biz'
#h5服务地址
h5
:
url
:
'
http://javays.com'
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