Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
multiSystem
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
Yulun Yao
multiSystem
Commits
20d43b3b
Commit
20d43b3b
authored
Oct 15, 2020
by
Gakki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
aaa
parent
713b54b0
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
356 additions
and
45 deletions
+356
-45
webpack.prod.conf.js
build/webpack.prod.conf.js
+1
-1
index.js
config/index.js
+7
-0
App.vue
src/App.vue
+0
-18
index.vue
src/components/Layout/index.vue
+8
-11
getMicRouters.js
src/router/getMicRouters.js
+5
-7
micSystemsList.json
src/router/micSystemsList.json
+15
-0
pudongRoutes.json
src/router/pudongRoutes.json
+20
-2
routes.js
src/router/routes.js
+15
-3
xuhuiRoutes.json
src/router/xuhuiRoutes.json
+76
-1
api.js
src/server/api.js
+2
-2
sysInfoSetting.vue
src/views/personal/sysInfoSetting.vue
+207
-0
No files found.
build/webpack.prod.conf.js
View file @
20d43b3b
...
...
@@ -11,8 +11,8 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin')
const
OptimizeCSSPlugin
=
require
(
'optimize-css-assets-webpack-plugin'
)
const
UglifyJsPlugin
=
require
(
'uglifyjs-webpack-plugin'
)
let
env
=
require
(
'../config/prod.env'
)
console
.
log
(
process
.
env
.
NODE_ENV
)
let
env
=
require
(
'../config/prod.env'
)
if
(
process
.
env
.
NODE_ENV
===
'sit'
)
{
env
=
require
(
'../config/sit.env'
)
}
else
if
(
process
.
env
.
NODE_ENV
===
'uat'
)
{
...
...
config/index.js
View file @
20d43b3b
...
...
@@ -18,6 +18,13 @@ module.exports = {
// '^/api': ''
// }
// }
'/api'
:
{
target
:
'http://hm.omniview.pro/api'
,
changOrigin
:
true
,
pathRewrite
:
{
'^/api'
:
''
}
}
},
// Various Dev Server settings
...
...
src/App.vue
View file @
20d43b3b
...
...
@@ -34,24 +34,6 @@ export default {
// window.addEventListener('beforeunload', () => {
// sessionStorage.setItem('VuexStore', JSON.stringify(this.$store.state))
// })
const
addRoutes
=
(
data
)
=>
{
const
{
routes
}
=
this
.
$router
.
options
const
parent
=
routes
.
find
(
item
=>
item
.
name
===
'Layout'
)
parent
.
children
.
push
(...
data
)
this
.
$router
.
addRoutes
([
parent
])
}
if
(
this
.
$store
.
state
.
routes
.
length
>
0
)
{
addRoutes
(
this
.
$store
.
state
.
routes
)
return
}
},
beforeDestroy
()
{
window
.
removeEventListener
(
'beforeunload'
,
()
=>
{
sessionStorage
.
setItem
(
'VuexStore'
,
JSON
.
stringify
(
this
.
$store
.
state
))
})
},
watch
:
{
content
(
cur
)
{
...
...
src/components/Layout/index.vue
View file @
20d43b3b
...
...
@@ -143,20 +143,17 @@ export default {
},
deep
:
true
},
$route
(
to
,
from
)
{
if
(
to
.
meta
.
openMode
&&
(
to
.
meta
.
openMode
==
'child'
)
){
const
astore
=
JSON
.
parse
(
sessionStorage
.
getItem
(
'VuexStore'
))
if
(
astore
)
astore
.
content
=
''
sessionStorage
.
setItem
(
'VuexStore'
,
JSON
.
stringify
(
astore
))
}
},
},
created
(){
this
.
getLogo
()
this
.
getInfo
()
/** 持久化存储vuex 使其页面刷新后数据不丢失 */
//在页面加载时读取sessionStorage里的状态信息
if
(
sessionStorage
.
getItem
(
'VuexStore'
))
{
this
.
$store
.
replaceState
(
Object
.
assign
({},
this
.
$store
.
state
,
JSON
.
parse
(
sessionStorage
.
getItem
(
'VuexStore'
))))
}
//在页面刷新时将vuex里的信息保存到sessionStorage里
window
.
addEventListener
(
'beforeunload'
,
()
=>
{
sessionStorage
.
setItem
(
'VuexStore'
,
JSON
.
stringify
(
this
.
$store
.
state
))
})
},
methods
:
{
showChangePwdModal
(){
...
...
src/router/getMicRouters.js
View file @
20d43b3b
...
...
@@ -4,24 +4,22 @@ import xuhui from '@/router/xuhuiRoutes.json'
async
function
GetRoutes
(
router
)
{
let
env
=
process
.
env
.
NODE_ENV
console
.
log
(
env
)
let
MicRouters
switch
(
env
)
{
case
env
.
indexOf
(
'pudong'
)
>
-
1
:
case
env
.
indexOf
(
'pudong'
)
>
-
1
:
// 根据当前打包的项目调用该项目对应的路由
MicRouters
=
pudong
break
case
env
.
indexOf
(
'xuhui'
)
>
-
1
:
MicRouters
=
xuhui
break
default
:
default
:
// 当前仅可使用pudong / xuhui -sit/uat进行打包
MicRouters
=
pudong
break
}
// const MicRouters = require('@/router/micRouter.json')
// const rv = Math.floor(Math.random() * Math.random() * 10000)
// const MicRouters = (
// await Axios.get(api.CONFIGS_MICSYSTEMS_ROUTERS + '?v=' + rv)
// ).data
const
micSystemRoutersConfigs
=
Object
.
assign
({},
MicRouters
)
const
{
routes
}
=
router
.
options
const
parent
=
routes
.
find
(
item
=>
item
.
name
===
'Layout'
)
...
...
src/router/micSystemsList.json
View file @
20d43b3b
...
...
@@ -8,5 +8,20 @@
"name"
:
"danger"
,
"entry"
:
"http://211.136.105.193/dangerweb"
,
"activeRule"
:
"/danger"
},
{
"name"
:
"czd"
,
"entry"
:
"http://211.136.105.193/czd"
,
"activeRule"
:
"/czd"
},
{
"name"
:
"xuhuiChild1"
,
"entry"
:
"http://31.0.161.39/xuhuiChild1"
,
"activeRule"
:
"/xuhuiChild1"
},
{
"name"
:
"xuhuiChild2"
,
"entry"
:
"http://31.0.161.39/xuhuiChild2"
,
"activeRule"
:
"/xuhuiChild2"
}
]
src/router/pudongRoutes.json
View file @
20d43b3b
...
...
@@ -33,6 +33,10 @@
{
"path"
:
"/pudong/successCase"
,
"name"
:
"successCase"
,
"meta"
:
{
"title"
:
"成功案例"
,
"menuPath"
:
true
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
}
},
{
"path"
:
"/pudong/streetMailSettings"
,
"name"
:
"streetMailSettings"
,
"meta"
:
{
"title"
:
"街道邮件配置"
,
"menuPath"
:
true
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
}
}
]
},
...
...
@@ -48,7 +52,7 @@
},
{
"path"
:
"/danger/creditTitle"
,
"name"
:
"creditTitle"
,
"meta"
:
{
"title"
:
"信用主体评分"
,
"menuPath"
:
true
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
}
"meta"
:
{
"title"
:
"信用主体评分"
,
"menuPath"
:
true
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
,
"openMode"
:
"child"
}
},
{
"path"
:
"/danger/creditManage"
,
"name"
:
"creditManage"
,
...
...
@@ -63,6 +67,20 @@
"meta"
:
{
"title"
:
"隐患点管理"
,
"menuPath"
:
true
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
}
}
]
},
{
"path"
:
"/czd/systemManagement/placementContactManagement"
,
"name"
:
"placementContactManagement"
,
"meta"
:
{
"title"
:
"处置单联系方式管理"
,
"menuPath"
:
true
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
},
"children"
:
[
{
"path"
:
"/czd/systemManagement/placementContactManagement/commiteeContactManagement"
,
"name"
:
"commiteeContactManagement"
,
"meta"
:
{
"title"
:
"居委会联系人管理"
,
"menuPath"
:
true
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
}
},
{
"path"
:
"/czd/systemManagement/placementContactManagement/propertyContactManagement"
,
"name"
:
"propertyContactManagement"
,
"meta"
:
{
"title"
:
"物业联系人管理"
,
"menuPath"
:
true
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
}
}
]
}
]
}
\ No newline at end of file
src/router/routes.js
View file @
20d43b3b
...
...
@@ -133,10 +133,22 @@ const appRoutes = [
},
]
},
{
path
:
'/systemManagement'
,
name
:
'systemManagement'
,
component
:
resolve
=>
require
([
'@/components/Layout/content-wrapper'
],
resolve
),
//ContentWrapper,
meta
:
{
title
:
'系统管理'
,
menuPath
:
true
,
menuIcon
:
'profile'
,
hideInBread
:
true
},
children
:
[
{
// 系统信息配置
path
:
'/systemManagement/sysInfoSetting'
,
name
:
'sysInfoSetting'
,
component
:
resolve
=>
require
([
'@/views/personal/sysInfoSetting'
],
resolve
),
//NonResidents,
meta
:
{
title
:
'系统信息配置'
,
menuPath
:
true
,
hideInBread
:
false
,
},
children
:
[
]
},
{
// 拓展信息管理
path
:
'
/tbls'
,
name
:
'tbls'
,
component
:
resolve
=>
require
([
'@/views/houseData/tbls'
],
resolve
),
//Tbls,
path
:
'/systemManagement
/tbls'
,
name
:
'tbls'
,
component
:
resolve
=>
require
([
'@/views/houseData/tbls'
],
resolve
),
//Tbls,
meta
:
{
title
:
'拓展信息管理'
,
menuPath
:
true
,
menuIcon
:
'setting'
,
hideInBread
:
false
,
},
},
]
},
],
},
{
...
...
src/router/xuhuiRoutes.json
View file @
20d43b3b
[]
\ No newline at end of file
{
"Layout"
:
[
{
"path"
:
"/xuhuiChild1/disposal"
,
"name"
:
"Disposal"
,
"meta"
:
{
"title"
:
"处置单列表"
,
"menuPath"
:
false
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
},
"children"
:[
{
"path"
:
"/xuhuiChild1/disposal/disposalList"
,
"name"
:
"disposalList"
,
"meta"
:
{
"title"
:
"处置单列表"
,
"menuPath"
:
false
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
false
},
"children"
:
[
{
"path"
:
"/xuhuiChild1/disposal/disposalView/:id"
,
"name"
:
"DisposalView"
,
"meta"
:
{
"title"
:
"处置单详情"
,
"menuPath"
:
false
,
"hideInBread"
:
false
}
}
]
}
]
},
{
"path"
:
"/xuhuiChild1/month"
,
"name"
:
"month"
,
"meta"
:
{
"title"
:
"房办月查"
,
"menuIcon"
:
"profile"
,
"menuPath"
:
false
,
"hideInBread"
:
false
},
"children"
:[
{
"path"
:
"/xuhuiChild1/month/monthList"
,
"name"
:
"month"
,
"meta"
:
{
"title"
:
"房办月查列表"
,
"menuIcon"
:
"profile"
,
"menuPath"
:
false
,
"hideInBread"
:
false
},
"children"
:
[
{
"path"
:
"/xuhuiChild1/month/monthInfo"
,
"name"
:
"monthInfo"
,
"meta"
:
{
"title"
:
"检查详情"
,
"menuPath"
:
false
,
"hideInBread"
:
false
}
}
]
}
]
},
{
"path"
:
"/xuhuiChild2/repair"
,
"name"
:
"repairList"
,
"meta"
:
{
"title"
:
"应急报修"
,
"menuIcon"
:
"profile"
,
"menuPath"
:
false
,
"hideInBread"
:
false
},
"children"
:[
{
"path"
:
"/xuhuiChild2/repair/repairList"
,
"name"
:
"repairList"
,
"meta"
:
{
"title"
:
"应急报修列表"
,
"menuIcon"
:
"profile"
,
"menuPath"
:
false
,
"hideInBread"
:
false
},
"children"
:
[
{
"path"
:
"/xuhuiChild2/repair/repairInfo"
,
"name"
:
"repairInfo"
,
"meta"
:
{
"title"
:
"报修详情"
,
"menuPath"
:
false
,
"hideInBread"
:
false
}
}
]
}
]
},
{
"path"
:
"/xuhuiChild2/tousu"
,
"name"
:
"tousu"
,
"meta"
:
{
"title"
:
"投诉信息"
,
"menuPath"
:
true
,
"menuIcon"
:
"profile"
,
"hideInBread"
:
true
},
"children"
:
[
{
"path"
:
"/xuhuiChild2/tousu/tousuQuestion"
,
"name"
:
"tousuQuestion"
,
"meta"
:
{
"title"
:
"投诉问题排行"
,
"menuPath"
:
true
,
"hideInBread"
:
false
},
"children"
:[
{
"path"
:
"/xuhuiChild2/tousu/tousuQuestion/questionInfo"
,
"name"
:
"questionInfo"
,
"meta"
:
{
"title"
:
"投诉问题列表"
,
"menuPath"
:
false
,
"hideInBread"
:
false
}
},
{
"path"
:
"/xuhuiChild2/tousu/tousuQuestion/tousuDetails"
,
"name"
:
"tousuDetails"
,
"meta"
:
{
"title"
:
"投诉问题详情"
,
"menuPath"
:
false
,
"hideInBread"
:
false
}
}
]
},
{
"path"
:
"/xuhuiChild2/tousu/tousuDensity"
,
"name"
:
"tousuDensity"
,
"meta"
:
{
"title"
:
"投诉密度排行"
,
"menuPath"
:
true
,
"hideInBread"
:
false
}
}
]
}
]
}
\ No newline at end of file
src/server/api.js
View file @
20d43b3b
...
...
@@ -7,8 +7,8 @@ let BASE_URL = '', MOCK_URL=''
switch
(
process
.
env
.
NODE_ENV
)
{
case
'devol'
:
// 本地线上部署环境下
// BASE_URL = 'http://search.omniview.pro/api'
//
BASE_URL = 'http://211.136.105.193/apiv2'
BASE_URL
=
'http://hm.omniview.pro/api'
BASE_URL
=
'http://211.136.105.193/apiv2'
//
BASE_URL = 'http://hm.omniview.pro/api'
break
case
'sit'
:
// sit环境下
...
...
src/views/personal/sysInfoSetting.vue
0 → 100644
View file @
20d43b3b
<
template
>
<div
class=
"routerWapper"
>
<div
class=
"layoutMargin layoutPadding"
v-if=
"$route.name == 'sysInfoSetting'"
>
<!--
<a-modal
title=
"资料上传"
:visible=
"logoConfigFormvisible"
@
ok=
"handleSubmitLogoConfig"
:confirmLoading=
"confirmLoading"
@
cancel=
"logoConfigFormvisible = false"
okText=
"确认"
cancelText=
"取消"
>
-->
<a-tabs
default-active-key=
"1"
>
<a-tab-pane
tab=
"系统信息"
key=
"1"
>
<a-form
:form=
"prjConfigForm"
>
<a-form-item
label=
"项目名"
:label-col=
"
{ span: 5 }" :wrapper-col="{ span: 12 }">
<a-input
v-decorator=
"['prjName',
{ rules: [{ required: true, message: '请输入项目名!' }] }]" />
</a-form-item>
<a-form-item
label=
"图片"
:label-col=
"
{ span: 5 }" :wrapper-col="{ span: 12 }">
<img
@
click=
"previewVisible = true"
:src=
"logoConfigDatas.previewImage"
alt=
""
width=
"105"
height=
"105"
>
<a-upload
listType=
"picture-card"
:fileList=
"fileList"
:customRequest=
"(data) =>
{handleUpload(data,fileList)}"
@preview="handlePreview"
:beforeUpload="beforeUpload"
:accept="fileUpload.acceptTypes">
<div
v-if=
"fileList.length
<
1
"
>
<a-icon
type=
"cloud-upload"
/>
<div
class=
"ant-upload-text"
style=
"fontSize:12px"
>
图片仅支持jpg、png、jpeg格式
</div>
</div>
</a-upload>
<a-button
@
click=
"delImg"
>
删除图片
</a-button>
</a-form-item>
<!--
<a-form-item
label=
"项目名"
:label-col=
"
{ span: 5 }" :wrapper-col="{ span: 12 }">
<a-button
@
click=
"delImg"
>
删除图片
</a-button>
</a-form-item>
-->
</a-form>
<a-row>
<a-col
:span=
'16'
></a-col>
<a-col
:span=
'8'
>
<a-button
type=
'default'
@
click=
"handleSubmitLogoConfig"
>
保存信息
</a-button>
</a-col>
</a-row>
<!--
<a-button
type=
'default'
@
click=
"handleSubmitLogoConfig"
>
保存信息
</a-button>
-->
<a-modal
:visible=
"previewVisible"
style=
"text-align:center"
:width=
"600"
:footer=
"null"
@
cancel=
"previewVisible = false"
>
<img
alt=
"项目logo"
style=
"width: 80%;height:auto"
:src=
"logoConfigDatas.previewImage"
/>
</a-modal>
</a-tab-pane>
</a-tabs>
<!--
</a-modal>
-->
</div>
</div>
</
template
>
<
script
>
export
default
{
data
(){
return
{
isShowChangePwd
:
false
,
collapsed
:
false
,
username
:
''
,
logoConfig
:
{
logoName
:
''
,
logoImg
:
''
},
logoConfigDatas
:
{
isDelImg
:
false
,
previewImage
:
''
,
file
:
''
},
// 模态框
logoConfigFormvisible
:
true
,
confirmLoading
:
false
,
// form
formLayout
:
'horizontal'
,
prjConfigForm
:
this
.
$form
.
createForm
(
this
),
//上传
previewVisible
:
false
,
fileList
:
[],
fileUpload
:
{
acceptTypes
:
'.jpg,.jpeg,.png'
,
acceptTypesArray
:
[
'jpg'
,
'jpeg'
,
'png'
]
},
postParams
:
{},
}
},
created
(){
this
.
getLogo
()
this
.
getInfo
()
},
methods
:
{
getInfo
()
{
this
.
$ajax
.
get
({
url
:
this
.
$api
.
GET_USER_INFO
,
}).
then
(
res
=>
{
// 本地存储用户基本信息
let
userInfo
=
res
.
data
.
content
,
name
if
(
!
res
.
data
||
!
res
.
data
.
content
){
userInfo
=
{}
name
=
''
}
else
{
userInfo
=
res
.
data
.
content
name
=
userInfo
.
username
=
res
.
data
.
content
.
name
||
res
.
data
.
content
.
phone
this
.
$store
.
commit
(
'SET_USERINFO'
,
userInfo
)
this
.
$cookie
.
set
(
'userName'
,
name
)
this
.
$store
.
commit
(
'SET_USERNAME'
,
name
)
}
})
},
getLogo
(){
this
.
$ajax
.
get
({
url
:
this
.
$api
.
GET_PROJECT
,
}).
then
(
res
=>
{
if
(
res
.
code
==
200
)
{
const
logConfig
=
this
.
$com
.
confirm
(
res
,
'data.content'
,
{})
this
.
logoConfig
.
logoName
=
!
logConfig
.
prjName
?
''
:
logConfig
.
prjName
this
.
logoConfig
.
logoImg
=
!
logConfig
.
titleImg
?
''
:
logConfig
.
titleImg
this
.
logoConfigDatas
.
previewImage
=
this
.
logoConfig
.
logoImg
document
.
title
=
this
.
logoConfig
.
logoName
this
.
showLogoConfigFormModal
()
}
})
},
beforeUpload
(
file
)
{
const
fileNameArr
=
file
.
name
.
split
(
'.'
)
const
fileSuffix
=
fileNameArr
[
fileNameArr
.
length
-
1
].
toLowerCase
()
const
isAccept
=
this
.
$com
.
oneOf
(
fileSuffix
,
this
.
fileUpload
.
acceptTypesArray
)
const
isLt5M
=
file
.
size
/
1024
/
1024
<
5
let
message
=
''
if
(
!
isAccept
){
message
+=
!
isAccept
?(
'文件格式限定为'
+
this
.
fileUpload
.
acceptTypes
+
';'
):
''
}
if
(
!
isLt5M
){
message
+=
!
islt200m
?
'一寸照需小于5M;'
:
''
}
if
(
isAccept
&&
isLt5M
){
return
true
}
else
{
this
.
$modal
.
error
({
title
:
'上传文件验证未通过'
,
content
:
message
,
okText
:
'确认'
,
cancelText
:
'取消'
,
})
return
false
}
},
handleUpload
(
data
)
{
const
formData
=
new
FormData
()
formData
.
append
(
'file'
,
data
.
file
)
data
.
onProgress
()
this
.
$ajax
.
post
({
url
:
this
.
$api
.
UPLOAD_TEMP
,
params
:
formData
}).
then
(
res
=>
{
if
(
res
.
code
===
'200'
)
{
const
data
=
this
.
$com
.
confirm
(
res
,
'data.content'
,
{})
this
.
logoConfigDatas
.
file
=
!
data
.
titleImg
?
''
:
data
.
titleImg
this
.
logoConfigDatas
.
previewImage
=
!
data
.
titleImg
?
''
:
data
.
titleImg
this
.
fileList
=
[]
}
})
},
handlePreview
()
{
this
.
previewVisible
=
true
},
delImg
(){
this
.
fileList
=
[]
this
.
logoConfig
.
logoImg
=
''
this
.
logoConfigDatas
.
previewImage
=
''
this
.
logoConfigDatas
.
isDelImg
=
true
},
showLogoConfigFormModal
()
{
console
.
log
(
this
.
logoConfig
)
this
.
logoConfigDatas
.
isDelImg
=
false
this
.
logoConfigFormvisible
=
true
this
.
$nextTick
(
function
()
{
this
.
prjConfigForm
.
setFieldsValue
({
prjName
:
this
.
logoConfig
.
logoName
})
})
},
handleSubmitLogoConfig
()
{
this
.
prjConfigForm
.
validateFields
((
err
)
=>
{
if
(
!
err
)
{
const
postParams
=
{
'file'
:
this
.
logoConfigDatas
.
file
,
'prjName'
:
this
.
prjConfigForm
.
getFieldValue
(
'prjName'
),
'isDelImg'
:
this
.
logoConfigDatas
.
isDelImg
,
}
this
.
$ajax
.
post
({
url
:
this
.
$api
.
POST_PROJECT
,
params
:
postParams
,
contentType
:
'application/x-www-form-urlencoded'
}).
then
(
res
=>
{
if
(
res
.
code
==
'200'
)
{
this
.
logoConfigFormvisible
=
false
const
logConfig
=
this
.
$com
.
confirm
(
res
,
'data.content'
,
{})
this
.
logoConfig
.
logoName
=
!
logConfig
.
prjName
?
''
:
logConfig
.
prjName
this
.
logoConfig
.
logoImg
=
!
logConfig
.
titleImg
?
''
:
logConfig
.
titleImg
this
.
logoConfigDatas
.
previewImage
=
this
.
logoConfig
.
logoImg
document
.
title
=
this
.
logoConfig
.
logoName
}
else
{
this
.
$message
.
error
(
res
.
msg
)
}
})
}
})
},
},
}
</
script
>
\ 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