Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
occloud-server
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
yangjiarong
occloud-server
Commits
79c04df0
Commit
79c04df0
authored
Aug 01, 2022
by
liuliufashi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
ef86df04
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
136 additions
and
68 deletions
+136
-68
index.ts
web-vue-admin/src/api/index.ts
+13
-2
index.ts
web-vue-admin/src/router/index.ts
+1
-1
request.ts
web-vue-admin/src/utils/request.ts
+2
-1
index.vue
...-admin/src/views/goods-cabinet/components/goods/index.vue
+46
-37
index.vue
...min/src/views/goods-cabinet/components/goodsubs/index.vue
+0
-0
index.vue
web-vue-admin/src/views/home/index.vue
+4
-3
index.vue
web-vue-admin/src/views/login/index.vue
+12
-4
index.vue
web-vue-admin/src/views/pay-bind/index.vue
+37
-11
index.vue
...vue-admin/src/views/pay-config/compoents/header/index.vue
+0
-1
index.vue
...e-admin/src/views/pay-list/components/createpay/index.vue
+1
-1
index.vue
web-vue-admin/src/views/pay-list/index.vue
+20
-7
No files found.
web-vue-admin/src/api/index.ts
View file @
79c04df0
...
...
@@ -120,7 +120,7 @@ export const onCreateGoods = async(data:any)=>{
}
export
const
onfindAli
=
async
(
uid
:
any
)
=>
{
return
await
request
({
url
:
`/pay/find
alipay
?uid=
${
uid
}
`
,
url
:
`/pay/find
Ali
?uid=
${
uid
}
`
,
method
:
'post'
,
});
}
...
...
@@ -160,7 +160,7 @@ export const onFindbyLikeName = async(params:any)=>{
export
const
onfindby
=
async
(
params
:
any
)
=>
{
return
await
request
({
url
:
`/goods/findgoodspays?uid=
${
params
.
uid
}
&
name=
${
params
.
name
}
&status=
${
params
.
status
}
&
page=
${
params
.
page
}
&size=
${
params
.
size
}
`
,
url
:
`/goods/findgoodspays?uid=
${
params
.
uid
}
&page=
${
params
.
page
}
&size=
${
params
.
size
}
`
,
method
:
'post'
,
});
}
...
...
@@ -231,4 +231,14 @@ export const onDisableWx = async(data:any)=>{
data
});
}
export
const
onFindBysub
=
async
(
data
:
any
)
=>
{
return
await
request
({
url
:
`/goods/findBysub?subject=
${
data
.
subject
}
&uid=
${
data
.
uid
}
&page=
${
data
.
page
}
&size=
${
data
.
size
}
`
,
method
:
'post'
,
data
});
}
// /goods/findBysub
// /pay/DisableAli
\ No newline at end of file
web-vue-admin/src/router/index.ts
View file @
79c04df0
...
...
@@ -19,7 +19,7 @@ const routes: Array<RouteRecordRaw> = [
path
:
'/home'
,
name
:
'Home'
,
component
:
Home
,
redirect
:
'/home/
paybind
'
,
redirect
:
'/home/
goodscabinet
'
,
children
:[
{
path
:
'/home/paybind'
,
...
...
web-vue-admin/src/utils/request.ts
View file @
79c04df0
...
...
@@ -19,7 +19,8 @@ instance.interceptors.request.use(
function
(
config
:
any
)
{
// 这里判断localStorage里面是否存在token,如果有则在请求头里面设置
if
(
token
)
{
// config.headers.Authorization = token;
config
.
headers
.
Authorization
=
token
;
config
.
headers
[
'token'
]
=
token
;
}
return
config
;
},
...
...
web-vue-admin/src/views/goods-cabinet/components/goods/index.vue
View file @
79c04df0
...
...
@@ -15,19 +15,24 @@
<a-form-item
label=
" 商品示图"
name=
"picurl"
:rules=
"rulesRef.picurl"
:wrapper-col=
"
{ offset: 0, span: 8 }" class="Up"
labelAlign="left" :label-col="{ span: 2 }">
<div
class=
"clearfix"
>
<a-upload
class=
"clearfix-up"
v-model:file-list=
"fileList"
action=
"http://43.142.42.187:8899/file/upload"
list-type=
"picture-card"
:maxCount=
"1"
@
preview=
"handlePreview"
@
change=
"handleChange"
:before-upload=
"beforeUpload"
>
<div
v-if=
"fileList.length
<
8
"
>
<plus-outlined
/>
<div
style=
"margin-top: 8px"
>
Upload
</div>
<a-upload
v-model:file-list=
"fileList"
list-type=
"picture-card"
:show-upload-list=
"false"
action=
"http://43.142.42.187:8899/file/upload"
:before-upload=
"beforeUpload"
@
change=
"handleChange"
>
<img
v-if=
"imageUrl"
:src=
"imageUrl"
alt=
"avatar"
style=
"width: 102px;height: 102px;"
/>
<div
v-else
>
<loading-outlined
v-if=
"loading"
></loading-outlined>
<plus-outlined
v-else
></plus-outlined>
<div
class=
"ant-upload-text"
>
Upload
</div>
</div>
</a-upload>
<a-modal
:visible=
"previewVisible"
:title=
"previewTitle"
:footer=
"null"
@
cancel=
"handleCancel"
>
<img
alt=
"example"
style=
"width: 100%"
:src=
"previewImage"
/>
</a-modal>
<div>
<p
class=
"warin"
>
建议图片比例为4:3,大小不超过2
0
M,图片仅支持JPG、JPEG、PNG格式
建议图片比例为4:3,大小不超过2M,图片仅支持JPG、JPEG、PNG格式
</p>
</div>
</div>
...
...
@@ -35,8 +40,8 @@
<a-form-item
label=
"商品详情"
name=
"body"
labelAlign=
"left"
:label-col=
"
{ span: 2 }">
<div
style=
"position: relative;"
>
<div
style=
"display:none"
>
<a-upload
class=
"clearfix-up-1"
action=
"http://43.142.42.187:8899/file/upload"
list-type=
"picture-card"
:maxCount=
"1"
@
preview=
"onHandlePreview"
@
change=
"onEdithandleChange"
:before-upload=
"onBeforeUpload"
>
<a-upload
class=
"clearfix-up-1"
action=
"http://43.142.42.187:8899/file/upload"
list-type=
"picture-card"
:maxCount=
"1"
@
change=
"onEdithandleChange"
:before-upload=
"onBeforeUpload"
>
<div
ref=
"upImage"
style=
"width:30px;height:30px;border: none;"
><i
class=
"iconfont icon-tupian"
style=
"font-size:28px;"
></i>
</div>
</a-upload>
...
...
@@ -99,7 +104,8 @@ import { getUid } from "@/utils/userInfo";
const
useForm
=
Form
.
useForm
;
const
upImage
=
ref
<
any
>
(
null
)
const
textarea
=
ref
<
any
>
(
''
)
const
loading
=
ref
<
boolean
>
(
false
);
const
imageUrl
=
ref
<
string
>
(
''
);
interface
FormState
{
subject
:
string
,
shortname
:
string
;
...
...
@@ -167,7 +173,7 @@ let content = ref("");
const
myQuillEditor
=
ref
<
any
>
(
null
);
const
crossedPrice
=
ref
<
Number
>
(
1
);
const
sellingPrice
=
ref
<
Number
>
(
1
);
const
value
=
ref
<
number
>
(
1
);
const
value
=
ref
<
string
>
(
'1'
);
const
previewVisible
=
ref
(
false
);
const
previewImage
=
ref
(
""
);
const
previewTitle
=
ref
(
""
);
...
...
@@ -199,24 +205,6 @@ const handleCancel = () => {
previewVisible
.
value
=
false
;
previewTitle
.
value
=
""
;
};
const
handlePreview
=
async
(
file
:
any
)
=>
{
if
(
!
file
.
url
&&
!
file
.
preview
)
{
file
.
preview
=
(
await
getBase64
(
file
.
originFileObj
))
as
string
;
}
previewImage
.
value
=
file
.
url
||
file
.
preview
;
previewVisible
.
value
=
true
;
previewTitle
.
value
=
file
.
name
||
file
.
url
.
substring
(
file
.
url
.
lastIndexOf
(
"/"
)
+
1
);
};
const
onHandlePreview
=
async
(
file
:
any
)
=>
{
if
(
!
file
.
url
&&
!
file
.
preview
)
{
file
.
preview
=
(
await
getBase64
(
file
.
originFileObj
))
as
string
;
}
previewImage
.
value
=
file
.
url
||
file
.
preview
;
previewVisible
.
value
=
true
;
previewTitle
.
value
=
file
.
name
||
file
.
url
.
substring
(
file
.
url
.
lastIndexOf
(
"/"
)
+
1
);
};
const
formState
=
reactive
<
FormState
>
({
subject
:
''
,
shortname
:
""
,
...
...
@@ -256,6 +244,8 @@ const onFinishFailed = (errorInfo: any) => {
console
.
log
(
"Failed:"
,
errorInfo
);
};
const
handleChange
=
(
info
:
any
)
=>
{
const
size
=
info
.
file
.
size
/
1024
if
(
size
<
2000
){
let
resFileList
=
[...
info
.
fileList
];
// 1. Limit the number of uploaded files
...
...
@@ -266,16 +256,21 @@ const handleChange = (info: any) => {
resFileList
=
resFileList
.
map
((
file
)
=>
{
if
(
file
.
response
)
{
// Component will show file.url as link
formState
.
picurl
=
file
.
response
.
data
;
imageUrl
.
value
=
file
.
response
.
data
;
formState
.
picurl
=
imageUrl
.
value
}
return
file
;
});
fileList
.
value
=
resFileList
;
}
else
{
}
};
const
onEdithandleChange
=
(
info
:
any
)
=>
{
const
size
=
info
.
file
.
size
/
1024
if
(
size
<
2000
){
let
resFileList
=
[...
info
.
fileList
];
resFileList
=
resFileList
.
slice
(
-
2
);
resFileList
=
resFileList
.
map
((
file
)
=>
{
...
...
@@ -286,12 +281,15 @@ const onEdithandleChange = (info: any) => {
if
(
!!
resFileList
)
{
isEditfileList
.
value
=
resFileList
;
}
}
else
{
}
};
const
onSelectPlain
=
(
e
:
any
)
=>
{
if
(
e
.
target
.
value
==
'0'
){
formState
.
value
.
price
=
"
1"
formState
.
price
=
"0.0
1"
}
else
{
formState
.
value
.
price
=
""
formState
.
price
=
""
}
value
.
value
=
e
.
target
.
value
;
...
...
@@ -300,16 +298,27 @@ const onEditorChange = (e: any) => {
console
.
log
(
e
.
html
,
'e'
);
}
const
beforeUpload
:
UploadProps
[
'beforeUpload'
]
=
file
=>
{
const
size
=
file
.
size
/
1024
if
(
size
<
2000
){
if
(
!
(
file
.
type
.
includes
(
'png'
)
||
file
.
type
.
includes
(
'jpeg'
)
||
file
.
type
.
includes
(
'jpg'
)))
{
message
.
error
(
`
${
file
.
name
}
不是png/jpef/jpg格式`
);
return
Upload
.
LIST_IGNORE
;
}
}
else
{
message
.
info
(
'图片最大为2M'
)
}
};
const
onBeforeUpload
:
UploadProps
[
'beforeUpload'
]
=
file
=>
{
const
size
=
file
.
size
/
1024
if
(
size
<
2000
){
if
(
!
(
file
.
type
.
includes
(
'png'
)
||
file
.
type
.
includes
(
'jpeg'
)
||
file
.
type
.
includes
(
'jpg'
)))
{
message
.
error
(
`
${
file
.
name
}
不是png/jpef/jpg格式`
);
return
Upload
.
LIST_IGNORE
;
}
}
else
{
message
.
info
(
'图片最大为2M'
)
}
};
const
onSubmit
=
()
=>
{
...
...
@@ -354,6 +363,8 @@ defineExpose({
previewVisible
,
previewImage
,
fileList
,
loading
,
imageUrl
,
previewTitle
,
options
,
content
,
...
...
@@ -377,10 +388,8 @@ defineExpose({
onSelectPlain
,
handleChange
,
handleCancel
,
handlePreview
,
onFinish
,
onFinishFailed
,
onHandlePreview
,
onEdithandleChange
,
onBeforeUpload
});
...
...
web-vue-admin/src/views/goods-cabinet/components/goodsubs/index.vue
View file @
79c04df0
This diff is collapsed.
Click to expand it.
web-vue-admin/src/views/home/index.vue
View file @
79c04df0
...
...
@@ -31,7 +31,7 @@
>
<a-menu-item
v-for=
"item,index in list"
:key=
"i
tem
"
:key=
"i
ndex
"
@
click=
"goNewPage(item,index)"
>
<div
style=
"display: flex; align-items: center"
>
...
...
@@ -85,8 +85,8 @@ interface FormUser {
const
router
=
useRouter
();
const
store
=
useStore
();
const
indexItem
=
ref
<
any
>
(
'0'
)
const
selectedKeys
=
ref
<
string
[]
>
([
"1"
])
const
indexItem
=
ref
<
Number
>
(
0
)
const
selectedKeys
=
ref
<
string
[]
>
([
0
])
const
list
=
ref
<
any
>
()
const
info
=
reactive
<
FormUser
>
(
store
.
getters
.
getUserInfo
);
const
goNewPage
=
(
e
:
any
,
index
:
any
)
=>
{
...
...
@@ -103,6 +103,7 @@ const handleMenuClick: MenuProps['onClick'] = async(e) => {
console
.
log
(
'click'
,
e
);
if
(
e
.
key
==
'1'
){
const
data
=
await
onLogOut
()
localStorage
.
removeItem
(
'uid'
)
router
.
replace
({
path
:
'/login'
})
...
...
web-vue-admin/src/views/login/index.vue
View file @
79c04df0
...
...
@@ -73,7 +73,7 @@
<
script
lang=
"ts"
setup
>
import
{
useRouter
}
from
"vue-router"
;
import
{
defineExpose
,
reactive
,
ref
,
toRaw
}
from
"vue"
;
import
{
defineExpose
,
reactive
,
ref
,
toRaw
,
onMounted
}
from
"vue"
;
import
{
onLogin
}
from
"@/api/index"
;
import
{
message
}
from
"ant-design-vue"
;
import
{
useStore
}
from
"vuex"
;
...
...
@@ -87,7 +87,6 @@ interface FormState {
const
checked
=
ref
<
boolean
>
(
false
);
const
loading
=
ref
<
boolean
>
(
false
);
const
router
=
useRouter
();
const
store
=
useStore
();
const
formState
=
reactive
<
FormState
>
({
username
:
""
,
password
:
""
,
...
...
@@ -105,9 +104,9 @@ const onSubmit = async () => {
name
:
toRaw
(
formState
).
username
,
password
:
toRaw
(
formState
).
password
,
};
if
(
checked
.
value
)
{
if
(
checked
.
value
)
{
const
data
:
any
=
await
onLogin
(
JSON
.
stringify
(
user
));
console
.
log
(
data
,
'data'
);
loading
.
value
=
true
if
(
data
.
message
===
"ok"
&&
data
.
state
===
1
)
{
setUserInfo
(
user
);
...
...
@@ -130,6 +129,15 @@ const onRegister = () => {
const
onAgreement
=
()
=>
{
window
.
open
(
"https://xs-legal.finezb.com/service.html"
,
"_blank"
);
};
onMounted
(()
=>
{
if
(
!!
localStorage
.
getItem
(
'uid'
)){
router
.
push
({
path
:
"/home"
,
});
}
else
{
return
}
})
defineExpose
({
formState
,
checked
,
...
...
web-vue-admin/src/views/pay-bind/index.vue
View file @
79c04df0
...
...
@@ -234,17 +234,11 @@ const onSubmit = async () => {
validate
()
.
then
(
async
()
=>
{
let
data
:
any
=
{};
const
prarms
=
{
paytype
:
query
.
value
.
paytype
,
uid
:
getUid
(),
...
toRaw
(
modelRef
),
};
if
(
status
.
value
===
1
)
{
let
prarms
:
any
=
{
}
if
(
query
.
value
.
paytype
==
"1"
){
prarms
=
{
amount
:
dataFrom
.
value
.
amount
,
id
:
dataFrom
.
value
.
id
,
...
...
@@ -269,6 +263,7 @@ const onSubmit = async () => {
...
toRaw
(
modelRef
),
};
}
if
(
query
.
value
.
paytype
==
"1"
)
{
data
=
await
onUpdateWX
(
JSON
.
stringify
(
prarms
));
}
else
if
(
query
.
value
.
paytype
==
"2"
)
{
...
...
@@ -282,6 +277,34 @@ const onSubmit = async () => {
}
await
init
();
}
else
{
let
prarms
:
any
=
{
}
if
(
query
.
value
.
paytype
==
"1"
){
prarms
=
{
amount
:
dataFrom
.
value
.
amount
,
id
:
dataFrom
.
value
.
id
,
paystate
:
dataFrom
.
value
.
paystate
,
paytype
:
dataFrom
.
value
.
paytype
,
status
:
dataFrom
.
value
.
status
,
weight
:
dataFrom
.
value
.
weight
,
mchid
:
toRaw
(
modelRef
).
privatekey
,
mchkey
:
toRaw
(
modelRef
).
alipaypublickey
,
...
toRaw
(
modelRef
),
};
}
else
{
prarms
=
{
amount
:
dataFrom
.
value
.
amount
,
id
:
dataFrom
.
value
.
id
,
paystate
:
dataFrom
.
value
.
paystate
,
paytype
:
dataFrom
.
value
.
paytype
,
status
:
dataFrom
.
value
.
status
,
weight
:
dataFrom
.
value
.
weight
,
mchid
:
toRaw
(
modelRef
).
mchid
,
mchkey
:
toRaw
(
modelRef
).
mchkey
,
...
toRaw
(
modelRef
),
};
}
if
(
query
.
value
.
paytype
==
1
)
{
data
=
await
onWxPay
(
prarms
);
}
else
if
(
query
.
value
.
paytype
==
2
)
{
...
...
@@ -323,19 +346,22 @@ const onSetShowTable = async (data: any) => {
status
.
value
=
1
;
isShowTable
.
value
=
false
;
if
(
query
.
value
.
paytype
==
1
)
{
console
.
log
(
data
,
'data'
);
const
{
appid
,
name
}
=
data
;
const
uid
:
any
=
getUid
();
modelRef
.
privatekey
=
modelRef
.
privatekey
;
modelRef
.
alipaypublickey
=
modelRef
.
alipaypublickey
;
modelRef
.
privatekey
=
''
;
modelRef
.
alipaypublickey
=
''
;
modelRef
.
appid
=
appid
;
modelRef
.
name
=
name
;
// modelRef.server_url =server_url
modelRef
.
uid
=
uid
;
}
else
{
const
{
alipaypublickey
,
privatekey
,
appid
,
payname
}
=
data
;
const
{
alipaypublickey
,
privatekey
,
appid
,
name
}
=
data
;
const
uid
:
any
=
getUid
();
modelRef
.
alipaypublickey
=
''
;
modelRef
.
privatekey
=
privatekey
;
modelRef
.
privatekey
=
''
;
modelRef
.
appid
=
appid
;
modelRef
.
name
=
name
;
// modelRef.server_url =server_url
...
...
web-vue-admin/src/views/pay-config/compoents/header/index.vue
View file @
79c04df0
...
...
@@ -41,7 +41,6 @@
</div>
<div
v-else-if=
"column.key === 'tags'"
>
<a-button
type=
"primary"
@
click=
"onOpenInfo(record, index, column)"
>
查看
</a-button>
</div>
</
template
>
</a-table>
...
...
web-vue-admin/src/views/pay-list/components/createpay/index.vue
View file @
79c04df0
...
...
@@ -85,7 +85,7 @@
<a-radio-group
v-model:value=
"modalvalue"
>
<div
v-for=
"item in list"
:itemkey=
"item.id"
>
<a-radio
v-if=
"item.paytype == 1"
:value=
"item.id"
:lable=
"item.id"
@
change=
"onChangeRadioName(item)"
>
{{
item
.
name
}}
</a-radio>
<a-radio
v-else-if=
"item.paytype == 2"
:value=
"item.id"
:lable=
"item.id"
@
change=
"onChangeRadioName(item)"
>
{{
item
.
pay
name
}}
</a-radio>
<a-radio
v-else-if=
"item.paytype == 2"
:value=
"item.id"
:lable=
"item.id"
@
change=
"onChangeRadioName(item)"
>
{{
item
.
name
}}
</a-radio>
</div>
</a-radio-group>
</a-modal>
...
...
web-vue-admin/src/views/pay-list/index.vue
View file @
79c04df0
...
...
@@ -3,7 +3,7 @@
<div
style=
"display: flex;align-items: center;justify-content: space-between;"
v-if=
"isShow"
>
<div>
<a-input-search
v-model:value=
"value"
placeholder=
"请输入商品名"
style=
"width: 200px;margin-left: 20px;"
@
search=
"onSearch"
/>
@
search=
"on
Get
Search"
/>
</div>
<div>
<a-button
type=
"primary"
block
@
click=
"onCreatePay"
>
新建支付项
</a-button>
...
...
@@ -118,7 +118,7 @@ import { ref, defineExpose, onMounted,reactive } from 'vue';
import
{
SelectProps
,
message
}
from
'ant-design-vue'
;
import
{
getUid
}
from
'@/utils/userInfo'
import
moment
from
'moment'
;
import
{
onUpdateGoodsPay
,
onfindby
,
onfindWX
,
onfindAli
,
onDelectgoodpay
,
onFindbyLikeName
}
from
'@/api/index'
import
{
onUpdateGoodsPay
,
onfindby
,
onfindWX
,
onfindAli
,
onDelectgoodpay
,
onFindbyLikeName
,
onFindBysub
}
from
'@/api/index'
import
CreatePay
from
'./components/createpay/index.vue'
import
dayjs
,
{
Dayjs
}
from
'dayjs'
;
import
useClipboard
from
'vue-clipboard3'
...
...
@@ -141,6 +141,7 @@ let formState = ref<any>({
})
const
pagination
=
reactive
({
total
:
0
,
page
:
1
,
defaultPageSize
:
10
,
showSizeChanger
:
true
,
pageSizeOptions
:
[
'5'
,
'10'
,
'15'
,
'20'
],
...
...
@@ -180,8 +181,8 @@ const columns = [
},
{
title
:
'备注'
,
dataIndex
:
'
shortname
'
,
key
:
'
shortname
'
,
dataIndex
:
'
remark
'
,
key
:
'
remark
'
,
},
{
title
:
'操作'
,
...
...
@@ -218,6 +219,17 @@ const handleOk =async(e: MouseEvent) => {
onSearch
()
}
};
const
onGetSearch
=
async
()
=>
{
const
params
=
{
size
:
pagination
.
defaultPageSize
,
page
:
pagination
.
page
,
uid
:
getUid
(),
subject
:
value
.
value
}
const
data
=
await
onFindBysub
(
params
)
list
.
value
=
data
.
data
.
goods
pagination
.
total
=
data
.
data
.
count
}
const
onEdit
=
(
e
:
any
)
=>
{
formState
.
value
=
{
...
e
...
...
@@ -232,8 +244,8 @@ const onEdit = (e: any) => {
}
const
onSearch
=
async
()
=>
{
const
params
=
{
page
:
1
,
size
:
10
,
size
:
pagination
.
defaultPageSize
,
page
:
pagination
.
page
,
name
:
value
.
value
,
uid
:
getUid
()
}
...
...
@@ -247,7 +259,7 @@ const tableChange=async(e:any)=>{
per_page
:
e
.
pageSize
//每页显示条数
};
const
params
=
{
size
:
queryData
.
per_page
,
size
:
queryData
.
per_page
,
page
:
queryData
.
current_page
,
uid
:
getUid
()
}
...
...
@@ -360,6 +372,7 @@ defineExpose({
popupScroll
,
onSet
,
onSearch
,
onGetSearch
,
onEdit
,
onCreatePay
,
onBack
,
...
...
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