记得上下班打卡 | git大法好,push需谨慎
Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
liquidnet-bus-v1
Project
Project
Details
Activity
Releases
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
董敬伟
liquidnet-bus-v1
Commits
8f336e96
Commit
8f336e96
authored
Oct 29, 2021
by
jiangxiulong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
draw mysql
parent
b55704c4
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
136 additions
and
10 deletions
+136
-10
MQConst.java
...ain/java/com/liquidnet/service/base/constant/MQConst.java
+2
-1
ConsumerSweetIntegralActivityDrawRedisStreamConfig.java
...g/ConsumerSweetIntegralActivityDrawRedisStreamConfig.java
+77
-0
ConsumerIntegralActivityDrawRdsReceiver.java
...eet/receiver/ConsumerIntegralActivityDrawRdsReceiver.java
+17
-0
redis_queue_create.txt
...rvice/liquidnet-service-sweet/docu/redis_queue_create.txt
+5
-1
SweetIntegralActivityDrawServiceImpl.java
...et/service/impl/SweetIntegralActivityDrawServiceImpl.java
+31
-7
sqlmap.properties
...uidnet-service-sweet/src/main/resources/sqlmap.properties
+4
-1
No files found.
liquidnet-bus-common/liquidnet-common-service-base/src/main/java/com/liquidnet/service/base/constant/MQConst.java
View file @
8f336e96
...
@@ -75,7 +75,7 @@ public class MQConst {
...
@@ -75,7 +75,7 @@ public class MQConst {
public
enum
SweetQueue
{
public
enum
SweetQueue
{
ARTISTS_RELATION
(
"sweet:stream:rk.artists.relation"
,
"group.artists.relation"
,
"用户-关系"
),
ARTISTS_RELATION
(
"sweet:stream:rk.artists.relation"
,
"group.artists.relation"
,
"用户-关系"
),
ARTISTS_RELATION_MDSK
(
"sweet:stream:rk.artists.mdsk.relation"
,
"group.artists.mdsk.relation"
,
"用户-关系"
),
ARTISTS_RELATION_MDSK
(
"sweet:stream:rk.artists.mdsk.relation"
,
"group.artists.mdsk.relation"
,
"用户-关系"
),
LUCK_DRAW
(
"sweet:stream:rk.luckDraw"
,
"group.luckDraw"
,
"用户-抽奖"
),
LUCK_DRAW
(
"sweet:stream:rk.luckDraw"
,
"group.luckDraw"
,
"用户-抽奖"
),
ANSWERINSERT_DRAW
(
"sweet:stream:rk.answerInsert"
,
"group.answerInsert"
,
"答案"
),
ANSWERINSERT_DRAW
(
"sweet:stream:rk.answerInsert"
,
"group.answerInsert"
,
"答案"
),
...
@@ -85,6 +85,7 @@ public class MQConst {
...
@@ -85,6 +85,7 @@ public class MQConst {
SWEET_TEMPLATE_MSG
(
"sweet:stream:rk.sweetTemplateMsg"
,
"group.sweetTemplateMsg"
,
"发送模版消息"
),
SWEET_TEMPLATE_MSG
(
"sweet:stream:rk.sweetTemplateMsg"
,
"group.sweetTemplateMsg"
,
"发送模版消息"
),
SWEET_CITY_VOTE_DRAW
(
"sweet:stream:rk.cityVote"
,
"group.cityVote"
,
"用户投票记录"
),
SWEET_CITY_VOTE_DRAW
(
"sweet:stream:rk.cityVote"
,
"group.cityVote"
,
"用户投票记录"
),
SWEET_ANTIGENIC_QUESTION_DRAW
(
"sweet:stream:rk.antigenicQuestion"
,
"group.antigenicQuestion"
,
"防疫答题"
),
SWEET_ANTIGENIC_QUESTION_DRAW
(
"sweet:stream:rk.antigenicQuestion"
,
"group.antigenicQuestion"
,
"防疫答题"
),
SWEET_INTEGRAL_ACTIVITY_DRAW
(
"sweet:stream:rk.integralActivityDraw"
,
"group.integralActivityDraw"
,
"积分抽奖"
),
;
;
private
final
String
key
;
private
final
String
key
;
...
...
liquidnet-bus-service/liquidnet-service-consumer-all/liquidnet-service-consumer-sweet/src/main/java/com/liquidnet/service/consumer/sweet/config/ConsumerSweetIntegralActivityDrawRedisStreamConfig.java
0 → 100644
View file @
8f336e96
package
com
.
liquidnet
.
service
.
consumer
.
sweet
.
config
;
import
com.liquidnet.service.consumer.sweet.receiver.ConsumerIntegralActivityDrawRdsReceiver
;
import
lombok.var
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.connection.stream.Consumer
;
import
org.springframework.data.redis.connection.stream.MapRecord
;
import
org.springframework.data.redis.connection.stream.ReadOffset
;
import
org.springframework.data.redis.connection.stream.StreamOffset
;
import
org.springframework.data.redis.stream.StreamMessageListenerContainer
;
import
org.springframework.data.redis.stream.Subscription
;
import
java.time.Duration
;
import
static
com
.
liquidnet
.
service
.
base
.
constant
.
MQConst
.
SweetQueue
.
SWEET_INTEGRAL_ACTIVITY_DRAW
;
@Configuration
public
class
ConsumerSweetIntegralActivityDrawRedisStreamConfig
{
@Autowired
ConsumerIntegralActivityDrawRdsReceiver
consumerIntegralActivityDrawRdsReceiver
;
private
StreamMessageListenerContainer
<
String
,
MapRecord
<
String
,
String
,
String
>>
buildStreamMessageListenerContainer
(
RedisConnectionFactory
factory
)
{
var
options
=
StreamMessageListenerContainer
.
StreamMessageListenerContainerOptions
.
builder
()
.
pollTimeout
(
Duration
.
ofMillis
(
1
))
.
build
();
return
StreamMessageListenerContainer
.
create
(
factory
,
options
);
}
/**
* 缺票登记
*
* @param listenerContainer
* @param t
* @return
*/
private
Subscription
receiveSqlIntegralActivityDraw
(
StreamMessageListenerContainer
<
String
,
MapRecord
<
String
,
String
,
String
>>
listenerContainer
,
int
t
)
{
return
listenerContainer
.
receiveAutoAck
(
Consumer
.
from
(
SWEET_INTEGRAL_ACTIVITY_DRAW
.
getGroup
(),
SWEET_INTEGRAL_ACTIVITY_DRAW
.
name
()
+
t
),
StreamOffset
.
create
(
SWEET_INTEGRAL_ACTIVITY_DRAW
.
getKey
(),
ReadOffset
.
lastConsumed
()),
consumerIntegralActivityDrawRdsReceiver
);
}
/* —————————————————————————— | —————————————————————————— | —————————————————————————— */
/* -------------------------------------------------------- | 缺票登记 */
@Bean
public
Subscription
subscriptionSqlIntegralActivityDraw
(
RedisConnectionFactory
factory
)
{
var
listenerContainer
=
this
.
buildStreamMessageListenerContainer
(
factory
);
var
subscription
=
receiveSqlIntegralActivityDraw
(
listenerContainer
,
1
);
listenerContainer
.
start
();
return
subscription
;
}
@Bean
public
Subscription
subscriptionSqlIntegralActivityDraw2
(
RedisConnectionFactory
factory
)
{
var
listenerContainer
=
this
.
buildStreamMessageListenerContainer
(
factory
);
var
subscription
=
receiveSqlIntegralActivityDraw
(
listenerContainer
,
1
);
listenerContainer
.
start
();
return
subscription
;
}
@Bean
public
Subscription
subscriptionSqlIntegralActivityDraw3
(
RedisConnectionFactory
factory
)
{
var
listenerContainer
=
this
.
buildStreamMessageListenerContainer
(
factory
);
var
subscription
=
receiveSqlIntegralActivityDraw
(
listenerContainer
,
1
);
listenerContainer
.
start
();
return
subscription
;
}
/* -------------------------------------------------------- | */
}
liquidnet-bus-service/liquidnet-service-consumer-all/liquidnet-service-consumer-sweet/src/main/java/com/liquidnet/service/consumer/sweet/receiver/ConsumerIntegralActivityDrawRdsReceiver.java
0 → 100644
View file @
8f336e96
package
com
.
liquidnet
.
service
.
consumer
.
sweet
.
receiver
;
import
com.liquidnet.service.base.constant.MQConst
;
import
org.springframework.stereotype.Component
;
@Component
public
class
ConsumerIntegralActivityDrawRdsReceiver
extends
AbstractSqlRedisReceiver
{
@Override
protected
String
getRedisStreamKey
()
{
return
MQConst
.
SweetQueue
.
SWEET_INTEGRAL_ACTIVITY_DRAW
.
getKey
();
}
@Override
protected
String
getRedisStreamGroup
()
{
return
MQConst
.
SweetQueue
.
SWEET_INTEGRAL_ACTIVITY_DRAW
.
getGroup
();
}
}
liquidnet-bus-service/liquidnet-service-sweet/docu/redis_queue_create.txt
View file @
8f336e96
...
@@ -35,4 +35,8 @@ XGROUP CREATE sweet:stream:rk.cityVote group.cityVote 0
...
@@ -35,4 +35,8 @@ XGROUP CREATE sweet:stream:rk.cityVote group.cityVote 0
-- 防疫答题 --
-- 防疫答题 --
XADD sweet:stream:rk.antigenicQuestion * 0 0
XADD sweet:stream:rk.antigenicQuestion * 0 0
XGROUP CREATE sweet:stream:rk.antigenicQuestion group.antigenicQuestion 0
XGROUP CREATE sweet:stream:rk.antigenicQuestion group.antigenicQuestion 0
\ No newline at end of file
-- 积分抽奖 --
XADD sweet:stream:rk.integralActivityDraw * 0 0
XGROUP CREATE sweet:stream:rk.integralActivityDraw group.integralActivityDraw 0
\ No newline at end of file
liquidnet-bus-service/liquidnet-service-sweet/src/main/java/com/liquidnet/service/sweet/service/impl/SweetIntegralActivityDrawServiceImpl.java
View file @
8f336e96
package
com
.
liquidnet
.
service
.
sweet
.
service
.
impl
;
package
com
.
liquidnet
.
service
.
sweet
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.liquidnet.commons.lang.util.CollectionUtil
;
import
com.liquidnet.commons.lang.util.CollectionUtil
;
import
com.liquidnet.commons.lang.util.CurrentUtil
;
import
com.liquidnet.commons.lang.util.CurrentUtil
;
...
@@ -8,6 +7,8 @@ import com.liquidnet.commons.lang.util.DateUtil;
...
@@ -8,6 +7,8 @@ import com.liquidnet.commons.lang.util.DateUtil;
import
com.liquidnet.commons.lang.util.IDGenerator
;
import
com.liquidnet.commons.lang.util.IDGenerator
;
import
com.liquidnet.service.base.PagedResult
;
import
com.liquidnet.service.base.PagedResult
;
import
com.liquidnet.service.base.ResponseDto
;
import
com.liquidnet.service.base.ResponseDto
;
import
com.liquidnet.service.base.SqlMapping
;
import
com.liquidnet.service.base.constant.MQConst
;
import
com.liquidnet.service.sweet.dto.vo.IntegralActivityDrawVo
;
import
com.liquidnet.service.sweet.dto.vo.IntegralActivityDrawVo
;
import
com.liquidnet.service.sweet.dto.vo.IntegralActivityVo
;
import
com.liquidnet.service.sweet.dto.vo.IntegralActivityVo
;
import
com.liquidnet.service.sweet.dto.vo.admin.SweetIntegralActivityPrizeVo
;
import
com.liquidnet.service.sweet.dto.vo.admin.SweetIntegralActivityPrizeVo
;
...
@@ -15,6 +16,7 @@ import com.liquidnet.service.sweet.entity.SweetIntegralActivityDraw;
...
@@ -15,6 +16,7 @@ import com.liquidnet.service.sweet.entity.SweetIntegralActivityDraw;
import
com.liquidnet.service.sweet.entity.SweetIntegralActivityPrize
;
import
com.liquidnet.service.sweet.entity.SweetIntegralActivityPrize
;
import
com.liquidnet.service.sweet.mapper.SweetIntegralActivityDrawMapper
;
import
com.liquidnet.service.sweet.mapper.SweetIntegralActivityDrawMapper
;
import
com.liquidnet.service.sweet.service.ISweetIntegralActivityDrawService
;
import
com.liquidnet.service.sweet.service.ISweetIntegralActivityDrawService
;
import
com.liquidnet.service.sweet.utils.QueueUtils
;
import
com.liquidnet.service.sweet.utils.RedisDataUtils
;
import
com.liquidnet.service.sweet.utils.RedisDataUtils
;
import
com.liquidnet.service.sweet.utils.SweetNewObjectUtil
;
import
com.liquidnet.service.sweet.utils.SweetNewObjectUtil
;
import
org.apache.commons.lang.StringUtils
;
import
org.apache.commons.lang.StringUtils
;
...
@@ -50,6 +52,9 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
...
@@ -50,6 +52,9 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
@Autowired
@Autowired
private
MongoTemplate
mongoTemplate
;
private
MongoTemplate
mongoTemplate
;
@Autowired
private
QueueUtils
queueUtils
;
@Override
@Override
public
ResponseDto
<
SweetIntegralActivityPrizeVo
>
create
(
String
integralActivityId
)
{
public
ResponseDto
<
SweetIntegralActivityPrizeVo
>
create
(
String
integralActivityId
)
{
// TODO: 2021/10/26 看情况是否加锁 一个用户整个逻辑单进程
// TODO: 2021/10/26 看情况是否加锁 一个用户整个逻辑单进程
...
@@ -98,8 +103,9 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
...
@@ -98,8 +103,9 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
if
(
activityPrizeNum
<
0
||
activityPrizeWinnersNum
<
0
)
{
// 库存不够了
if
(
activityPrizeNum
<
0
||
activityPrizeWinnersNum
<
0
)
{
// 库存不够了
return
ResponseDto
.
failure
(
"活动太火爆了,请稍后再试"
);
return
ResponseDto
.
failure
(
"活动太火爆了,请稍后再试"
);
}
}
String
drawId
=
IDGenerator
.
nextSnowId
();
IntegralActivityDrawVo
integralActivityDrawVo
=
IntegralActivityDrawVo
.
getNew
();
IntegralActivityDrawVo
integralActivityDrawVo
=
IntegralActivityDrawVo
.
getNew
();
integralActivityDrawVo
.
setDrawId
(
IDGenerator
.
nextSnowId
()
);
integralActivityDrawVo
.
setDrawId
(
drawId
);
integralActivityDrawVo
.
setIntegralActivityId
(
integralActivityId
);
integralActivityDrawVo
.
setIntegralActivityId
(
integralActivityId
);
integralActivityDrawVo
.
setActivityNum
(
integralActivity
.
getActivityNum
());
integralActivityDrawVo
.
setActivityNum
(
integralActivity
.
getActivityNum
());
integralActivityDrawVo
.
setPrizeId
(
sweetIntegralActivityPrize
.
getPrizeId
());
integralActivityDrawVo
.
setPrizeId
(
sweetIntegralActivityPrize
.
getPrizeId
());
...
@@ -116,7 +122,18 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
...
@@ -116,7 +122,18 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
// mongo
// mongo
mongoTemplate
.
insert
(
integralActivityDrawVo
,
IntegralActivityDrawVo
.
class
.
getSimpleName
());
mongoTemplate
.
insert
(
integralActivityDrawVo
,
IntegralActivityDrawVo
.
class
.
getSimpleName
());
// TODO: 2021/10/28 mysql 抽奖记录 库存?
// mysql 抽奖记录
LinkedList
<
String
>
sqls
=
CollectionUtil
.
linkedListString
();
LinkedList
<
Object
[]>
sqlsDataA
=
CollectionUtil
.
linkedListObjectArr
();
sqls
.
add
(
SqlMapping
.
get
(
"integral_activity_draw.insert"
));
sqlsDataA
.
add
(
new
Object
[]{
drawId
,
integralActivityId
,
integralActivity
.
getActivityNum
(),
sweetIntegralActivityPrize
.
getPrizeId
(),
sweetIntegralActivityPrize
.
getPrizeTitle
(),
sweetIntegralActivityPrize
.
getPrizeType
(),
sweetIntegralActivityPrize
.
getPrizeTypeNum
(),
sweetIntegralActivityPrize
.
getRelationId
(),
userId
,
nickname
});
queueUtils
.
sendMsgByRedis
(
MQConst
.
SweetQueue
.
SWEET_INTEGRAL_ACTIVITY_DRAW
.
getKey
(),
SqlMapping
.
gets
(
sqls
,
sqlsDataA
));
return
ResponseDto
.
success
(
sweetIntegralActivityPrizeVo
);
return
ResponseDto
.
success
(
sweetIntegralActivityPrizeVo
);
}
}
...
@@ -159,8 +176,6 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
...
@@ -159,8 +176,6 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
@Override
@Override
public
ResponseDto
perfectAddress
(
String
drawId
,
String
receivingAddressesId
,
String
receivingName
,
String
receivingPhone
,
String
receivingAddress
)
{
public
ResponseDto
perfectAddress
(
String
drawId
,
String
receivingAddressesId
,
String
receivingName
,
String
receivingPhone
,
String
receivingAddress
)
{
// todo mysql
// 更新缓存
// 更新缓存
IntegralActivityDrawVo
drawVo
=
redisDataUtils
.
getIntegralActivityDrawInfo
(
drawId
);
IntegralActivityDrawVo
drawVo
=
redisDataUtils
.
getIntegralActivityDrawInfo
(
drawId
);
drawVo
.
setReceivingAddressesId
(
receivingAddressesId
);
drawVo
.
setReceivingAddressesId
(
receivingAddressesId
);
...
@@ -173,14 +188,23 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
...
@@ -173,14 +188,23 @@ public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetInteg
mongoTemplate
.
getCollection
(
IntegralActivityDrawVo
.
class
.
getSimpleName
()).
updateOne
(
mongoTemplate
.
getCollection
(
IntegralActivityDrawVo
.
class
.
getSimpleName
()).
updateOne
(
Query
.
query
(
Criteria
.
where
(
"drawId"
).
is
(
drawId
)).
getQueryObject
(),
Query
.
query
(
Criteria
.
where
(
"drawId"
).
is
(
drawId
)).
getQueryObject
(),
new
Document
(
"$set"
,
new
Document
(
"receivingStatus"
,
2
)
new
Document
(
"$set"
,
new
Document
(
"receivingAddressesId"
,
receivingAddressesId
)
.
append
(
"receivingAddressesId"
,
receivingAddressesId
)
.
append
(
"receivingName"
,
receivingName
)
.
append
(
"receivingName"
,
receivingName
)
.
append
(
"receivingPhone"
,
receivingPhone
)
.
append
(
"receivingPhone"
,
receivingPhone
)
.
append
(
"receivingAddress"
,
receivingAddress
)
.
append
(
"receivingAddress"
,
receivingAddress
)
.
append
(
"updatedAt"
,
DateUtil
.
Formatter
.
yyyyMMddHHmmss
.
format
(
nowTime
)))
.
append
(
"updatedAt"
,
DateUtil
.
Formatter
.
yyyyMMddHHmmss
.
format
(
nowTime
)))
);
);
// mysql
LinkedList
<
String
>
sqls
=
CollectionUtil
.
linkedListString
();
LinkedList
<
Object
[]>
sqlsDataA
=
CollectionUtil
.
linkedListObjectArr
();
sqls
.
add
(
SqlMapping
.
get
(
"integral_activity_draw.update"
));
sqlsDataA
.
add
(
new
Object
[]{
receivingAddressesId
,
receivingName
,
receivingPhone
,
receivingAddress
,
nowTime
,
drawId
});
queueUtils
.
sendMsgByRedis
(
MQConst
.
SweetQueue
.
SWEET_INTEGRAL_ACTIVITY_DRAW
.
getKey
(),
SqlMapping
.
gets
(
sqls
,
sqlsDataA
));
return
ResponseDto
.
success
();
return
ResponseDto
.
success
();
}
}
...
...
liquidnet-bus-service/liquidnet-service-sweet/src/main/resources/sqlmap.properties
View file @
8f336e96
...
@@ -47,4 +47,7 @@ sweet_city_vote.insert=INSERT INTO sweet_city_vote (vote_id,phone,openId,unionId
...
@@ -47,4 +47,7 @@ sweet_city_vote.insert=INSERT INTO sweet_city_vote (vote_id,phone,openId,unionId
sweet_city_vote_stat.insert
=
INSERT INTO sweet_city_vote_stat (stat_id,city_code,city_name,vote_num,type) VALUES (?,?,?,?,?)
sweet_city_vote_stat.insert
=
INSERT INTO sweet_city_vote_stat (stat_id,city_code,city_name,vote_num,type) VALUES (?,?,?,?,?)
sweet_city_vote_stat.update
=
UPDATE sweet_city_vote_stat SET vote_num = IFNULL(vote_num, 0) + 1, updated_at = ? WHERE city_code = ? AND type = ?
sweet_city_vote_stat.update
=
UPDATE sweet_city_vote_stat SET vote_num = IFNULL(vote_num, 0) + 1, updated_at = ? WHERE city_code = ? AND type = ?
# --------------------------防疫答题--------------------------
# --------------------------防疫答题--------------------------
sweet_antigenic_question.insert
=
INSERT INTO sweet_antigenic_question (question_id,type,openId,unionId,nickname,address,phone,urgent_phone,keyword1,keyword11,keyword2,keyword3,keyword4,keyword5,keyword6,keyword7) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
sweet_antigenic_question.insert
=
INSERT INTO sweet_antigenic_question (question_id,type,openId,unionId,nickname,address,phone,urgent_phone,keyword1,keyword11,keyword2,keyword3,keyword4,keyword5,keyword6,keyword7) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
\ No newline at end of file
# ------------------------积分抽奖----------------------------
integral_activity_draw.insert
=
INSERT INTO sweet_integral_activity_draw (draw_id,integral_activity_id,activity_num,prize_id,prize_title,prize_type,prize_type_num,relation_id,user_id,nickname) VALUES (?,?,?,?,?,?,?,?,?,?)
integral_activity_draw.update
=
UPDATE sweet_integral_activity_draw SET receiving_addresses_id = ?, receiving_name = ?, receiving_phone = ?, receiving_address = ?, updated_at = ? WHERE draw_id = ?
\ No newline at end of file
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