Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
jinfa-platform
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
shenshaokai
jinfa-platform
Commits
1c5b1f4c
Commit
1c5b1f4c
authored
Mar 24, 2022
by
xiexiuxing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
merge:合并合同功能调整
parent
efde8cad
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
275 additions
and
111 deletions
+275
-111
feature.md
.gitlab/merge_request_templates/feature.md
+9
-0
fixbug.md
.gitlab/merge_request_templates/fixbug.md
+13
-0
Jenkinsfile
Jenkinsfile
+0
-0
index.less
...ges/accountSetting/components/SafeVerification/index.less
+23
-26
index.tsx
...ages/accountSetting/components/SafeVerification/index.tsx
+73
-15
EmailVerifyPanel.tsx
...Setting/components/VerifyPanel/Panel/EmailVerifyPanel.tsx
+9
-7
PaycodeVerifyPanel.tsx
...tting/components/VerifyPanel/Panel/PaycodeVerifyPanel.tsx
+9
-5
PhoneVerifyPanel.tsx
...Setting/components/VerifyPanel/Panel/PhoneVerifyPanel.tsx
+8
-4
ResetPayCode.tsx
...ountSetting/components/VerifyPanel/Panel/ResetPayCode.tsx
+9
-3
useShowRiskCheck.ts
...tSetting/components/VerifyPanel/Panel/useShowRiskCheck.ts
+20
-0
index.tsx
src/pages/contract/components/examine/index.tsx
+21
-16
index.tsx
src/pages/contract/contractexecution/details/index.tsx
+0
-0
index.tsx
src/pages/contract/coordination/details/index.tsx
+6
-1
index.tsx
src/pages/contract/manage/details/index.tsx
+9
-0
ContractText.tsx
...pages/contract/manage/editing/components/ContractText.tsx
+14
-11
index.tsx
src/pages/contract/manage/purchase/index.tsx
+9
-9
index.tsx
...s/procurement/callForBids/addRemarkBidCommittee/index.tsx
+16
-6
index.tsx
...n/marketingAbility/components/couponsListLayout/index.tsx
+9
-1
index.tsx
...onents/listModalLayout/components/productLayout/index.tsx
+0
-1
index.tsx
...ion/marketingAbility/components/listModalLayout/index.tsx
+12
-4
index.tsx
...n/marketingAbility/components/productListLayout/index.tsx
+6
-1
add.tsx
...arketingAbility/selfManagement/readySubmitExamine/add.tsx
+0
-1
No files found.
.gitlab/merge_request_templates/feature.md
0 → 100644
View file @
1c5b1f4c
# 新功能概况
1.
功能描述(必填)
2.
预期效果/行为是什么
3.
可能影响到的模块是什么
4.
禅道需求地址
.gitlab/merge_request_templates/fixbug.md
0 → 100644
View file @
1c5b1f4c
# bug概况
1.
重现步骤(必填)
2.
目前的错误行为是什么
3.
预期效果/行为是什么
4.
相关日志/屏幕截图(如果可以提供的话,方便追踪)
5.
测试通过后希望同步的分支
6.
禅道bug地址
Jenkinsfile
0 → 100644
View file @
1c5b1f4c
This diff is collapsed.
Click to expand it.
src/pages/accountSetting/components/SafeVerification/index.less
View file @
1c5b1f4c
.box {
z-index: 99;
.container {
height: 32px;
line-height: 32px;
font-size: 14px;
background: #EBF7F2;
border: 1px solid #00B37A;
margin: 8px 0 32px 0;
width: 495px;
cursor: pointer;
position: relative;
.btn {
color: #00B37A;
text-align: center;
}
}
}
.container {
height: 32px;
line-height: 32px;
font-size: 14px;
background: #EBF7F2;
border: 1px solid #00B37A;
margin: 8px 0 32px 0;
width: 495px;
cursor: pointer;
position: relative;
.risk {
display: flex;
flex-direction: column;
align-items: center;
}
.btn {
color: #00B37A;
text-align: center;
}
}
.sliderVerify {
position: absolute;
top: 50%;
left: 50%;
// background-color: #fff;
z-index: 99;
// transform: translateX(-130px);
margin-left: -130px;
margin-top: -136px;
}
\ No newline at end of file
src/pages/accountSetting/components/SafeVerification/index.tsx
View file @
1c5b1f4c
import
React
,
{
useState
}
from
'react'
;
import
React
,
{
use
Effect
,
use
State
}
from
'react'
;
import
styles
from
'./index.less'
;
import
{
Row
,
Col
}
from
'antd'
;
import
SliderVerify
from
'../SliderVerify'
;
import
{
Row
,
Col
,
Modal
,
message
}
from
'antd'
;
//
import SliderVerify from '../SliderVerify';
import
{
useIntl
}
from
'umi'
import
{
RiskCheck
}
from
'@linkseeks/god'
;
import
{
decryptedByAES
}
from
'@/utils/cryptoAes'
;
import
{
getMemberCaptcha
}
from
'@/services/MemberV2Api'
;
// const imageUrl = 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1689053532,4230915864&fm=26&gp=0.jpg'
const
imageUrl
=
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1689053532,4230915864&fm=26&gp=0.jpg'
// 滑块尺寸
const
FLAG_SIZE
=
60
const
IMG_WIDTH
=
352
const
IMG_HEIGHT
=
180
const
SafeVerification
=
(
props
)
=>
{
interface
Iprops
{
isDisabled
:
boolean
handleVerifySuccess
:
()
=>
void
,
tips
?:
string
}
const
SafeVerification
:
React
.
FC
<
Iprops
>
=
(
props
)
=>
{
const
intl
=
useIntl
();
const
{
isDisabled
,
tips
=
intl
.
formatMessage
({
id
:
'accountSetting.inputCode'
,
defaultMessage
:
'请填写验证码'
})
}
=
props
const
[
visible
,
setVisible
]
=
useState
(
false
)
const
[
remoteImg
,
setRemoteImg
]
=
useState
({
x
:
0
,
y
:
0
,
imgId
:
''
,
img
:
''
,
})
const
handleVisible
=
()
=>
{
if
(
isDisabled
)
{
message
.
error
(
tips
);
return
}
setVisible
(
true
)
}
const
cancel
=
()
=>
{
...
...
@@ -21,6 +45,27 @@ const SafeVerification = (props) => {
setVisible
(
false
);
!!
props
.
handleVerifySuccess
&&
props
.
handleVerifySuccess
()
}
useEffect
(()
=>
{
if
(
visible
)
{
getMemberCaptcha
({
width
:
IMG_WIDTH
.
toString
(),
height
:
IMG_HEIGHT
.
toString
(),
size
:
FLAG_SIZE
.
toString
()
}).
then
(
res
=>
{
const
{
backImage
,
width
,
height
,
imgId
}
=
res
.
data
setRemoteImg
(()
=>
{
return
{
img
:
'data:image/jpeg;base64,'
+
backImage
,
imgId
,
x
:
Number
(
decryptedByAES
(
width
)),
y
:
Number
(
height
)
}
})
})
}
},
[
visible
])
return
(
<
div
className=
{
styles
.
box
}
>
<
Row
>
...
...
@@ -29,20 +74,33 @@ const SafeVerification = (props) => {
<
div
className=
{
styles
.
btn
}
onClick=
{
handleVisible
}
>
{
intl
.
formatMessage
({
id
:
'accountSetting.clickVerify'
})
}
</
div
>
<
div
className=
{
styles
.
sliderVerify
}
>
<
SliderVerify
visible=
{
visible
}
onCancel=
{
cancel
}
onSuccess=
{
handleSuccess
}
imageUrl=
{
imageUrl
}
/>
</
div
>
</
div
>
</
Col
>
</
Row
>
<
Modal
title=
{
intl
.
formatMessage
({
id
:
'components.huadongyanzheng'
})
}
visible=
{
visible
}
mask
centered
destroyOnClose
footer=
{
null
}
onCancel=
{
cancel
}
>
<
RiskCheck
className=
{
styles
.
risk
}
imgUrl=
{
remoteImg
.
img
}
imgWidth=
{
IMG_WIDTH
}
imgHeight=
{
IMG_HEIGHT
}
xPoint=
{
remoteImg
.
x
}
yPoint=
{
remoteImg
.
y
}
shadowSize=
{
FLAG_SIZE
}
differ=
{
10
}
tipText=
{
intl
.
formatMessage
({
id
:
'components.riskCheckTips'
,
defaultMessage
:
''
})
}
onSuccess=
{
handleSuccess
}
/>
</
Modal
>
</
div
>
)
}
...
...
src/pages/accountSetting/components/VerifyPanel/Panel/EmailVerifyPanel.tsx
View file @
1c5b1f4c
...
...
@@ -19,6 +19,7 @@ import {
postMemberSecurityPswUpdate
}
from
'@/services/MemberV2Api'
;
import
{
useIntl
}
from
'umi'
import
useShowRiskCheck
from
'./useShowRiskCheck'
;
const
layout
=
{
...
...
@@ -35,6 +36,7 @@ const EmailVerifyPanel = (props) => {
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
{
email
,
pageType
}
=
props
;
const
[
form
]
=
Form
.
useForm
();
const
{
canShowRiskCheck
,
onValuesChange
}
=
useShowRiskCheck
();
const
handleFinish
=
(
values
)
=>
{
const
{
pageType
}
=
props
;
...
...
@@ -70,8 +72,6 @@ const EmailVerifyPanel = (props) => {
}
})
}
// 发送旧的邮箱验证码
const
getCode
=
useCallback
(()
=>
{
let
SERVICE_MAP
=
{
...
...
@@ -92,12 +92,10 @@ const EmailVerifyPanel = (props) => {
'phone'
:
postMemberSecurityPhoneEmailCheck
}
const
service
=
SERVICE_CHECK
[
props
.
pageType
];
service
({
smsCode
:
captcha
},
{
ctlType
:
'none'
}).
then
((
data
)
=>
{
console
.
log
(
data
);
service
({
smsCode
:
captcha
}).
then
((
data
)
=>
{
if
(
data
.
code
==
1000
)
{
message
.
success
(
intl
.
formatMessage
({
id
:
'accountSetting.verifyOk'
}))
setVisible
(
true
);
}
}
})
}
...
...
@@ -110,6 +108,7 @@ const EmailVerifyPanel = (props) => {
name=
"basic"
onFinish=
{
handleFinish
}
form=
{
form
}
onValuesChange=
{
onValuesChange
}
>
{
!
visible
...
...
@@ -131,7 +130,10 @@ const EmailVerifyPanel = (props) => {
</
Row
>
</
Form
.
Item
>
<
div
style=
{
{
marginBottom
:
'130px'
}
}
>
<
SafeVerification
handleVerifySuccess=
{
handleVerifySuccess
}
/>
<
SafeVerification
handleVerifySuccess=
{
handleVerifySuccess
}
isDisabled=
{
!
canShowRiskCheck
}
/>
</
div
>
</>
:
null
...
...
src/pages/accountSetting/components/VerifyPanel/Panel/PaycodeVerifyPanel.tsx
View file @
1c5b1f4c
...
...
@@ -7,6 +7,7 @@ import { history } from 'umi'
import
{
encryptedByAES
}
from
'@/utils/cryptoAes'
import
{
postMemberSecurityEmailUpdate
,
postMemberSecurityPayCheck
,
postMemberSecurityPhoneUpdate
,
postMemberSecurityPswUpdate
}
from
'@/services/MemberV2Api'
;
import
{
useIntl
}
from
'umi'
import
useShowRiskCheck
from
'./useShowRiskCheck'
;
const
layout
=
{
...
...
@@ -28,6 +29,7 @@ const PaycodeVerifyPanel: React.FC<IProps> = (props) => {
const
{
pageType
}
=
props
;
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
const
{
canShowRiskCheck
,
onValuesChange
}
=
useShowRiskCheck
(
'paycode'
);
const
handleFinish
=
(
values
)
=>
{
const
{
pageType
}
=
props
;
...
...
@@ -68,10 +70,8 @@ const PaycodeVerifyPanel: React.FC<IProps> = (props) => {
const
handleVerifySuccess
=
()
=>
{
const
payPassword
=
encryptedByAES
(
form
.
getFieldValue
(
'paycode'
));
const
service
=
postMemberSecurityPayCheck
;
service
({
payPassword
:
payPassword
},
{
ctlType
:
"none"
}).
then
((
data
)
=>
{
console
.
log
(
data
);
service
({
payPassword
:
payPassword
}).
then
((
data
)
=>
{
if
(
data
.
code
==
1000
)
{
message
.
success
(
intl
.
formatMessage
({
id
:
'accountSetting.verifyOk'
}))
setVisible
(
true
);
}
})
...
...
@@ -85,8 +85,8 @@ const PaycodeVerifyPanel: React.FC<IProps> = (props) => {
name=
"basic"
form=
{
form
}
onFinish=
{
handleFinish
}
onValuesChange=
{
onValuesChange
}
>
{
!
visible
?
<>
...
...
@@ -104,7 +104,11 @@ const PaycodeVerifyPanel: React.FC<IProps> = (props) => {
</
Row
>
</
Form
.
Item
>
<
div
style=
{
{
marginBottom
:
'130px'
}
}
>
<
SafeVerification
handleVerifySuccess=
{
handleVerifySuccess
}
/>
<
SafeVerification
handleVerifySuccess=
{
handleVerifySuccess
}
isDisabled=
{
!
canShowRiskCheck
}
tips=
{
intl
.
formatMessage
({
id
:
'accountSetting.inputPayPsw'
,
defaultMessage
:
'请填写支付密码'
})
}
/>
</
div
>
</>
:
null
...
...
src/pages/accountSetting/components/VerifyPanel/Panel/PhoneVerifyPanel.tsx
View file @
1c5b1f4c
...
...
@@ -18,6 +18,7 @@ import {
postMemberSecurityPswSmsCheck
,
postMemberSecurityPswUpdate
}
from
'@/services/MemberV2Api'
;
import
useShowRiskCheck
from
'./useShowRiskCheck'
;
const
layout
=
{
labelCol
:
{
span
:
3
},
...
...
@@ -38,6 +39,7 @@ const PhoneVerifyPanel: React.FC<IProps> = (props) => {
const
intl
=
useIntl
();
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
const
{
canShowRiskCheck
,
onValuesChange
}
=
useShowRiskCheck
();
const
{
phone
,
pageType
}
=
props
;
const
onFinish
=
(
values
)
=>
{
...
...
@@ -92,13 +94,11 @@ const PhoneVerifyPanel: React.FC<IProps> = (props) => {
'phone'
:
postMemberSecurityPhoneSmsCheck
}
const
service
=
SERVICE_CHECK
[
props
.
pageType
];
service
({
smsCode
:
captcha
}
,
{
ctlType
:
'none'
}
).
then
((
data
)
=>
{
service
({
smsCode
:
captcha
}).
then
((
data
)
=>
{
if
(
data
.
code
===
1000
)
{
message
.
success
(
intl
.
formatMessage
({
id
:
'accountSetting.verifyOk'
}))
setVisible
(
true
);
}
})
}
return
(
...
...
@@ -110,6 +110,7 @@ const PhoneVerifyPanel: React.FC<IProps> = (props) => {
name=
"basic"
onFinish=
{
onFinish
}
form=
{
form
}
onValuesChange=
{
onValuesChange
}
>
{
!
visible
...
...
@@ -131,7 +132,10 @@ const PhoneVerifyPanel: React.FC<IProps> = (props) => {
</
Row
>
</
Form
.
Item
>
<
div
style=
{
{
marginBottom
:
'130px'
}
}
>
<
SafeVerification
handleVerifySuccess=
{
handleVerifySuccess
}
/>
<
SafeVerification
handleVerifySuccess=
{
handleVerifySuccess
}
isDisabled=
{
!
canShowRiskCheck
}
/>
</
div
>
</>
:
null
...
...
src/pages/accountSetting/components/VerifyPanel/Panel/ResetPayCode.tsx
View file @
1c5b1f4c
...
...
@@ -6,6 +6,7 @@ import TypeForHeader from '../../TypeForHeader';
import
{
history
,
useIntl
}
from
'umi'
import
{
encryptedByAES
}
from
'@/utils/cryptoAes'
import
{
postMemberSecurityPaySms
,
postMemberSecurityPaySmsCheck
,
postMemberSecurityPayUpdate
}
from
'@/services/MemberV2Api'
;
import
useShowRiskCheck
from
'./useShowRiskCheck'
;
const
layout
=
{
labelCol
:
{
span
:
3
},
wrapperCol
:
{
span
:
13
},
...
...
@@ -26,6 +27,8 @@ const ResetPayCode: React.FC<IProps> = (props) => {
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
const
{
phone
,
pageType
}
=
props
;
const
{
canShowRiskCheck
,
onValuesChange
}
=
useShowRiskCheck
();
const
onFinish
=
(
values
)
=>
{
const
postData
=
{
payPassword
:
encryptedByAES
(
values
.
password
)
...
...
@@ -51,8 +54,7 @@ const ResetPayCode: React.FC<IProps> = (props) => {
const
handleVerifySuccess
=
()
=>
{
const
captcha
=
form
.
getFieldValue
(
'captcha'
);
const
service
=
postMemberSecurityPaySmsCheck
service
({
smsCode
:
captcha
},
{
ctlType
:
'none'
}).
then
((
data
)
=>
{
console
.
log
(
data
);
service
({
smsCode
:
captcha
}).
then
((
data
)
=>
{
if
(
data
.
code
==
1000
)
{
setVisible
(
true
);
}
...
...
@@ -129,6 +131,7 @@ const ResetPayCode: React.FC<IProps> = (props) => {
name=
"basic"
onFinish=
{
onFinish
}
form=
{
form
}
onValuesChange=
{
onValuesChange
}
>
{
!
visible
...
...
@@ -152,7 +155,10 @@ const ResetPayCode: React.FC<IProps> = (props) => {
</
Row
>
</
Form
.
Item
>
<
div
style=
{
{
marginBottom
:
'130px'
}
}
>
<
SafeVerification
handleVerifySuccess=
{
handleVerifySuccess
}
/>
<
SafeVerification
handleVerifySuccess=
{
handleVerifySuccess
}
isDisabled=
{
!
canShowRiskCheck
}
/>
</
div
>
</>
:
null
...
...
src/pages/accountSetting/components/VerifyPanel/Panel/useShowRiskCheck.ts
0 → 100644
View file @
1c5b1f4c
import
React
,
{
useState
}
from
'react'
;
function
useShowRiskCheck
(
key
:
string
=
'captcha'
)
{
const
[
canShowRiskCheck
,
setCanShowRiskCheck
]
=
useState
(
false
);
const
onValuesChange
=
(
changedValues
)
=>
{
if
(
key
in
changedValues
)
{
if
(
changedValues
[
key
])
{
setCanShowRiskCheck
(
true
)
}
else
{
setCanShowRiskCheck
(
false
)
}
}
}
return
{
canShowRiskCheck
,
onValuesChange
};
}
export
default
useShowRiskCheck
\ No newline at end of file
src/pages/contract/components/examine/index.tsx
View file @
1c5b1f4c
...
...
@@ -33,6 +33,7 @@ const Examine: React.FC<Iprops> = ({
})
=>
{
const
[
isPass
,
setIsAllMember
]
=
useState
(
1
)
const
[
state
,
setstate
]
=
useState
<
any
>
(
false
);
const
[
contractUrl
,
setcontractUrl
]
=
useState
(
''
);
/* 设置选中值 */
const
handleIsAllMemberChange
=
(
v
:
any
)
=>
{
setIsAllMember
(
v
.
target
.
value
)
...
...
@@ -91,11 +92,13 @@ const Examine: React.FC<Iprops> = ({
/* 合同协同签订-签订合同 */
case
'Signacontract'
:
fn
=
postContractManageSign
values
.
contractUrl
=
contractUrl
;
values
.
contractId
=
applyId
;
break
;
}
console
.
log
(
values
)
const
msg
=
message
.
loading
({
content
:
intl
.
formatMessage
({
id
:
'contract.zhengzaicaozuo'
}),
content
:
intl
.
formatMessage
({
id
:
'contract.zhengzaicaozuo'
}),
duration
:
0
,
});
fn
(
values
).
then
(
res
=>
{
...
...
@@ -136,9 +139,10 @@ const Examine: React.FC<Iprops> = ({
},
onChange
(
info
)
{
if
(
info
.
file
.
response
)
{
const
{
code
}
=
info
.
file
.
response
;
const
{
code
,
data
:
{
url
}
}
=
info
.
file
.
response
;
console
.
log
(
code
);
message
.
info
(
intl
.
formatMessage
({
id
:
'contract.shangchuanchenggong'
}));
setcontractUrl
(
url
)
message
.
info
(
intl
.
formatMessage
({
id
:
'contract.shangchuanchenggong'
}));
console
.
log
(
info
.
file
)
setstate
(
true
);
}
...
...
@@ -148,12 +152,12 @@ const Examine: React.FC<Iprops> = ({
}
if
(
info
.
file
.
status
===
'done'
)
{
}
else
if
(
info
.
file
.
status
===
'error'
)
{
message
.
error
(
`
${
info
.
file
.
name
}
${
intl
.
formatMessage
({
id
:
'contract.shangchuanshibai'
})}
`
);
message
.
error
(
`
${
info
.
file
.
name
}
${
intl
.
formatMessage
({
id
:
'contract.shangchuanshibai'
})}
`
);
}
},
beforeUpload
(
file
)
{
if
(
file
.
size
/
1024
/
1024
>
20
)
{
message
.
warning
(
intl
.
formatMessage
({
id
:
'contract.fujiandaxiaochaoguo20M'
}));
message
.
warning
(
intl
.
formatMessage
({
id
:
'contract.fujiandaxiaochaoguo20M'
}));
return
Promise
.
reject
();
}
},
...
...
@@ -161,13 +165,14 @@ const Examine: React.FC<Iprops> = ({
const
uploadNode
=
()
=>
{
return
(
<
div
>
<
p
style=
{
{
paddingTop
:
10
,
paddingBottom
:
10
,
}
}
>
{
intl
.
formatMessage
({
id
:
'contract.zhizhihetongyifangyi'
})
}
</
p
>
<
p
style=
{
{
paddingTop
:
10
,
paddingBottom
:
10
,
}
}
>
{
intl
.
formatMessage
({
id
:
'contract.zhizhihetongyifangyi'
})
}
</
p
>
<
Row
style=
{
{
marginBottom
:
30
,
}
}
>
<
Col
>
<
Upload
{
...
uploadProps
}
maxCount=
{
1
}
>
<
Button
icon=
{
<
UploadOutlined
/>
}
>
{
intl
.
formatMessage
({
id
:
'contract.shangchuanfujian'
})
}
</
Button
>
<
Button
icon=
{
<
UploadOutlined
/>
}
>
{
intl
.
formatMessage
({
id
:
'contract.shangchuanfujian'
})
}
</
Button
>
</
Upload
>
</
Col
>
</
Row
>
...
...
@@ -176,7 +181,7 @@ const Examine: React.FC<Iprops> = ({
}
return
(
<
div
>
<
Modal
footer=
{
null
}
title=
{
intl
.
formatMessage
({
id
:
'contract.tijiaoshenhe'
})
}
visible=
{
ExamineFlag
}
onCancel=
{
()
=>
fetchData
(
'onCancel'
)
}
>
<
Modal
footer=
{
null
}
title=
{
intl
.
formatMessage
({
id
:
'contract.tijiaoshenhe'
})
}
visible=
{
ExamineFlag
}
onCancel=
{
()
=>
fetchData
(
'onCancel'
)
}
>
<
Form
name=
"basic"
form=
{
form
}
...
...
@@ -185,20 +190,20 @@ const Examine: React.FC<Iprops> = ({
onFinishFailed=
{
onFinishFailed
}
>
{
type
===
'Signacontract'
?
uploadNode
()
:
null
}
<
Form
.
Item
name=
"isPass"
label=
""
rules=
{
[{
required
:
true
,
message
:
intl
.
formatMessage
({
id
:
'contract.qingxuanzetongguofangshi'
})
}]
}
initialValue=
{
isPass
}
>
<
Form
.
Item
name=
"isPass"
label=
""
rules=
{
[{
required
:
true
,
message
:
intl
.
formatMessage
({
id
:
'contract.qingxuanzetongguofangshi'
})
}]
}
initialValue=
{
isPass
}
>
<
Radio
.
Group
onChange=
{
handleIsAllMemberChange
}
>
<
Radio
value=
{
1
}
>
{
agreeText
}
</
Radio
>
<
Radio
value=
{
0
}
>
{
disagree
}
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
{
isPass
?
intl
.
formatMessage
({
id
:
'contract.shenhetongguoyuanyin'
})
:
intl
.
formatMessage
({
id
:
'contract.shenbuhetongguoyuanyin'
})
}
rules=
{
[{
required
:
true
,
message
:
intl
.
formatMessage
({
id
:
'contract.qingxuanzezuofeiriqi'
})
}]
}
>
<
Form
.
Item
label=
{
isPass
?
intl
.
formatMessage
({
id
:
'contract.shenhetongguoyuanyin'
})
:
intl
.
formatMessage
({
id
:
'contract.shenbuhetongguoyuanyin'
})
}
rules=
{
[{
required
:
true
,
message
:
intl
.
formatMessage
({
id
:
'contract.qingxuanzezuofeiriqi'
})
}]
}
>
</
Form
.
Item
>
<
Form
.
Item
label=
''
name=
"opinion"
rules=
{
[{
required
:
isPass
?
false
:
true
,
message
:
intl
.
formatMessage
({
id
:
'contract.shenhetongguoyijian'
})
}]
}
>
<
TextArea
placeholder=
{
intl
.
formatMessage
({
id
:
'contract.zaicishurunideyuanyin'
})
}
maxLength=
{
120
}
/>
<
Form
.
Item
label=
''
name=
"opinion"
rules=
{
[{
required
:
isPass
?
false
:
true
,
message
:
intl
.
formatMessage
({
id
:
'contract.shenhetongguoyijian'
})
}]
}
>
<
TextArea
placeholder=
{
intl
.
formatMessage
({
id
:
'contract.zaicishurunideyuanyin'
})
}
maxLength=
{
120
}
/>
</
Form
.
Item
>
<
div
style=
{
{
display
:
'flex'
,
justifyContent
:
'flex-end'
}
}
>
<
Button
onClick=
{
()
=>
fetchData
(
'onCancel'
)
}
style=
{
{
marginRight
:
10
}
}
>
{
intl
.
formatMessage
({
id
:
'contract.quxiao'
})
}
</
Button
>
<
Button
type=
"primary"
htmlType=
"submit"
>
{
intl
.
formatMessage
({
id
:
'contract.baocun'
})
}
</
Button
>
<
Button
onClick=
{
()
=>
fetchData
(
'onCancel'
)
}
style=
{
{
marginRight
:
10
}
}
>
{
intl
.
formatMessage
({
id
:
'contract.quxiao'
})
}
</
Button
>
<
Button
type=
"primary"
htmlType=
"submit"
>
{
intl
.
formatMessage
({
id
:
'contract.baocun'
})
}
</
Button
>
</
div
>
</
Form
>
</
Modal
>
...
...
@@ -206,8 +211,8 @@ const Examine: React.FC<Iprops> = ({
)
}
Examine
.
defaultProps
=
{
agreeText
:
intl
.
formatMessage
({
id
:
'contract.tongguo'
}),
disagree
:
intl
.
formatMessage
({
id
:
'contract.butongguo'
}),
agreeText
:
intl
.
formatMessage
({
id
:
'contract.tongguo'
}),
disagree
:
intl
.
formatMessage
({
id
:
'contract.butongguo'
}),
uploadNode
:
null
}
export
default
Examine
;
src/pages/contract/contractexecution/details/index.tsx
View file @
1c5b1f4c
This diff is collapsed.
Click to expand it.
src/pages/contract/coordination/details/index.tsx
View file @
1c5b1f4c
...
...
@@ -64,6 +64,7 @@ const Details = (props: any) => {
const
[
basicData
,
setbasicData
]
=
useState
<
any
>
({
invoiceProveVOList
:
[],
})
// 合同付款基本信息
const
[
contractUrl
,
setcontractUrl
]
=
useState
(
''
);
/* 获取详情的数据 */
const
getDetail
=
()
=>
{
getContractCoordinationGetDetail
({
contractId
}).
then
(
res
=>
{
...
...
@@ -178,8 +179,10 @@ const Details = (props: any) => {
},
onChange
(
info
)
{
if
(
info
.
file
.
response
)
{
const
{
code
}
=
info
.
file
.
response
;
console
.
log
(
info
.
file
)
const
{
code
,
data
:
{
url
}
}
=
info
.
file
.
response
;
console
.
log
(
code
);
setcontractUrl
(
url
)
message
.
info
(
intl
.
formatMessage
({
id
:
'contract.shangchuanchenggong'
}));
setstate
(
true
);
}
...
...
@@ -247,6 +250,7 @@ const Details = (props: any) => {
break
;
case
'Sign'
:
fn
=
postContractCoordinationSign
;
values
.
contractUrl
=
contractUrl
break
;
default
:
break
;
...
...
@@ -479,6 +483,7 @@ const Details = (props: any) => {
<
Col
>
<
Upload
{
...
uploadProps
}
maxCount=
{
1
}
>
<
Button
icon=
{
<
UploadOutlined
/>
}
>
{
intl
.
formatMessage
({
id
:
'contract.shangchuanfujian'
})
}
</
Button
>
</
Upload
>
...
...
src/pages/contract/manage/details/index.tsx
View file @
1c5b1f4c
...
...
@@ -310,6 +310,7 @@ const Details = (props: any) => {
window
.
open
(
res
.
data
.
url
)
}
}
else
{
console
.
log
(
1111
)
setIsModalVisible
(
!
Visible
)
}
}
...
...
@@ -432,14 +433,22 @@ const Details = (props: any) => {
<
div
className=
'ant-card-head'
>
<
div
className=
'ant-card-head-wrapper'
>
<
div
className=
'ant-card-head-wrapper'
>
<
<<<<<<
HEAD
{
intl
.
formatMessage
({
id
:
'
contract
.
dianzihetong
'
})}
=======
{
contractText
.
isUseElectronicContract
?
intl
.
formatMessage
({
id
:
'
contract
.
dianzihetong
'
})
:
intl
.
formatMessage
({
id
:
'
contract
.
zhizhihetong
'
})}
>
>>>>>>
c401c53d5 (feat:合同功能调整)
</
div
>
</
div
>
</
div
>
<
div
className=
'ant-card-body'
>
<
div
className=
{
style
.
upload_item
}
style=
{
{
width
:
680
}
}
>
<
div
className=
'ant-card-head-wrapper'
>
<
<<<<<<
HEAD
{
intl
.
formatMessage
({
id
:
'
contract
.
dianzihetong
'
})}
=======
{
contractText
.
isUseElectronicContract
?
intl
.
formatMessage
({
id
:
'
contract
.
dianzihetong
'
})
:
intl
.
formatMessage
({
id
:
'
contract
.
zhizhihetong
'
})}
>
>>>>>>
c401c53d5 (feat:合同功能调整)
</
div
>
<
div
className=
{
style
.
upload_left
}
onClick=
{
()
=>
onDownload
(
contractText
)
}
style=
{
{
width
:
600
,
cursor
:
'pointer'
}
}
>
<
FileWordFilled
/>
...
...
src/pages/contract/manage/editing/components/ContractText.tsx
View file @
1c5b1f4c
...
...
@@ -81,16 +81,17 @@ const ContractText = (props: any) => {
const
beforeDocUpload
=
(
file
:
any
)
=>
{
const
isLt20M
=
file
.
size
/
1024
/
1024
<
20
;
if
(
!
isLt20M
)
{
message
.
error
(
intl
.
formatMessage
({
id
:
'contract.shangchuanwenjiandaxiaobuchao'
}));
message
.
error
(
intl
.
formatMessage
({
id
:
'contract.shangchuanwenjiandaxiaobuchao'
}));
}
return
isLt20M
;
}
// 上传回调
const
handleChange
=
({
fileList
})
=>
{
if
(
fileList
[
0
].
response
)
{
console
.
log
(
fileList
[
0
].
name
,
fileList
[
0
].
response
.
data
)
if
(
fileList
[
0
].
response
.
code
===
1000
)
{
Templatel
.
n
ame
=
fileList
[
0
].
name
Templatel
.
file
Url
=
fileList
[
0
].
response
.
data
Templatel
.
fileN
ame
=
fileList
[
0
].
name
Templatel
.
contract
Url
=
fileList
[
0
].
response
.
data
setTemplatel
({
...
Templatel
})
}
}
...
...
@@ -98,7 +99,7 @@ const ContractText = (props: any) => {
/* 生成电子合同 */
const
generate
=
()
=>
{
if
(
!
Templatel
.
id
)
{
message
.
info
(
intl
.
formatMessage
({
id
:
'contract.qingxianxuanzehetongmoban'
}))
message
.
info
(
intl
.
formatMessage
({
id
:
'contract.qingxianxuanzehetongmoban'
}))
}
else
{
const
param
=
{
contractTemplateId
:
Templatel
.
id
,
...
...
@@ -124,22 +125,22 @@ const ContractText = (props: any) => {
width
:
'100%'
,
}
}
>
<
Form
.
Item
label=
{
intl
.
formatMessage
({
id
:
'contract.hetongmuban'
})
}
labelAlign=
"left"
labelCol=
{
{
span
:
2
}
}
>
<
Form
.
Item
label=
{
intl
.
formatMessage
({
id
:
'contract.hetongmuban'
})
}
labelAlign=
"left"
labelCol=
{
{
span
:
2
}
}
>
<
Select
value=
{
Templatel
.
id
}
style=
{
{
width
:
600
}
}
options=
{
TemplatePage
}
placeholder=
{
intl
.
formatMessage
({
id
:
'contract.qingxuanzehetongmuban'
})
}
placeholder=
{
intl
.
formatMessage
({
id
:
'contract.qingxuanzehetongmuban'
})
}
onChange=
{
(
e
)
=>
getTemplate
(
e
)
}
>
</
Select
>
{
checkNick
&&
<
Button
type=
'link'
onClick=
{
()
=>
generate
()
}
>
{
intl
.
formatMessage
({
id
:
'contract.shengchenghetong'
})
}
</
Button
>
checkNick
&&
<
Button
type=
'link'
onClick=
{
()
=>
generate
()
}
>
{
intl
.
formatMessage
({
id
:
'contract.shengchenghetong'
})
}
</
Button
>
}
</
Form
.
Item
>
{
Object
.
keys
(
Templatel
).
length
!=
0
&&
<
Form
.
Item
label=
{
intl
.
formatMessage
({
id
:
'contract.hetongwenben'
})
}
labelAlign=
"left"
labelCol=
{
{
span
:
2
}
}
>
<
Form
.
Item
label=
{
intl
.
formatMessage
({
id
:
'contract.hetongwenben'
})
}
labelAlign=
"left"
labelCol=
{
{
span
:
2
}
}
>
<
div
className=
{
styles
.
upload_item
}
style=
{
{
width
:
680
}
}
>
<
div
className=
{
styles
.
upload_left
}
style=
{
{
width
:
600
}
}
>
<
FileWordFilled
/>
...
...
@@ -152,17 +153,19 @@ const ContractText = (props: any) => {
beforeUpload=
{
beforeDocUpload
}
onChange=
{
handleChange
}
accept=
'.doc,.docx'
maxCount=
{
1
}
>
<
div
className=
{
styles
.
uploadIconBtn
}
>
<
Button
type=
'link'
>
{
intl
.
formatMessage
({
id
:
'contract.shangchuanhetong'
})
}
</
Button
>
<
Button
type=
'link'
>
{
intl
.
formatMessage
({
id
:
'contract.shangchuanhetong'
})
}
</
Button
>
</
div
>
</
Upload
>
</
div
>
</
Form
.
Item
>
}
<
Form
.
Item
label=
{
intl
.
formatMessage
({
id
:
'contract.dianzihetong'
})
}
labelAlign=
"left"
labelCol=
{
{
span
:
2
}
}
>
<
Form
.
Item
label=
{
intl
.
formatMessage
({
id
:
'contract.dianzihetong'
})
}
labelAlign=
"left"
labelCol=
{
{
span
:
2
}
}
>
<
Checkbox
checked=
{
checkNick
}
onChange=
{
onCheckboxChange
}
>
{
intl
.
formatMessage
({
id
:
'contract.shiyongdianzihetong'
})
}
{
intl
.
formatMessage
({
id
:
'contract.shiyongdianzihetong'
})
}
</
Checkbox
>
</
Form
.
Item
>
</
div
>
...
...
src/pages/contract/manage/purchase/index.tsx
View file @
1c5b1f4c
...
...
@@ -23,7 +23,7 @@ const PurchaseList = () => {
const
[
selectRow
,
setSelectRow
]
=
useState
<
any
[]
>
([])
// 模态框选择的行数据
//表头
const
columns
:
ColumnType
<
any
>
[]
=
[{
title
:
intl
.
formatMessage
({
id
:
'contract.xuqiudanhaozhaiyao'
}),
title
:
intl
.
formatMessage
({
id
:
'contract.xuqiudanhaozhaiyao'
}),
dataIndex
:
'demandNO'
,
align
:
'left'
,
render
:
(
text
,
record
)
=>
...
...
@@ -37,7 +37,7 @@ const PurchaseList = () => {
<
p
>
{
record
.
demandAbstract
}
</
p
>
</
div
>
},
{
title
:
intl
.
formatMessage
({
id
:
'contract.xuqiufabushijian'
}),
title
:
intl
.
formatMessage
({
id
:
'contract.xuqiufabushijian'
}),
dataIndex
:
'demandPublishTime'
,
align
:
'left'
,
sorter
:
{
...
...
@@ -45,12 +45,12 @@ const PurchaseList = () => {
multiple
:
1
,
},
},
{
title
:
intl
.
formatMessage
({
id
:
'contract.shoubiaohuiyuan'
}),
title
:
intl
.
formatMessage
({
id
:
'contract.shoubiaohuiyuan'
}),
dataIndex
:
'awardName'
,
align
:
'left'
,
},
{
title
:
intl
.
formatMessage
({
id
:
'contract.shoubiaoshijian'
}),
title
:
intl
.
formatMessage
({
id
:
'contract.shoubiaoshijian'
}),
dataIndex
:
'awardTime'
,
align
:
'left'
,
sorter
:
{
...
...
@@ -59,7 +59,7 @@ const PurchaseList = () => {
},
},
{
title
:
intl
.
formatMessage
({
id
:
'contract.shoubiaojine'
}),
title
:
intl
.
formatMessage
({
id
:
'contract.shoubiaojine'
}),
dataIndex
:
'awardAmount'
,
align
:
'left'
,
sorter
:
{
...
...
@@ -75,7 +75,7 @@ const PurchaseList = () => {
}
},
{
title
:
intl
.
formatMessage
({
id
:
'contract.waibuzhuangtai'
}),
title
:
intl
.
formatMessage
({
id
:
'contract.waibuzhuangtai'
}),
dataIndex
:
'outerStatus'
,
align
:
'left'
,
...
...
@@ -87,7 +87,7 @@ const PurchaseList = () => {
}
},
{
title
:
intl
.
formatMessage
({
id
:
'contract.neibuzhuangtai'
}),
title
:
intl
.
formatMessage
({
id
:
'contract.neibuzhuangtai'
}),
dataIndex
:
'innerStatus'
,
align
:
'left'
,
render
:
(
text
)
=>
{
...
...
@@ -99,13 +99,13 @@ const PurchaseList = () => {
)
}
},
{
title
:
intl
.
formatMessage
({
id
:
'contract.caozuo'
}),
title
:
intl
.
formatMessage
({
id
:
'contract.caozuo'
}),
dataIndex
:
'state'
,
align
:
'left'
,
render
:
(
_
,
record
)
=>
{
return
(
<
div
>
<
span
style=
{
{
color
:
'#00B37A'
,
cursor
:
'pointer'
,
marginRight
:
10
}
}
onClick=
{
()
=>
like
(
record
)
}
>
{
intl
.
formatMessage
({
id
:
'contract.chuangjiancaigouxunjiahetong'
})
}
</
span
>
<
span
style=
{
{
color
:
'#00B37A'
,
cursor
:
'pointer'
,
marginRight
:
10
}
}
onClick=
{
()
=>
like
(
record
)
}
>
{
intl
.
formatMessage
({
id
:
'contract.chuangjiancaigouxunjiahetong'
})
}
</
span
>
</
div
>
)
}
...
...
src/pages/procurement/callForBids/addRemarkBidCommittee/index.tsx
View file @
1c5b1f4c
...
...
@@ -146,12 +146,22 @@ const AddRemarkBidCommittee: React.FC<AddRemarkBidCommitteeProps> = (props) => {
const
inviteTenderId
=
value
[
'inviteTender'
][
'id'
]
let
_value
=
omit
(
value
,
[
'code'
,
'createTime'
,
'openTenderTime'
,
'projectName'
,
'remarkTime'
,
'status'
,
'inviteTender'
])
_value
.
inviteTender
=
{
id
:
inviteTenderId
}
_value
.
expertExtractRecordList
=
value
?.
expertExtractRecordList
?.
length
?
value
.
expertExtractRecordList
.
map
(
item
=>
({
id
:
item
.
id
,
expert
:
{
id
:
item
.
expert
.
id
},
source
:
item
.
source
,
status
:
item
.
status
}))
:
[]
_value
.
expertExtractRecordList
=
value
?.
expertExtractRecordList
?.
length
?
value
.
expertExtractRecordList
.
map
(
item
=>
{
if
(
pageStatus
===
PageStatus
.
ADD
)
{
return
{
expert
:
{
id
:
item
.
expert
.
id
},
source
:
item
.
source
,
status
:
item
.
status
}
}
else
{
return
{
id
:
item
.
id
,
expert
:
{
id
:
item
.
expert
.
id
},
source
:
item
.
source
,
status
:
item
.
status
}
}
})
:
[]
_value
.
expertExtractQueryList
=
value
.
expertExtractQueryList
.
map
(
item
=>
omit
(
item
,
[
'excludeArea'
,
'needArea'
]))
if
(
_value
.
expertExtractRecordList
?.
length
)
{
postPurchaseExpertExtractSaveOrUpdateExpertExtract
(
_value
).
then
(
res
=>
{
...
...
src/pages/transaction/marketingAbility/components/couponsListLayout/index.tsx
View file @
1c5b1f4c
...
...
@@ -109,7 +109,15 @@ const CouponsListLayout: React.FC<CouponsListLayoutProps> = (props: any) => {
message
.
warning
(
remind
.
message
[
2
])
return
}
onConfirm
(
couponSource
)
let
limitValue
:
number
[]
=
[];
couponSource
.
forEach
(
_item
=>
{
limitValue
.
push
(
_item
.
limitValue
)
})
if
((
new
Set
(
limitValue
)).
size
!==
limitValue
.
length
)
{
message
.
error
(
`
${
remind
.
label
[
1
]}
阶梯必须大于或小于其他
${
remind
.
label
[
1
]}
阶梯`
)
}
else
{
onConfirm
(
couponSource
)
}
})
}
...
...
src/pages/transaction/marketingAbility/components/listModalLayout/components/productLayout/index.tsx
View file @
1c5b1f4c
...
...
@@ -81,7 +81,6 @@ const ProductLayout: React.FC<ProductLayoutProps> = (props: any) => {
required
:
true
,
validator
:
(
_rule
,
value
)
=>
{
const
pattern
=
/
(
^
[
1-9
](\d
+
)?(\.\d
{1,3}
)?
$
)
|
(
^
\d\.\d
{1,3}$
)
/
;
const
pattern1
=
/
(
^
[
1-9
](\d
+
)?(\.\d
{1,2}
)?
$
)
|
(
^
\d\.\d
{1,2}$
)
/
;
console
.
log
(
remind
,
'remind'
)
if
(
!
value
)
{
return
Promise
.
reject
(
new
Error
(
remind
.
message
[
4
]));
}
...
...
src/pages/transaction/marketingAbility/components/listModalLayout/index.tsx
View file @
1c5b1f4c
...
...
@@ -143,15 +143,23 @@ const ListModalLayout: React.FC<ListModalLayoutProps> = (props: any) => {
message
.
warning
(
remind
.
message
[
2
])
return
}
onConfirm
(
dataSource
)
let
limitValue
:
number
[]
=
[];
dataSource
.
forEach
(
_item
=>
{
limitValue
.
push
(
_item
.
limitValue
)
})
if
((
new
Set
(
limitValue
)).
size
!==
limitValue
.
length
)
{
message
.
error
(
`
${
remind
.
label
[
1
]}
阶梯必须大于或小于其他
${
remind
.
label
[
1
]}
阶梯`
)
}
else
{
onConfirm
(
dataSource
)
}
})
}
const
renderFooter
=
()
=>
{
return
(
<
div
style=
{
{
textAlign
:
'right'
}
}
>
<
Button
onClick=
{
onClose
}
style=
{
{
marginRight
:
8
}
}
>
{
intl
.
formatMessage
({
id
:
'marketingAbility.quxiao'
})
}
</
Button
>
<
Button
type=
"primary"
onClick=
{
handleClick
}
>
{
intl
.
formatMessage
({
id
:
'marketingAbility.tijiao'
})
}
</
Button
>
<
Button
onClick=
{
onClose
}
style=
{
{
marginRight
:
8
}
}
>
{
intl
.
formatMessage
({
id
:
'marketingAbility.quxiao'
})
}
</
Button
>
<
Button
type=
"primary"
onClick=
{
handleClick
}
>
{
intl
.
formatMessage
({
id
:
'marketingAbility.tijiao'
})
}
</
Button
>
</
div
>
)
}
...
...
@@ -295,7 +303,7 @@ const ListModalLayout: React.FC<ListModalLayoutProps> = (props: any) => {
))
}
</
Form
>
{
/* 添加分组 */
}
{
!
isPreview
&&
<
Button
type=
"dashed"
block
icon=
{
<
PlusOutlined
/>
}
onClick=
{
handleAppend
}
>
{
intl
.
formatMessage
({
id
:
'marketingAbility.tianjia'
})
}
</
Button
>
}
{
!
isPreview
&&
<
Button
type=
"dashed"
block
icon=
{
<
PlusOutlined
/>
}
onClick=
{
handleAppend
}
>
{
intl
.
formatMessage
({
id
:
'marketingAbility.tianjia'
})
}
</
Button
>
}
{
/* 弹框: -> 商品 */
}
<
CollocationLayout
isGift=
{
isGift
}
...
...
src/pages/transaction/marketingAbility/components/productListLayout/index.tsx
View file @
1c5b1f4c
...
...
@@ -73,7 +73,6 @@ const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
useEffect
(()
=>
{
if
(
focus$
)
{
console
.
log
(
focus$
,
10086
)
setValue
(
focus$
)
setDataSource
([])
}
...
...
@@ -201,6 +200,9 @@ const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
item
.
goodsSubsidiaryGroupList
=
[...
params
]
}
})
form
.
setFieldsValue
({
'productList'
:
fields
})
setListModalVisible
(
false
)
setDataSource
(
fields
)
}
...
...
@@ -213,6 +215,9 @@ const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
item
.
couponGroupList
=
[...
params
]
}
})
form
.
setFieldsValue
({
'productList'
:
fields
})
setListModalVisible
(
false
)
setDataSource
(
fields
)
}
...
...
src/pages/transaction/marketingAbility/selfManagement/readySubmitExamine/add.tsx
View file @
1c5b1f4c
...
...
@@ -247,7 +247,6 @@ const AddedMarketing = () => {
},
[])
const
handleGetRule
=
()
=>
{
console
.
log
(
!
refresh
)
setRefresh
(
!
refresh
)
}
...
...
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