Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
sbkpay
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
zhenfei.zhang
sbkpay
Commits
14d81a4a
Commit
14d81a4a
authored
Aug 11, 2017
by
李定达
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1.支付签到修改完成
parent
a23535b3
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
229 additions
and
102 deletions
+229
-102
sbkpay/control.cpp
+89
-76
sbkpay/control.h
+19
-3
sbkpay/global.h
+4
-0
sbkpay/hostwidget.cpp
+46
-15
sbkpay/hostwidget.h
+7
-1
sbkpay/hostwidget.ui
+50
-6
sbkpay/main.cpp
+14
-1
No files found.
sbkpay/control.cpp
View file @
14d81a4a
...
...
@@ -15,7 +15,7 @@
typedef
int
(
*
GetValue
)
(
char
*
,
char
*
);
typedef
int
(
*
GetRSACret
)(
int
,
const
char
*
,
const
char
*
);
Control
::
Control
(
QObject
*
parent
)
:
QObject
(
parent
)
Control
::
Control
(
QObject
*
parent
)
:
QObject
(
parent
)
,
_widget
(
NULL
)
{
InitModel
();
}
...
...
@@ -27,63 +27,50 @@ void Control::Start(const char *indata, char *outdata)
if
(
_widget
==
NULL
)
_widget
=
new
HostWidget
();
connect
(
_widget
,
&
HostWidget
::
RequestWithType
,
this
,
&
Control
::
RequestWithType
);
memcpy
(
&
_request
,
indata
,
sizeof
(
struct
AlipayRequest
)
);
QLOG_INFO
()
<<
"get data from pos : "
<<
indata
;
connect
(
_widget
,
&
HostWidget
::
RequestWithType
,
this
,
&
Control
::
RequestWithType
)
;
if
(
strlen
(
indata
)
>
sizeof
(
struct
AlipayRequest
)
)
connect
(
_widget
,
&
HostWidget
::
Exits
,
this
,
[
&
loop
]
(
)
{
GetResponse
(
QString
(
ERROR_REQUEST_DATA
),
_response
);
memcpy
(
outdata
,
&
_response
,
sizeof
(
struct
AlipayRequest
));
QLOG_ERROR
()
<<
"send error msg to pos : "
<<
outdata
;
_lock
.
lock
();
delete
_widget
;
_widget
=
NULL
;
_lock
.
lock
();
return
;
}
memcpy
(
&
_request
,
indata
,
strlen
(
indata
));
_widget
->
ShowWithRequest
(
_request
);
connect
(
_widget
,
&
HostWidget
::
ExitWithMSG
,
this
,
[
this
,
&
loop
]
(
QString
message
)
QLOG_INFO
()
<<
"quit with normal"
;
loop
.
exit
();
});
connect
(
_widget
,
&
HostWidget
::
ExitWithMSG
,
this
,
[
this
,
&
loop
]
(
QString
code
,
QString
message
)
{
QLOG_INFO
()
<<
"quit with : "
<<
message
;
SetResPonseWithMessage
(
code
,
message
);
loop
.
exit
();
});
_widget
->
ShowWithRequest
(
_request
);
loop
.
exec
();
_lock
.
lock
();
delete
_widget
;
_widget
=
NULL
;
_lock
.
unlock
();
}
void
Control
::
GetErrorResponse
(
QString
message
,
AlipayResponse
&
response
)
{
memcpy
(
outdata
,
(
char
*
)(
&
_response
),
sizeof
(
struct
AlipayResponse
));
outdata
[
sizeof
(
struct
AlipayResponse
)]
=
0
;
QLOG_INFO
()
<<
"return data to pos : "
<<
outdata
;
}
void
Control
::
GetResponse
(
QString
message
,
AlipayResponse
&
respons
e
)
void
Control
::
SetResPonseWithMessage
(
QString
code
,
const
QString
&
messag
e
)
{
FMTool
::
SetString
(
_response
.
ResponseCode
,
3
,
code
);
FMTool
::
SetString
(
_response
.
ResponseMsg
,
40
,
message
);
}
void
Control
::
InitModel
()
{
memset
(
&
_request
,
0
,
sizeof
(
struct
AlipayRequest
));
memset
(
&
_response
,
0
,
sizeof
(
struct
AlipayResponse
));
memset
(
&
_request
,
' '
,
sizeof
(
struct
AlipayRequest
));
memset
(
&
_response
,
' '
,
sizeof
(
struct
AlipayResponse
));
}
bool
Control
::
SendMessageToPayMent
(
const
QJsonObject
&
json
,
QByteArray
&
outdata
)
bool
Control
::
SendMessageToPayMent
(
const
QJsonObject
&
json
,
QByteArray
&
outdata
,
QString
&
error
)
{
char
in
[
MAX_BUF_LEN
]
=
{
0
};
char
out
[
MAX_BUF_LEN
]
=
{
0
};
...
...
@@ -113,19 +100,28 @@ bool Control::SendMessageToPayMent(const QJsonObject &json, QByteArray &outdata)
return
true
;
}
else
QLOG_ERROR
()
<<
"get function (GetValue) failed"
;
{
QLOG_ERROR
()
<<
"get function (GetRSACret) failed"
;
error
=
QString
(
ERROR_LOAD_DLL2
);
}
}
else
{
QLOG_ERROR
()
<<
"load dll failed"
;
error
=
QString
(
ERROR_LOAD_DLL1
);
}
return
false
;
}
bool
Control
::
GetRSA
()
bool
Control
::
GetRSA
(
QString
&
error
)
{
QLibrary
lib
(
qApp
->
applicationDirPath
()
+
"/"
+
"FreemudWrapper.dll"
);
int
rlt
=
0
;
error
.
clear
();
if
(
lib
.
load
())
{
...
...
@@ -134,7 +130,7 @@ bool Control::GetRSA()
if
(
getrsacret
!=
NULL
)
{
QEventLoop
loop
;
QtConcurrent
::
run
(
[
this
,
&
loop
,
&
rlt
,
getrsacret
]()
QtConcurrent
::
run
(
[
this
,
&
loop
,
&
rlt
,
&
error
,
getrsacret
]()
{
int
i
=
FMTool
::
GetString
(
_request
.
Reserved1
,
48
).
toInt
();
QString
storeID
=
FMTool
::
GetString
(
_request
.
StoreNo
,
20
);
...
...
@@ -142,70 +138,87 @@ bool Control::GetRSA()
rlt
=
getrsacret
(
i
,
storeID
.
toLatin1
().
data
(),
PosNO
.
toLatin1
().
data
());
if
(
!
rlt
)
error
=
QString
(
ERROR_LOAD_FAILED
);
loop
.
exit
();
});
loop
.
exec
();
}
else
{
QLOG_ERROR
()
<<
"get function (GetRSACret) failed"
;
error
=
QString
(
ERROR_LOAD_DLL2
);
}
}
else
{
QLOG_ERROR
()
<<
"load dll failed"
;
error
=
QString
(
ERROR_LOAD_DLL1
);
}
return
rlt
;
}
void
Control
::
RequestSign
()
{
QString
error
;
bool
rlt
=
GetRSA
(
error
);
_lock
.
lock
();
if
(
_widget
!=
NULL
)
_widget
->
ShowWiteMGS
(
sign
,
rlt
);
_lock
.
unlock
();;
return
rlt
;
_widget
->
ShowWiteMGS
(
sign
,
rlt
,
error
);
_lock
.
unlock
();
}
void
Control
::
RequestWithType
(
ReqType
type
,
QStringList
list
)
bool
Control
::
GetJson
(
ReqType
type
,
QJsonObject
&
json
,
const
QByteArray
array
,
QString
&
error
)
{
QJsonObject
json
;
QByteArray
outdata
;
QJsonDocument
jsonDocument
=
QJsonDocument
::
fromJson
(
array
.
data
());
if
(
type
==
sign
)
if
(
jsonDocument
.
isNull
()
)
{
GetRSA
();
return
;
QLOG_ERROR
()
<<
"server return not json"
;
error
=
QString
(
"服务端返回数据异常"
);
return
false
;
}
JsonFactory
::
GetJsonWithType
(
type
,
json
,
_request
,
list
);
json
=
jsonDocument
.
object
(
);
QLOG_INFO
()
<<
json
;
RspFactory
::
GetResPonseJson
(
type
,
_response
,
json
)
;
SendMessageToPayMent
(
json
,
outdata
);
if
(
json
.
contains
(
JSON_KEY_MESSAGE
))
error
=
json
[
JSON_KEY_MESSAGE
].
toString
();
QLOG_INFO
()
<<
outdata
.
data
();
if
(
json
.
contains
(
JSON_KEY_STATUSCODE
)
&&
json
[
JSON_KEY_STATUSCODE
].
toInt
()
==
100
)
return
true
;
return
false
;
}
QJsonParseError
parseError
;
QJsonDocument
rspDoc
=
QJsonDocument
::
fromJson
(
outdata
,
&
parseError
);
QJsonObject
rspObj
=
rspDoc
.
object
();
if
(
parseError
.
error
!=
QJsonParseError
::
NoError
)
{
RspFactory
::
GetResPonseWithError
(
_response
,
"40"
,
"接收数据格式错误"
);
}
else
{
RspFactory
::
GetResPonseJson
(
type
,
_response
,
rspObj
);
}
void
Control
::
Request
(
ReqType
type
,
QStringList
list
)
{
QJsonObject
json
,
rtjson
;
QString
error
;
QByteArray
outdata
;
QString
msg
;
if
(
rspObj
.
contains
(
JSON_KEY_STATUSCODE
))
{
if
(
rspObj
[
JSON_KEY_STATUSCODE
].
toInt
()
==
100
)
{
if
(
type
==
pay
)
{
double
Amount
=
rspObj
[
JSON_KEY_TRANSAMOUNT
].
toInt
()
/
100.0
;
msg
=
QString
(
"需收取 ¥ %1"
).
arg
(
Amount
);
_widget
->
ShowWiteMGS
(
type
,
1
,
msg
);
}
}
else
{
msg
=
rspObj
[
JSON_KEY_MESSAGE
].
toString
();
_widget
->
ShowWiteMGS
(
type
,
0
,
msg
);
}
}
else
{
msg
=
"接受数据格式错误"
;
_widget
->
ShowWiteMGS
(
type
,
0
,
msg
);
}
JsonFactory
::
GetJsonWithType
(
type
,
json
,
_request
,
list
);
bool
rlt
=
SendMessageToPayMent
(
json
,
outdata
,
error
);
if
(
rlt
)
rlt
=
Control
::
GetJson
(
type
,
rtjson
,
outdata
,
error
);
_lock
.
lock
();
if
(
_widget
!=
NULL
)
_widget
->
ShowWiteMGS
(
type
,
rlt
,
error
);
_lock
.
unlock
();
}
void
Control
::
RequestWithType
(
ReqType
type
,
QStringList
list
)
{
if
(
type
==
sign
)
{
RequestSign
();
return
;
}
Request
(
type
,
list
);
}
sbkpay/control.h
View file @
14d81a4a
...
...
@@ -26,9 +26,19 @@ private:
void
InitModel
();
bool
SendMessageToPayMent
(
const
QJsonObject
&
json
,
QByteArray
&
outdata
);
//签到
bool
GetRSA
();
bool
SendMessageToPayMent
(
const
QJsonObject
&
json
,
QByteArray
&
outdata
,
QString
&
error
);
void
SetResPonseWithMessage
(
QString
code
,
const
QString
&
message
);
void
RequestSign
();
bool
GetRSA
(
QString
&
error
);
void
Request
(
ReqType
type
,
QStringList
list
);
bool
GetJson
(
QByteArray
&
json
,
QString
&
error
);
bool
GetJson
(
ReqType
type
,
QJsonObject
&
json
,
const
QByteArray
array
,
QString
&
error
);
public
slots
:
...
...
@@ -42,6 +52,12 @@ private:
HostWidget
*
_widget
;
//确保exe结束后不会重新弹窗
QMutex
_lock
;
};
#endif // CONTROL_H
sbkpay/global.h
View file @
14d81a4a
...
...
@@ -53,5 +53,9 @@
#define JSON_REQTYPE_find 2
#define ERROR_LOAD_DLL1 "加载基础组件(dll)失败"
#define ERROR_LOAD_DLL2 "加载基础组件(fun)失败"
#define ERROR_LOAD_FAILED "获取服务端返回数据失败"
#endif // GLOBAL
sbkpay/hostwidget.cpp
View file @
14d81a4a
...
...
@@ -13,6 +13,8 @@ HostWidget::HostWidget(QWidget *parent) :
{
ui
->
setupUi
(
this
);
_need_exit
=
false
;
_widgetlist
.
append
(
ui
->
pay
);
_widgetlist
.
append
(
ui
->
refund
);
_widgetlist
.
append
(
ui
->
find
);
...
...
@@ -21,10 +23,14 @@ HostWidget::HostWidget(QWidget *parent) :
_curr_show_widget
=
NULL
;
ui
->
btn_mananger_print
->
setEnabled
(
false
);
ui
->
btn_mananger_check
->
setEnabled
(
false
);
InitWidget
();
_label_pay_timer
=
new
LabelsTimer
(
ui
->
label_pay_time
,
60
,
"% 秒"
);
connect
(
_label_pay_timer
,
&
LabelsTimer
::
timeout
,
this
,
&
HostWidget
::
on_btn_mananger_exit_clicked
);
connect
(
_label_pay_timer
,
&
LabelsTimer
::
timeout
,
this
,
&
HostWidget
::
on_TimeOut
);
_label_pay_movie
=
new
QMovie
(
":res/loading.gif"
);
...
...
@@ -42,7 +48,7 @@ void HostWidget::ShowWidget(QWidget *showwidget)
ui
->
lineEdit_pay_code
->
setFocus
();
ui
->
label_pay_msg_time
->
setVisible
(
false
);
_label_pay_timer
->
start
(
6
0
,
"%1 秒"
);
_label_pay_timer
->
start
(
1
0
,
"%1 秒"
);
}
for
(
int
i
=
0
;
i
<
_widgetlist
.
size
();
++
i
)
...
...
@@ -79,18 +85,22 @@ void HostWidget::keyPressEvent(QKeyEvent *ke)
{
if
(
ke
->
key
()
==
Qt
::
Key_Return
&&
_curr_show_widget
==
ui
->
pay
)
{
ui
->
btn_pay_exit
->
hide
();
ui
->
label_pay_money
->
hide
();
ui
->
label_pay_title
->
setText
(
"支付宝支付中..."
);
if
(
!
_need_exit
)
{
ui
->
btn_pay_exit
->
hide
();
ui
->
label_pay_money
->
hide
();
ui
->
label_pay_title
->
setText
(
"支付宝支付中..."
);
_label_pay_timer
->
start
(
60
,
"%1 秒"
);
_label_pay_timer
->
start
(
60
,
"%1 秒"
);
QStringList
list
;
list
.
append
(
ui
->
lineEdit_pay_code
->
text
());
QStringList
list
;
list
.
append
(
ui
->
lineEdit_pay_code
->
text
());
QLOG_INFO
()
<<
list
;
QLOG_INFO
()
<<
list
;
emit
RequestWithType
(
pay
,
list
);
emit
RequestWithType
(
pay
,
list
);
}
else
emit
Exits
();
}
else
{
...
...
@@ -145,6 +155,14 @@ void HostWidget::ShowWiteMGS(ReqType type, bool flag, QString message)
if
(
type
==
sign
)
{
if
(
flag
)
ui
->
label_sign_title
->
setText
(
"获取签名成功"
);
else
ui
->
label_sign_title
->
setText
(
"获取签名失败"
);
ui
->
label_sign_msg
->
setText
(
message
);
ui
->
btn_sign_sign
->
show
();
ShowWidget
(
ui
->
sign
);
return
;
...
...
@@ -152,6 +170,7 @@ void HostWidget::ShowWiteMGS(ReqType type, bool flag, QString message)
if
(
type
==
pay
&&
_curr_show_widget
==
ui
->
pay
)
{
_need_exit
=
true
;
_label_pay_timer
->
stop
();
ui
->
label_pay_time_load
->
setVisible
(
false
);
ui
->
label_pay_money
->
setVisible
(
true
);
...
...
@@ -162,7 +181,7 @@ void HostWidget::ShowWiteMGS(ReqType type, bool flag, QString message)
if
(
flag
)
{
ui
->
label_pay_msg_time
->
setVisible
(
true
);
_label_pay_timer
->
setLabel
(
ui
->
label_pay_msg_time
);
_label_pay_timer
->
start
(
3
);
_label_pay_timer
->
start
(
3
0
);
ui
->
label_pay_title
->
setText
(
"支付成功"
);
ui
->
label_pay_time
->
setPixmap
(
QPixmap
(
":res/success.png"
));
}
else
{
...
...
@@ -197,28 +216,40 @@ void HostWidget::on_btn_mananger_print_clicked()
emit
RequestWithType
(
endday
,
list
);
}
void
HostWidget
::
on_TimeOut
()
{
this
->
hide
();
if
(
_need_exit
)
emit
Exits
();
else
emit
ExitWithMSG
(
"01"
,
QString
(
"操作超时"
));
}
void
HostWidget
::
on_btn_mananger_exit_clicked
()
{
this
->
hide
();
emit
ExitWithMSG
(
QString
(
"
"
));
emit
ExitWithMSG
(
"02"
,
QString
(
"收银员取消
"
));
}
void
HostWidget
::
on_btn_pay_exit_clicked
()
{
this
->
hide
();
emit
ExitWithMSG
(
QString
(
""
));
if
(
_need_exit
)
emit
Exits
();
else
emit
ExitWithMSG
(
"02"
,
QString
(
"收银员取消"
));
}
void
HostWidget
::
on_btn_find_exit_clicked
()
{
this
->
hide
();
emit
ExitWithMSG
(
QString
(
"
"
));
emit
ExitWithMSG
(
"02"
,
QString
(
"收银员取消
"
));
}
void
HostWidget
::
on_btn_sign_exit_clicked
()
{
this
->
hide
();
emit
ExitWithMSG
(
QString
(
"
"
));
emit
ExitWithMSG
(
"02"
,
QString
(
"收银员取消
"
));
}
void
HostWidget
::
on_btn_sign_sign_clicked
()
...
...
sbkpay/hostwidget.h
View file @
14d81a4a
...
...
@@ -32,8 +32,9 @@ signals:
void
RequestWithType
(
ReqType
type
,
QStringList
list
);
void
ExitWithMSG
(
QString
message
);
void
ExitWithMSG
(
QString
code
,
QString
message
);
void
Exits
();
protected
:
void
keyPressEvent
(
QKeyEvent
*
ke
);
...
...
@@ -55,6 +56,8 @@ private slots:
void
on_btn_sign_sign_clicked
();
void
on_TimeOut
();
private
:
void
ShowWidget
(
QWidget
*
showwidget
);
...
...
@@ -70,7 +73,10 @@ private:
AlipayRequest
_data
;
LabelsTimer
*
_label_pay_timer
;
QMovie
*
_label_pay_movie
;
bool
_need_exit
;
};
#endif // HOSTWIDGET_H
sbkpay/hostwidget.ui
View file @
14d81a4a
...
...
@@ -890,10 +890,9 @@
<item>
<widget
class=
"QLabel"
name=
"label_refund_title"
>
<property
name=
"styleSheet"
>
<string
notr=
"true"
>
#
widget_refund_main
<string
notr=
"true"
>
#
label_refund_title
{
border-radius:15px;
background-color: rgb(255, 255, 255);
font: 75 25px
"
Microsoft YaHei UI Light
"
;
}
</string>
</property>
<property
name=
"text"
>
...
...
@@ -909,16 +908,27 @@
<property
name=
"orientation"
>
<enum>
Qt::Vertical
</enum>
</property>
<property
name=
"sizeType"
>
<enum>
QSizePolicy::Maximum
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
20
</width>
<height>
40
</height>
<height>
14
</height>
</size>
</property>
</spacer>
</item>
<item>
<widget
class=
"QLabel"
name=
"label__refund_money"
>
<property
name=
"styleSheet"
>
<string
notr=
"true"
>
#label__refund_money
{
font: 75 16px
"
Microsoft YaHei UI Light
"
;
color: rgb(203, 203, 203);
color: rgb(160, 160, 160);
}
</string>
</property>
<property
name=
"text"
>
<string>
100
</string>
</property>
...
...
@@ -957,13 +967,25 @@
</item>
<item>
<widget
class=
"QLabel"
name=
"label__refund_bus"
>
<property
name=
"styleSheet"
>
<string
notr=
"true"
>
#label__refund_bus
{
font: 16px
"
微软雅黑
"
;
}
</string>
</property>
<property
name=
"text"
>
<string>
营业日期
</string>
<string>
营业日期
:
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QLabel"
name=
"label__refund_bussessdata"
>
<property
name=
"styleSheet"
>
<string
notr=
"true"
>
#label__refund_businessdata
{
font: 16px
"
微软雅黑
"
;
}
</string>
</property>
<property
name=
"text"
>
<string>
2017-11-11
</string>
</property>
...
...
@@ -1001,13 +1023,25 @@
</item>
<item>
<widget
class=
"QLabel"
name=
"label__refund_order"
>
<property
name=
"styleSheet"
>
<string
notr=
"true"
>
#label__refund_order
{
font: 16px
"
微软雅黑
"
;
}
</string>
</property>
<property
name=
"text"
>
<string>
订单号
</string>
<string>
订单号
:
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QLabel"
name=
"label__refund_id"
>
<property
name=
"styleSheet"
>
<string
notr=
"true"
>
#label__refund_id
{
font: 16px
"
微软雅黑
"
;
}
</string>
</property>
<property
name=
"text"
>
<string>
1
</string>
</property>
...
...
@@ -1061,6 +1095,16 @@
</item>
<item>
<widget
class=
"QPushButton"
name=
"btn__refund_refund"
>
<property
name=
"styleSheet"
>
<string
notr=
"true"
>
#btn__refund_refund
{
border:0px;
border-radius:3px;
background-color: rgb(128, 134, 143);
font: 75 20px
"
Microsoft YaHei UI Light
"
;
color: rgb(255, 255, 255);
}
</string>
</property>
<property
name=
"text"
>
<string>
发起退款(60)
</string>
</property>
...
...
sbkpay/main.cpp
View file @
14d81a4a
...
...
@@ -98,12 +98,25 @@ int main(int argc, char *argv[])
//pass
TestGetResPonseJson
();
AlipayRequest
req
;
FMTool
::
SetString
(
req
.
BusinessDay
,
8
,
QString
(
"20170908"
));
FMTool
::
SetString
(
req
.
TransType
,
2
,
QString
(
"40"
));
FMTool
::
SetString
(
req
.
Reserved1
,
64
,
QString
(
"1443"
));
FMTool
::
SetString
(
req
.
StoreNo
,
20
,
QString
(
"17607"
));
FMTool
::
SetString
(
req
.
DeviceNo
,
6
,
QString
(
"1"
));
FMTool
::
SetString
(
req
.
CashierNo
,
6
,
QString
(
"0123"
));
FMTool
::
SetString
(
req
.
CashTraceNo
,
6
,
QString
(
"123123"
));
char
as
[
MAX_BUF_LEN
]
=
{
0
};
memcpy
(
as
,
&
req
,
sizeof
(
struct
AlipayRequest
));
Control
control
;
char
as
[]
=
"ak10dh171300000000000 *#dhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
;
//
char as[] = "ak10dh171300000000000 *#dhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh";
char
b
[
MAX_BUF_LEN
]
=
{
0
};
control
.
Start
(
as
,
b
);
...
...
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