Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
midjourney-proxy
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
徐少华
midjourney-proxy
Commits
9ea039ee
Commit
9ea039ee
authored
Feb 14, 2020
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
5分钟未订阅提醒
parent
c028db92
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
498 additions
and
13 deletions
+498
-13
SkillService.java
...main/java/com/pcloud/book/skill/service/SkillService.java
+22
-0
SelfRobotKeywordBiz.java
...ava/com/pcloud/book/keywords/biz/SelfRobotKeywordBiz.java
+1
-1
SelfRobotKeywordBizImpl.java
...cloud/book/keywords/biz/impl/SelfRobotKeywordBizImpl.java
+23
-1
SelfRobotKeywordFacade.java
...m/pcloud/book/keywords/facade/SelfRobotKeywordFacade.java
+1
-1
SelfRobotKeywordFacadeImpl.java
...book/keywords/facade/impl/SelfRobotKeywordFacadeImpl.java
+2
-2
PcloudSubRemindBiz.java
...in/java/com/pcloud/book/skill/biz/PcloudSubRemindBiz.java
+13
-0
PcloudSkillBizImpl.java
...va/com/pcloud/book/skill/biz/impl/PcloudSkillBizImpl.java
+15
-0
PcloudSubRemindBizImpl.java
...om/pcloud/book/skill/biz/impl/PcloudSubRemindBizImpl.java
+0
-0
PcloudSkillCheck.java
...in/java/com/pcloud/book/skill/check/PcloudSkillCheck.java
+45
-1
PcloudSubRemindDao.java
...in/java/com/pcloud/book/skill/dao/PcloudSubRemindDao.java
+19
-0
PcloudSubRemindDaoImpl.java
...om/pcloud/book/skill/dao/impl/PcloudSubRemindDaoImpl.java
+44
-0
PcloudSkill.java
...c/main/java/com/pcloud/book/skill/entity/PcloudSkill.java
+3
-0
PcloudSubRemind.java
...in/java/com/pcloud/book/skill/entity/PcloudSubRemind.java
+63
-0
PcloudSubReply.java
...ain/java/com/pcloud/book/skill/entity/PcloudSubReply.java
+10
-1
SubTypeEnum.java
...rc/main/java/com/pcloud/book/skill/enums/SubTypeEnum.java
+6
-1
RedisTool.java
...src/main/java/com/pcloud/book/skill/remind/RedisTool.java
+80
-0
RemindSchedule.java
...ain/java/com/pcloud/book/skill/remind/RemindSchedule.java
+25
-0
SkillServiceImpl.java
.../com/pcloud/book/skill/service/impl/SkillServiceImpl.java
+25
-0
TaskSubscribeBizImpl.java
...cloud/book/timecontrol/biz/impl/TaskSubscribeBizImpl.java
+5
-0
PcloudSubRemind.Mapper.xml
...rc/main/resources/mapper/skill/PcloudSubRemind.Mapper.xml
+75
-0
PcloudSubReply.xml
...e-book/src/main/resources/mapper/skill/PcloudSubReply.xml
+21
-5
No files found.
pcloud-facade-book/src/main/java/com/pcloud/book/skill/service/SkillService.java
0 → 100644
View file @
9ea039ee
package
com
.
pcloud
.
book
.
skill
.
service
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.cloud.netflix.feign.FeignClient
;
import
org.springframework.web.bind.annotation.GetMapping
;
/**
* @Description:TODO
* @Author:zy
* @Date:2020-02-13
* @Version:1.0
*/
@FeignClient
(
value
=
"pcloud-service-book"
,
qualifier
=
"skillServiceCloud"
,
path
=
"/book/v1.0/skillService"
)
@Api
(
description
=
"技能内部接口"
)
public
interface
SkillService
{
@ApiOperation
(
value
=
"定时发送任务消息"
,
httpMethod
=
"GET"
)
@GetMapping
(
"skillRemindMessage"
)
void
skillRemindMessage
();
}
\ No newline at end of file
pcloud-service-book/src/main/java/com/pcloud/book/keywords/biz/SelfRobotKeywordBiz.java
View file @
9ea039ee
...
@@ -50,7 +50,7 @@ public interface SelfRobotKeywordBiz {
...
@@ -50,7 +50,7 @@ public interface SelfRobotKeywordBiz {
SelfRobotKeyword
getById
(
Long
id
);
SelfRobotKeyword
getById
(
Long
id
);
RobotSkillDetail
getSkillDetail
(
Integer
type
,
Integer
relSkillId
,
String
wxUserId
);
RobotSkillDetail
getSkillDetail
(
Integer
type
,
Integer
relSkillId
,
String
wxUserId
,
String
robotWxId
,
Integer
skillId
);
String
confirmSkill
(
Integer
id
,
Integer
type
,
Integer
relSkillId
,
String
robotId
,
String
wxUserId
);
String
confirmSkill
(
Integer
id
,
Integer
type
,
Integer
relSkillId
,
String
robotId
,
String
wxUserId
);
}
}
pcloud-service-book/src/main/java/com/pcloud/book/keywords/biz/impl/SelfRobotKeywordBizImpl.java
View file @
9ea039ee
...
@@ -30,12 +30,15 @@ import com.pcloud.book.keywords.vo.GuideWordVO;
...
@@ -30,12 +30,15 @@ import com.pcloud.book.keywords.vo.GuideWordVO;
import
com.pcloud.book.keywords.vo.LabelVO
;
import
com.pcloud.book.keywords.vo.LabelVO
;
import
com.pcloud.book.keywords.vo.SelfRobotReplyVO
;
import
com.pcloud.book.keywords.vo.SelfRobotReplyVO
;
import
com.pcloud.book.skill.biz.PcloudGroupActivityBiz
;
import
com.pcloud.book.skill.biz.PcloudGroupActivityBiz
;
import
com.pcloud.book.skill.biz.PcloudSubRemindBiz
;
import
com.pcloud.book.skill.biz.impl.PcloudSkillBizImpl
;
import
com.pcloud.book.skill.biz.impl.PcloudSkillBizImpl
;
import
com.pcloud.book.skill.dao.PcloudGroupActivityDao
;
import
com.pcloud.book.skill.dao.PcloudGroupActivityDao
;
import
com.pcloud.book.skill.dao.PcloudResourceDao
;
import
com.pcloud.book.skill.dao.PcloudResourceDao
;
import
com.pcloud.book.skill.dao.PcloudSkillDao
;
import
com.pcloud.book.skill.dao.PcloudSkillDao
;
import
com.pcloud.book.skill.dao.PcloudSubRemindDao
;
import
com.pcloud.book.skill.entity.PcloudGroupActivity
;
import
com.pcloud.book.skill.entity.PcloudGroupActivity
;
import
com.pcloud.book.skill.entity.PcloudSkill
;
import
com.pcloud.book.skill.entity.PcloudSkill
;
import
com.pcloud.book.skill.entity.PcloudSubRemind
;
import
com.pcloud.book.skill.facade.response.QueryPcloudResponseVO
;
import
com.pcloud.book.skill.facade.response.QueryPcloudResponseVO
;
import
com.pcloud.book.timecontrol.biz.TaskBiz
;
import
com.pcloud.book.timecontrol.biz.TaskBiz
;
import
com.pcloud.book.timecontrol.biz.TaskSubscribeBiz
;
import
com.pcloud.book.timecontrol.biz.TaskSubscribeBiz
;
...
@@ -139,6 +142,11 @@ public class SelfRobotKeywordBizImpl implements SelfRobotKeywordBiz {
...
@@ -139,6 +142,11 @@ public class SelfRobotKeywordBizImpl implements SelfRobotKeywordBiz {
private
PcloudSkillBizImpl
pcloudSkillBiz
;
private
PcloudSkillBizImpl
pcloudSkillBiz
;
@Autowired
@Autowired
private
TimeControlTaskSubscribeMapper
timeControlTaskSubscribeMapper
;
private
TimeControlTaskSubscribeMapper
timeControlTaskSubscribeMapper
;
@Autowired
private
PcloudSubRemindBiz
pcloudSubRemindBiz
;
@Autowired
private
PcloudSubRemindDao
pcloudSubRemindDao
;
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
...
@@ -628,7 +636,7 @@ public class SelfRobotKeywordBizImpl implements SelfRobotKeywordBiz {
...
@@ -628,7 +636,7 @@ public class SelfRobotKeywordBizImpl implements SelfRobotKeywordBiz {
}
}
@Override
@Override
public
RobotSkillDetail
getSkillDetail
(
Integer
type
,
Integer
relSkillId
,
String
wxUserId
)
{
public
RobotSkillDetail
getSkillDetail
(
Integer
type
,
Integer
relSkillId
,
String
wxUserId
,
String
robotWxId
,
Integer
skillId
)
{
if
(
null
==
type
||
null
==
relSkillId
){
if
(
null
==
type
||
null
==
relSkillId
){
throw
new
BizException
(
BizException
.
PARAM_IS_NULL
.
getCode
(),
"type为空或者relSkillId为空"
);
throw
new
BizException
(
BizException
.
PARAM_IS_NULL
.
getCode
(),
"type为空或者relSkillId为空"
);
}
}
...
@@ -662,6 +670,18 @@ public class SelfRobotKeywordBizImpl implements SelfRobotKeywordBiz {
...
@@ -662,6 +670,18 @@ public class SelfRobotKeywordBizImpl implements SelfRobotKeywordBiz {
}
}
}
}
PcloudSubRemind
pcloudSubRemind
=
pcloudSubRemindDao
.
getByMap
(
relSkillId
,
type
,
wxUserId
,
skillId
);
if
(
null
==
pcloudSubRemind
)
{
PcloudSubRemind
subRemind
=
new
PcloudSubRemind
();
subRemind
.
setCreateTime
(
new
Date
());
subRemind
.
setRelSkillId
(
relSkillId
);
subRemind
.
setRobotWxId
(
robotWxId
);
subRemind
.
setSkillType
(
type
);
subRemind
.
setSubscribeState
(
0
);
subRemind
.
setWxUserId
(
wxUserId
);
subRemind
.
setSkillId
(
Long
.
valueOf
(
skillId
));
pcloudSubRemindDao
.
insert
(
subRemind
);
}
return
robotSkillDetail
;
return
robotSkillDetail
;
}
}
...
@@ -686,6 +706,8 @@ public class SelfRobotKeywordBizImpl implements SelfRobotKeywordBiz {
...
@@ -686,6 +706,8 @@ public class SelfRobotKeywordBizImpl implements SelfRobotKeywordBiz {
}
else
if
(
3
==
type
){
}
else
if
(
3
==
type
){
pcloudSkillBiz
.
sendResource
(
id
,
wxUserId
,
robotId
,
relSkillId
);
pcloudSkillBiz
.
sendResource
(
id
,
wxUserId
,
robotId
,
relSkillId
);
}
}
//修改pcloud_sub_remind 未订阅提醒表状态
pcloudSubRemindBiz
.
updateSubState
(
relSkillId
,
type
,
wxUserId
,
id
);
return
skillFuseReply
;
return
skillFuseReply
;
}
}
...
...
pcloud-service-book/src/main/java/com/pcloud/book/keywords/facade/SelfRobotKeywordFacade.java
View file @
9ea039ee
...
@@ -114,7 +114,7 @@ public interface SelfRobotKeywordFacade {
...
@@ -114,7 +114,7 @@ public interface SelfRobotKeywordFacade {
@ApiOperation
(
value
=
"根据任务id获取任务详情"
,
httpMethod
=
"GET"
)
@ApiOperation
(
value
=
"根据任务id获取任务详情"
,
httpMethod
=
"GET"
)
@GetMapping
(
"getSkillDetail"
)
@GetMapping
(
"getSkillDetail"
)
ResponseDto
<?>
getSkillDetail
(
Integer
type
,
Integer
relSkillId
,
String
wxUserId
);
ResponseDto
<?>
getSkillDetail
(
Integer
type
,
Integer
relSkillId
,
String
wxUserId
,
String
robotWxId
,
Integer
skillId
);
@ApiOperation
(
value
=
"确认任务"
,
httpMethod
=
"GET"
)
@ApiOperation
(
value
=
"确认任务"
,
httpMethod
=
"GET"
)
@GetMapping
(
"confirmSkill"
)
@GetMapping
(
"confirmSkill"
)
...
...
pcloud-service-book/src/main/java/com/pcloud/book/keywords/facade/impl/SelfRobotKeywordFacadeImpl.java
View file @
9ea039ee
...
@@ -170,8 +170,8 @@ public class SelfRobotKeywordFacadeImpl implements SelfRobotKeywordFacade {
...
@@ -170,8 +170,8 @@ public class SelfRobotKeywordFacadeImpl implements SelfRobotKeywordFacade {
@Override
@Override
@GetMapping
(
"getSkillDetail"
)
@GetMapping
(
"getSkillDetail"
)
public
ResponseDto
<?>
getSkillDetail
(
@RequestParam
Integer
type
,
@RequestParam
Integer
relSkillId
,
@RequestParam
String
wxUserId
)
{
public
ResponseDto
<?>
getSkillDetail
(
@RequestParam
Integer
type
,
@RequestParam
Integer
relSkillId
,
@RequestParam
String
wxUserId
,
@RequestParam
String
robotWxId
,
@RequestParam
Integer
skillId
)
{
RobotSkillDetail
robotSkillDetail
=
selfRobotKeywordBiz
.
getSkillDetail
(
type
,
relSkillId
,
wxUserId
);
RobotSkillDetail
robotSkillDetail
=
selfRobotKeywordBiz
.
getSkillDetail
(
type
,
relSkillId
,
wxUserId
,
robotWxId
,
skillId
);
return
new
ResponseDto
<>(
robotSkillDetail
);
return
new
ResponseDto
<>(
robotSkillDetail
);
}
}
...
...
pcloud-service-book/src/main/java/com/pcloud/book/skill/biz/PcloudSubRemindBiz.java
0 → 100644
View file @
9ea039ee
package
com
.
pcloud
.
book
.
skill
.
biz
;
public
interface
PcloudSubRemindBiz
{
void
updateSubState
(
Integer
relSkillId
,
Integer
skillType
,
String
wxUserId
,
Integer
skillId
);
/**
* 定时发送任务消息
*/
void
sendTimeTaskMessage
();
}
pcloud-service-book/src/main/java/com/pcloud/book/skill/biz/impl/PcloudSkillBizImpl.java
View file @
9ea039ee
...
@@ -80,6 +80,7 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
...
@@ -80,6 +80,7 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
pcloudSkillDao
.
insert
(
pcloudSkill
);
pcloudSkillDao
.
insert
(
pcloudSkill
);
addSuccessReplies
(
pcloudSkill
);
addSuccessReplies
(
pcloudSkill
);
addCancelReplies
(
pcloudSkill
);
addCancelReplies
(
pcloudSkill
);
addNoReplies
(
pcloudSkill
);
}
}
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
...
@@ -93,6 +94,7 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
...
@@ -93,6 +94,7 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
//新增订阅回复
//新增订阅回复
addSuccessReplies
(
pcloudSkill
);
addSuccessReplies
(
pcloudSkill
);
addCancelReplies
(
pcloudSkill
);
addCancelReplies
(
pcloudSkill
);
addNoReplies
(
pcloudSkill
);
}
}
@ParamLog
(
"获取技能"
)
@ParamLog
(
"获取技能"
)
...
@@ -106,6 +108,7 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
...
@@ -106,6 +108,7 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
fillRelies
(
replies
);
fillRelies
(
replies
);
pcloudSkill
.
setSuccessSubReplies
(
replies
.
stream
().
filter
(
s
->
s
!=
null
&&
SubTypeEnum
.
SUCCESS
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
pcloudSkill
.
setSuccessSubReplies
(
replies
.
stream
().
filter
(
s
->
s
!=
null
&&
SubTypeEnum
.
SUCCESS
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
pcloudSkill
.
setCancelSubReplies
(
replies
.
stream
().
filter
(
s
->
s
!=
null
&&
SubTypeEnum
.
CANCEL
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
pcloudSkill
.
setCancelSubReplies
(
replies
.
stream
().
filter
(
s
->
s
!=
null
&&
SubTypeEnum
.
CANCEL
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
pcloudSkill
.
setNoSubReplies
(
replies
.
stream
().
filter
(
s
->
s
!=
null
&&
SubTypeEnum
.
NOSUBSCRIBE
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
fillTitleAndDetail
(
pcloudSkill
);
fillTitleAndDetail
(
pcloudSkill
);
return
pcloudSkill
;
return
pcloudSkill
;
}
}
...
@@ -134,6 +137,7 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
...
@@ -134,6 +137,7 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
if
(!
ListUtils
.
isEmpty
(
replyList
)){
if
(!
ListUtils
.
isEmpty
(
replyList
)){
pcloudSkill
.
setSuccessSubReplies
(
replyList
.
stream
().
filter
(
s
->
SubTypeEnum
.
SUCCESS
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
pcloudSkill
.
setSuccessSubReplies
(
replyList
.
stream
().
filter
(
s
->
SubTypeEnum
.
SUCCESS
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
pcloudSkill
.
setCancelSubReplies
(
replyList
.
stream
().
filter
(
s
->
SubTypeEnum
.
CANCEL
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
pcloudSkill
.
setCancelSubReplies
(
replyList
.
stream
().
filter
(
s
->
SubTypeEnum
.
CANCEL
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
pcloudSkill
.
setNoSubReplies
(
replyList
.
stream
().
filter
(
s
->
SubTypeEnum
.
NOSUBSCRIBE
.
value
.
equals
(
s
.
getSubType
())).
collect
(
Collectors
.
toList
()));
}
}
}
}
fillTitleAndDetailList
(
page
.
getRecordList
());
fillTitleAndDetailList
(
page
.
getRecordList
());
...
@@ -390,6 +394,17 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
...
@@ -390,6 +394,17 @@ public class PcloudSkillBizImpl implements PcloudSkillBiz {
}
}
pcloudSubReplyDao
.
batchInsert
(
cancelReplies
);
pcloudSubReplyDao
.
batchInsert
(
cancelReplies
);
}
}
@ParamLog
(
"新增未订阅回复"
)
private
void
addNoReplies
(
PcloudSkill
pcloudSkill
){
List
<
PcloudSubReply
>
noSubReplies
=
pcloudSkill
.
getNoSubReplies
();
if
(
ListUtils
.
isEmpty
(
noSubReplies
)){
return
;
}
for
(
PcloudSubReply
reply:
noSubReplies
){
reply
.
setPcloudSkillId
(
pcloudSkill
.
getId
());
}
pcloudSubReplyDao
.
batchInsert
(
noSubReplies
);
}
private
void
sendSubReplyMessage
(
List
<
PcloudSubReply
>
subReplyList
,
String
robotWxId
,
String
userWxId
)
{
private
void
sendSubReplyMessage
(
List
<
PcloudSubReply
>
subReplyList
,
String
robotWxId
,
String
userWxId
)
{
this
.
fillRelies
(
subReplyList
);
this
.
fillRelies
(
subReplyList
);
for
(
PcloudSubReply
reply
:
subReplyList
)
{
for
(
PcloudSubReply
reply
:
subReplyList
)
{
...
...
pcloud-service-book/src/main/java/com/pcloud/book/skill/biz/impl/PcloudSubRemindBizImpl.java
0 → 100644
View file @
9ea039ee
This diff is collapsed.
Click to expand it.
pcloud-service-book/src/main/java/com/pcloud/book/skill/check/PcloudSkillCheck.java
View file @
9ea039ee
...
@@ -3,7 +3,6 @@ package com.pcloud.book.skill.check;
...
@@ -3,7 +3,6 @@ package com.pcloud.book.skill.check;
import
com.pcloud.book.base.exception.BookBizException
;
import
com.pcloud.book.base.exception.BookBizException
;
import
com.pcloud.book.keywords.enums.ReplyTypeEnum
;
import
com.pcloud.book.keywords.enums.ReplyTypeEnum
;
import
com.pcloud.book.skill.entity.PcloudSkill
;
import
com.pcloud.book.skill.entity.PcloudSkill
;
import
com.pcloud.book.skill.entity.PcloudSkillGuide
;
import
com.pcloud.book.skill.entity.PcloudSubReply
;
import
com.pcloud.book.skill.entity.PcloudSubReply
;
import
com.pcloud.common.core.aspect.ParamLog
;
import
com.pcloud.common.core.aspect.ParamLog
;
import
com.pcloud.common.utils.ListUtils
;
import
com.pcloud.common.utils.ListUtils
;
...
@@ -29,6 +28,51 @@ public class PcloudSkillCheck {
...
@@ -29,6 +28,51 @@ public class PcloudSkillCheck {
}
}
checkReply
(
pcloudSkill
.
getCancelSubReplies
());
checkReply
(
pcloudSkill
.
getCancelSubReplies
());
checkReply
(
pcloudSkill
.
getSuccessSubReplies
());
checkReply
(
pcloudSkill
.
getSuccessSubReplies
());
checkRemindReply
(
pcloudSkill
.
getNoSubReplies
());
}
private
void
checkRemindReply
(
List
<
PcloudSubReply
>
list
){
if
(!
ListUtils
.
isEmpty
(
list
))
{
if
(
list
.
size
()
>
3
)
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"至多填写3条订阅提醒!"
);
}
for
(
PcloudSubReply
reply
:
list
)
{
if
(
reply
==
null
)
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"回复不能为空!"
);
}
if
(
null
==
reply
.
getSubType
())
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"订阅类型不能为空!"
);
}
if
(
null
==
reply
.
getType
())
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"回复类型不能为空!"
);
}
Integer
type
=
reply
.
getType
();
if
(
ReplyTypeEnum
.
TEXT
.
value
.
equals
(
type
)
&&
StringUtil
.
isEmpty
(
reply
.
getContent
()))
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"内容不能为空!"
);
}
if
(
ReplyTypeEnum
.
IMAGE
.
value
.
equals
(
type
)
&&
StringUtil
.
isEmpty
(
reply
.
getPicUrl
()))
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"图片地址不能为空!"
);
}
if
(
ReplyTypeEnum
.
APP
.
value
.
equals
(
type
)
&&
(
StringUtil
.
isEmpty
(
reply
.
getServeType
())
||
reply
.
getServeId
()
==
null
||
StringUtil
.
isEmpty
(
reply
.
getLinkUrl
())))
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"应用或作品id和类型、链接不能为空!"
);
}
if
(
ReplyTypeEnum
.
RESOURCE
.
value
.
equals
(
type
)
&&
reply
.
getResourceId
()
==
null
)
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"资源id不能为空!"
);
}
if
(
null
==
reply
.
getRemindIntervalTime
())
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"提醒间隔不能为空!"
);
}
if
(
null
==
reply
.
getRemindIntervalTime
())
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"提醒间隔不能为空!"
);
}
if
(
null
==
reply
.
getSubLinkConfirm
())
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"是否发送订阅链接不能为空!"
);
}
if
(
1
==
reply
.
getSubLinkConfirm
()
&&
null
==
reply
.
getSubLinkIntroduce
())
{
throw
new
BookBizException
(
BookBizException
.
PARAM_IS_ERROR
,
"快速订阅链接介绍不能为空!"
);
}
}
}
}
}
private
void
checkReply
(
List
<
PcloudSubReply
>
list
){
private
void
checkReply
(
List
<
PcloudSubReply
>
list
){
...
...
pcloud-service-book/src/main/java/com/pcloud/book/skill/dao/PcloudSubRemindDao.java
0 → 100644
View file @
9ea039ee
package
com
.
pcloud
.
book
.
skill
.
dao
;
import
com.pcloud.book.skill.entity.PcloudSubRemind
;
import
com.pcloud.common.core.dao.BaseDao
;
import
java.util.List
;
/**
* @author lily
* @date 2019/4/23 15:53
*/
public
interface
PcloudSubRemindDao
extends
BaseDao
<
PcloudSubRemind
>
{
void
updateSubState
(
Integer
relSkillId
,
Integer
skillType
,
String
wxUserId
,
Integer
skillId
);
List
<
PcloudSubRemind
>
getUnSubRecord
();
PcloudSubRemind
getByMap
(
Integer
relSkillId
,
Integer
skillType
,
String
wxUserId
,
Integer
skillId
);
}
pcloud-service-book/src/main/java/com/pcloud/book/skill/dao/impl/PcloudSubRemindDaoImpl.java
0 → 100644
View file @
9ea039ee
package
com
.
pcloud
.
book
.
skill
.
dao
.
impl
;
import
com.pcloud.book.skill.dao.PcloudSubRemindDao
;
import
com.pcloud.book.skill.entity.PcloudSubRemind
;
import
com.pcloud.common.core.dao.BaseDaoImpl
;
import
org.springframework.stereotype.Component
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author lily
* @date 2019/4/23 15:54
*/
@Component
(
"pcloudSubRemindDao"
)
public
class
PcloudSubRemindDaoImpl
extends
BaseDaoImpl
<
PcloudSubRemind
>
implements
PcloudSubRemindDao
{
@Override
public
void
updateSubState
(
Integer
relSkillId
,
Integer
skillType
,
String
wxUserId
,
Integer
skillId
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"relSkillId"
,
relSkillId
);
map
.
put
(
"skillType"
,
skillType
);
map
.
put
(
"wxUserId"
,
wxUserId
);
map
.
put
(
"skillId"
,
skillId
);
super
.
getSqlSession
().
update
(
getStatement
(
"updateSubState"
),
map
);
}
@Override
public
List
<
PcloudSubRemind
>
getUnSubRecord
()
{
return
super
.
getSqlSession
().
selectList
(
getStatement
(
"getUnSubRecord"
));
}
@Override
public
PcloudSubRemind
getByMap
(
Integer
relSkillId
,
Integer
skillType
,
String
wxUserId
,
Integer
skillId
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"relSkillId"
,
relSkillId
);
map
.
put
(
"skillType"
,
skillType
);
map
.
put
(
"wxUserId"
,
wxUserId
);
map
.
put
(
"skillId"
,
skillId
);
return
super
.
getSqlSession
().
selectOne
(
getStatement
(
"getByMap"
),
map
);
}
}
pcloud-service-book/src/main/java/com/pcloud/book/skill/entity/PcloudSkill.java
View file @
9ea039ee
...
@@ -35,4 +35,7 @@ public class PcloudSkill extends BaseEntity {
...
@@ -35,4 +35,7 @@ public class PcloudSkill extends BaseEntity {
@ApiModelProperty
(
"技能简介"
)
@ApiModelProperty
(
"技能简介"
)
private
String
detail
;
private
String
detail
;
@ApiModelProperty
(
"点击未订阅回复集合"
)
private
List
<
PcloudSubReply
>
noSubReplies
;
}
}
pcloud-service-book/src/main/java/com/pcloud/book/skill/entity/PcloudSubRemind.java
0 → 100644
View file @
9ea039ee
package
com
.
pcloud
.
book
.
skill
.
entity
;
import
com.pcloud.common.entity.BaseEntity
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
java.util.Date
;
/**
* @author lily
* @date 2019/4/23 15:03
*/
@Data
public
class
PcloudSubRemind
extends
BaseEntity
{
/**
* 主键id
*/
private
Long
id
;
/**
* 微信id
*/
private
String
wxUserId
;
/**
* 个人号id
*/
private
String
robotWxId
;
/**
* 技能类型:1时间管理,2共读活动,3配套资料,4教辅书单,5配套老师,6音乐
*/
private
Integer
skillType
;
/**
* 任务id
*/
private
Integer
relSkillId
;
/**
* 订阅状态
*/
private
Integer
subscribeState
;
/**
* 创建时间
*/
private
Date
createTime
;
/**
* 修改时间
*/
private
Date
updateTime
;
@ApiModelProperty
(
"技能Id"
)
private
Long
skillId
;
}
pcloud-service-book/src/main/java/com/pcloud/book/skill/entity/PcloudSubReply.java
View file @
9ea039ee
...
@@ -16,7 +16,7 @@ public class PcloudSubReply extends BaseEntity {
...
@@ -16,7 +16,7 @@ public class PcloudSubReply extends BaseEntity {
@ApiModelProperty
(
"技能id"
)
@ApiModelProperty
(
"技能id"
)
private
Long
pcloudSkillId
;
private
Long
pcloudSkillId
;
@ApiModelProperty
(
"订阅回复类型:1成功,2取消"
)
@ApiModelProperty
(
"订阅回复类型:1成功,2取消
,3未订阅提醒
"
)
private
Integer
subType
;
private
Integer
subType
;
@ApiModelProperty
(
"类型 1 文字 2 图片 3 链接 4应用 5素材"
)
@ApiModelProperty
(
"类型 1 文字 2 图片 3 链接 4应用 5素材"
)
...
@@ -81,4 +81,13 @@ public class PcloudSubReply extends BaseEntity {
...
@@ -81,4 +81,13 @@ public class PcloudSubReply extends BaseEntity {
@ApiModelProperty
(
"文件转码后的单张图片集合"
)
@ApiModelProperty
(
"文件转码后的单张图片集合"
)
private
List
<
ResourceOfficeItemDTO
>
resourceOfficeItemDTOs
;
private
List
<
ResourceOfficeItemDTO
>
resourceOfficeItemDTOs
;
@ApiModelProperty
(
"未订阅提醒消息间隔时间(秒)"
)
private
Integer
remindIntervalTime
;
@ApiModelProperty
(
"未订阅发送订阅链接是否开启"
)
private
Integer
subLinkConfirm
;
@ApiModelProperty
(
"未订阅发送订阅链接介绍"
)
private
String
subLinkIntroduce
;
}
}
pcloud-service-book/src/main/java/com/pcloud/book/skill/enums/SubTypeEnum.java
View file @
9ea039ee
...
@@ -10,7 +10,12 @@ public enum SubTypeEnum {
...
@@ -10,7 +10,12 @@ public enum SubTypeEnum {
/**
/**
* 取消订阅
* 取消订阅
*/
*/
CANCEL
(
2
);
CANCEL
(
2
),
/**
* 未订阅提醒
*/
NOSUBSCRIBE
(
3
);
/**
/**
* 值
* 值
*/
*/
...
...
pcloud-service-book/src/main/java/com/pcloud/book/skill/remind/RedisTool.java
0 → 100644
View file @
9ea039ee
package
com
.
pcloud
.
book
.
skill
.
remind
;
import
com.pcloud.common.utils.cache.redis.JedisClusterUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
redis.clients.jedis.exceptions.JedisException
;
import
java.util.UUID
;
public
class
RedisTool
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
RedisTool
.
class
);
/**
* 加锁
* @param lockName 锁的key
* @param acquireTimeout 获取超时时间
* @param timeout 锁的超时时间
* @return 锁标识
*/
public
static
String
lockWithTimeout
(
String
lockName
,
long
acquireTimeout
,
long
timeout
)
{
String
retIdentifier
=
null
;
try
{
// 随机生成一个value
String
identifier
=
UUID
.
randomUUID
().
toString
();
// 锁名,即key值
String
lockKey
=
"lock:"
+
lockName
;
// 超时时间,上锁后超过此时间则自动释放锁
int
lockExpire
=
(
int
)
(
timeout
/
1000
);
// 获取锁的超时时间,超过这个时间则放弃获取锁
long
end
=
System
.
currentTimeMillis
()
+
acquireTimeout
;
while
(
System
.
currentTimeMillis
()
<
end
)
{
if
(
JedisClusterUtils
.
setnx
(
lockKey
,
identifier
))
{
JedisClusterUtils
.
expire
(
lockKey
,
lockExpire
);
retIdentifier
=
identifier
;
return
retIdentifier
;
}
try
{
Thread
.
sleep
(
10
);
}
catch
(
InterruptedException
e
)
{
Thread
.
currentThread
().
interrupt
();
}
}
}
catch
(
JedisException
e
)
{
LOGGER
.
error
(
e
.
getMessage
(),
e
);
}
return
retIdentifier
;
}
/**
* 释放锁
* @param lockName 锁的key
* @param identifier 释放锁的标识
* @return
*/
public
static
boolean
releaseLock
(
String
lockName
,
String
identifier
)
{
String
lockKey
=
"lock:"
+
lockName
;
boolean
retFlag
=
false
;
try
{
if
(
identifier
.
equals
(
JedisClusterUtils
.
get
(
lockKey
)))
{
JedisClusterUtils
.
del
(
lockKey
);
retFlag
=
true
;
}
}
catch
(
JedisException
e
)
{
LOGGER
.
error
(
e
.
getMessage
(),
e
);
}
return
retFlag
;
}
public
static
boolean
lock
(
String
key
){
//加锁,如果返回1为true,表示已经加锁,如果再来存储同一个key会返回0为false
Boolean
flag
=
JedisClusterUtils
.
setnx
(
key
,
"lock"
);
//如果为true的话,设置一个过期时间,防止锁释放不掉
if
(
flag
){
JedisClusterUtils
.
expire
(
key
,
50
);
}
return
flag
;
}
}
pcloud-service-book/src/main/java/com/pcloud/book/skill/remind/RemindSchedule.java
0 → 100644
View file @
9ea039ee
package
com
.
pcloud
.
book
.
skill
.
remind
;
import
com.pcloud.book.skill.biz.PcloudSubRemindBiz
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.scheduling.annotation.Scheduled
;
import
org.springframework.stereotype.Component
;
@Component
(
"remindSchedule"
)
public
class
RemindSchedule
{
@Autowired
private
PcloudSubRemindBiz
pcloudSubRemindBiz
;
@Scheduled
(
cron
=
"0 * * * * ?"
)
public
void
skillRemindMessage
()
{
String
key
=
"REMIND_SCHEDULE"
;
while
(!
RedisTool
.
lock
(
key
)){
return
;
}
new
Thread
(()
->
{
pcloudSubRemindBiz
.
sendTimeTaskMessage
();
}).
start
();
}
}
pcloud-service-book/src/main/java/com/pcloud/book/skill/service/impl/SkillServiceImpl.java
0 → 100644
View file @
9ea039ee
package
com
.
pcloud
.
book
.
skill
.
service
.
impl
;
import
com.pcloud.book.skill.biz.PcloudSubRemindBiz
;
import
com.pcloud.book.skill.service.SkillService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
(
"skillService"
)
@RequestMapping
(
"skillService"
)
public
class
SkillServiceImpl
implements
SkillService
{
@Autowired
private
PcloudSubRemindBiz
pcloudSubRemindBiz
;
@Override
@GetMapping
(
"skillRemindMessage"
)
public
void
skillRemindMessage
()
{
/* new Thread(() -> {
pcloudSubRemindBiz.sendTimeTaskMessage();
}).start();*/
}
}
pcloud-service-book/src/main/java/com/pcloud/book/timecontrol/biz/impl/TaskSubscribeBizImpl.java
View file @
9ea039ee
...
@@ -9,6 +9,7 @@ import com.pcloud.book.consumer.resource.ProductConsr;
...
@@ -9,6 +9,7 @@ import com.pcloud.book.consumer.resource.ProductConsr;
import
com.pcloud.book.consumer.wechatgroup.WechatGroupConsr
;
import
com.pcloud.book.consumer.wechatgroup.WechatGroupConsr
;
import
com.pcloud.book.group.biz.WeixinQrcodeBiz
;
import
com.pcloud.book.group.biz.WeixinQrcodeBiz
;
import
com.pcloud.book.keywords.enums.ReplyTypeEnum
;
import
com.pcloud.book.keywords.enums.ReplyTypeEnum
;
import
com.pcloud.book.skill.biz.PcloudSubRemindBiz
;
import
com.pcloud.book.skill.dao.PcloudSkillDao
;
import
com.pcloud.book.skill.dao.PcloudSkillDao
;
import
com.pcloud.book.skill.dao.PcloudSubReplyDao
;
import
com.pcloud.book.skill.dao.PcloudSubReplyDao
;
import
com.pcloud.book.skill.entity.PcloudSkill
;
import
com.pcloud.book.skill.entity.PcloudSkill
;
...
@@ -109,6 +110,8 @@ public class TaskSubscribeBizImpl implements TaskSubscribeBiz {
...
@@ -109,6 +110,8 @@ public class TaskSubscribeBizImpl implements TaskSubscribeBiz {
private
PcloudSubReplyDao
pcloudSubReplyDao
;
private
PcloudSubReplyDao
pcloudSubReplyDao
;
@Autowired
@Autowired
private
ResourceConsr
resourceConsr
;
private
ResourceConsr
resourceConsr
;
@Autowired
private
PcloudSubRemindBiz
pcloudSubRemindBiz
;
@Value
(
"${wechat.group.link.prefix}"
)
@Value
(
"${wechat.group.link.prefix}"
)
private
String
wechatGroupLinkPrefix
;
private
String
wechatGroupLinkPrefix
;
...
@@ -174,6 +177,8 @@ public class TaskSubscribeBizImpl implements TaskSubscribeBiz {
...
@@ -174,6 +177,8 @@ public class TaskSubscribeBizImpl implements TaskSubscribeBiz {
});
});
}
}
});
});
//修改pcloud_sub_remind表状态
pcloudSubRemindBiz
.
updateSubState
(
taskId
,
SkillTypeEnum
.
TIME_MANAGE
.
value
,
wxUserId
,
null
);
LOGGER
.
info
(
"222"
);
LOGGER
.
info
(
"222"
);
}
}
...
...
pcloud-service-book/src/main/resources/mapper/skill/PcloudSubRemind.Mapper.xml
0 → 100644
View file @
9ea039ee
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd" >
<mapper
namespace=
"com.pcloud.book.skill.dao.impl.PcloudSubRemindDaoImpl"
>
<resultMap
id=
"BaseResultMap"
type=
"com.pcloud.book.skill.entity.PcloudSubRemind"
>
<id
column=
"id"
property=
"id"
jdbcType=
"BIGINT"
/>
<result
column=
"wx_user_id"
property=
"wxUserId"
jdbcType=
"VARCHAR"
/>
<result
column=
"robot_wx_id"
property=
"robotWxId"
jdbcType=
"VARCHAR"
/>
<result
column=
"skill_type"
property=
"skillType"
jdbcType=
"TINYINT"
/>
<result
column=
"rel_skill_id"
property=
"relSkillId"
jdbcType=
"BIGINT"
/>
<result
column=
"subscribe_state"
property=
"subscribeState"
jdbcType=
"TINYINT"
/>
<result
column=
"update_time"
property=
"updateTime"
jdbcType=
"TIMESTAMP"
/>
<result
column=
"create_time"
property=
"createTime"
jdbcType=
"TIMESTAMP"
/>
<result
column=
"skill_id"
property=
"skillId"
jdbcType=
"INTEGER"
/>
</resultMap>
<sql
id=
"Base_Column_List"
>
id, wx_user_id, robot_wx_id, skill_type, rel_skill_id, subscribe_state, create_time,update_time,skill_id
</sql>
<insert
id=
"insert"
parameterType=
"com.pcloud.book.skill.entity.PcloudSubRemind"
useGeneratedKeys=
"true"
keyProperty=
"id"
>
insert into pcloud_sub_remind
<trim
prefix=
"("
suffix=
")"
suffixOverrides=
","
>
wx_user_id, robot_wx_id, skill_type, rel_skill_id, subscribe_state, create_time,update_time,skill_id
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
#{wxUserId},
#{robotWxId},
#{skillType},
#{relSkillId},
#{subscribeState},
now(),
NOW(),
#{skillId}
</trim>
</insert>
<select
id=
"updateSubState"
parameterType=
"map"
>
update pcloud_sub_remind
set
subscribe_state=1,
update_time=now()
where
wx_user_id=#{wxUserId}
and rel_skill_id=#{relSkillId}
and skill_type=#{skillType}
<if
test=
"skillId !=null"
>
and skill_id=#{skillId}
</if>
</select>
<select
id=
"getUnSubRecord"
resultMap=
"BaseResultMap"
>
select
<include
refid=
"Base_Column_List"
/>
from pcloud_sub_remind
where subscribe_state=0
</select>
<select
id=
"getByMap"
resultMap=
"BaseResultMap"
>
select
<include
refid=
"Base_Column_List"
/>
from pcloud_sub_remind
where
wx_user_id=#{wxUserId}
and rel_skill_id=#{relSkillId}
and skill_type=#{skillType}
<if
test=
"skillId !=null"
>
and skill_id=#{skillId}
</if>
limit 1
</select>
</mapper>
\ No newline at end of file
pcloud-service-book/src/main/resources/mapper/skill/PcloudSubReply.xml
View file @
9ea039ee
...
@@ -14,10 +14,14 @@
...
@@ -14,10 +14,14 @@
<result
column=
"serve_type"
property=
"serveType"
jdbcType=
"BIGINT"
/>
<result
column=
"serve_type"
property=
"serveType"
jdbcType=
"BIGINT"
/>
<result
column=
"resource_id"
property=
"resourceId"
jdbcType=
"BIGINT"
/>
<result
column=
"resource_id"
property=
"resourceId"
jdbcType=
"BIGINT"
/>
<result
column=
"create_time"
property=
"createTime"
jdbcType=
"TIMESTAMP"
/>
<result
column=
"create_time"
property=
"createTime"
jdbcType=
"TIMESTAMP"
/>
<result
column=
"remind_interval_time"
property=
"remindIntervalTime"
jdbcType=
"INTEGER"
/>
<result
column=
"sub_link_confirm"
property=
"subLinkConfirm"
jdbcType=
"INTEGER"
/>
<result
column=
"sub_link_introduce"
property=
"subLinkIntroduce"
jdbcType=
"VARCHAR"
/>
</resultMap>
</resultMap>
<sql
id=
"Base_Column_List"
>
<sql
id=
"Base_Column_List"
>
id ,pcloud_skill_id ,sub_type ,type ,content ,description ,link_url ,pic_url ,serve_id ,serve_type ,resource_id ,create_time
id ,pcloud_skill_id ,sub_type ,type ,content ,description ,link_url ,pic_url ,serve_id ,serve_type ,resource_id ,create_time,remind_interval_time
,sub_link_confirm,sub_link_introduce
</sql>
</sql>
<select
id=
"getById"
resultMap=
"BaseResultMap"
parameterType=
"java.lang.Long"
>
<select
id=
"getById"
resultMap=
"BaseResultMap"
parameterType=
"java.lang.Long"
>
...
@@ -40,7 +44,10 @@
...
@@ -40,7 +44,10 @@
serve_id ,
serve_id ,
serve_type ,
serve_type ,
resource_id ,
resource_id ,
create_time
create_time,
remind_interval_time,
sub_link_confirm,
sub_link_introduce
</trim>
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
#{pcloudSkillId,jdbcType=BIGINT},
#{pcloudSkillId,jdbcType=BIGINT},
...
@@ -53,7 +60,10 @@
...
@@ -53,7 +60,10 @@
#{serveId,jdbcType=BIGINT},
#{serveId,jdbcType=BIGINT},
#{serveType,jdbcType=VARCHAR},
#{serveType,jdbcType=VARCHAR},
#{resourceId,jdbcType=BIGINT},
#{resourceId,jdbcType=BIGINT},
NOW()
NOW(),
#{remindIntervalTime},
#{subLinkConfirm},
#{subLinkIntroduce}
</trim>
</trim>
</insert>
</insert>
<insert
id=
"batchInsert"
parameterType=
"com.pcloud.book.skill.entity.PcloudSubReply"
useGeneratedKeys=
"true"
keyProperty=
"id"
>
<insert
id=
"batchInsert"
parameterType=
"com.pcloud.book.skill.entity.PcloudSubReply"
useGeneratedKeys=
"true"
keyProperty=
"id"
>
...
@@ -68,7 +78,10 @@
...
@@ -68,7 +78,10 @@
serve_id ,
serve_id ,
serve_type ,
serve_type ,
resource_id ,
resource_id ,
create_time
create_time,
remind_interval_time,
sub_link_confirm,
sub_link_introduce
) values
) values
<foreach
collection=
"list"
item=
"item"
index=
"index"
separator=
","
>
<foreach
collection=
"list"
item=
"item"
index=
"index"
separator=
","
>
(
(
...
@@ -82,7 +95,10 @@
...
@@ -82,7 +95,10 @@
#{item.serveId,jdbcType=BIGINT},
#{item.serveId,jdbcType=BIGINT},
#{item.serveType,jdbcType=VARCHAR},
#{item.serveType,jdbcType=VARCHAR},
#{item.resourceId,jdbcType=BIGINT},
#{item.resourceId,jdbcType=BIGINT},
NOW()
NOW(),
#{item.remindIntervalTime,jdbcType=INTEGER},
#{item.subLinkConfirm ,jdbcType=INTEGER},
#{item.subLinkIntroduce,jdbcType=VARCHAR}
)
)
</foreach>
</foreach>
</insert>
</insert>
...
...
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