Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
P
project
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
高宇
project
Commits
9cc5af01
Commit
9cc5af01
authored
May 12, 2019
by
高宇
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完成通讯录
parent
d9ae8300
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
387 additions
and
66 deletions
+387
-66
api.js
src/api.js
+2
-1
addressListForm.vue
src/components/addressBook/addressListForm.vue
+235
-0
list.vue
src/components/addressBook/list.vue
+117
-5
scheduleItem.vue
src/components/addressBook/scheduleItem.vue
+32
-59
keywordHeader.vue
src/components/common/keywordHeader.vue
+1
-1
No files found.
src/api.js
View file @
9cc5af01
...
@@ -2,6 +2,7 @@ import ElementApi from './apis/project'
...
@@ -2,6 +2,7 @@ import ElementApi from './apis/project'
import
sales
from
'./apis/sales'
import
sales
from
'./apis/sales'
import
contract
from
'./apis/contract'
import
contract
from
'./apis/contract'
import
product
from
'./apis/product'
import
product
from
'./apis/product'
import
addressBook
from
'./apis/addressBook'
const
usingJSONP
=
process
.
env
.
NODE_ENV
!==
'production'
const
usingJSONP
=
process
.
env
.
NODE_ENV
!==
'production'
const
API_HOST
=
process
.
env
.
API_HOST
const
API_HOST
=
process
.
env
.
API_HOST
const
API_PORT
=
process
.
env
.
API_PORT
const
API_PORT
=
process
.
env
.
API_PORT
...
@@ -26,7 +27,7 @@ const option = {
...
@@ -26,7 +27,7 @@ const option = {
}
}
let
apis
=
{}
let
apis
=
{}
apis
=
Object
.
assign
(
apis
,
ElementApi
,
sales
,
contract
,
product
)
apis
=
Object
.
assign
(
apis
,
ElementApi
,
sales
,
contract
,
product
,
addressBook
)
export
default
{
export
default
{
option
,
option
,
...
apis
...
apis
...
...
src/components/addressBook/addressListForm.vue
0 → 100644
View file @
9cc5af01
<
template
>
<div>
<el-row
class=
"form-content"
>
<el-form
size=
"mini"
:model=
"clientForm"
label-width=
"0"
label-position=
"top"
>
<el-col
:span=
"4"
v-for=
"(item, key) in filter"
:key=
"key"
>
<el-form-item>
<span
slot=
"label"
v-if=
"item.key !== 'Filter[sort]'"
>
<a
@
click
.
prevent=
"timeSort"
v-if=
"item.key === 'Filter[name]'"
>
{{
item
.
name
}}
<i
:class=
"['fa', setSortIcon()]"
></i>
</a>
<span
v-else
>
{{
item
.
name
}}
</span>
</span>
<el-select
clearable
v-model=
"clientForm[item.key]"
placeholder=
"请选择"
v-if=
"!item.itemKey && item.key !== 'Filter[sort]'"
size=
"mini"
>
<el-option
v-for=
"(option, optKey) in item.value"
:key=
"optKey"
:label=
"option.name"
:value=
"option.key"
>
<span
style=
"font-size: 12px;"
>
{{
option
.
name
}}
</span>
</el-option>
</el-select>
<el-cascader
:ref=
"'elCasc' + key"
v-model=
"item.cascader"
:props=
"props"
clearable
change-on-select
v-if=
"item.itemKey"
:options=
"item.value"
@
change=
"setCascader(item, key)"
></el-cascader>
</el-form-item>
</el-col>
</el-form>
</el-row>
</div>
</
template
>
<
script
>
import
{
findWhere
}
from
'../../lib/viewHelper'
import
$
from
'jquery'
const
timeItem
=
[
'period'
]
export
default
{
name
:
'client-form'
,
data
()
{
return
{
clientTimeForm
:
{},
clientTimeRange
:
{
from
:
''
,
to
:
''
},
clientForm
:
{},
props
:
{
label
:
'name'
,
value
:
'key'
,
children
:
'child'
}
}
},
props
:
[
'filter'
,
'formSearchKey'
],
methods
:
{
setCascader
(
item
,
key
)
{
if
(
item
.
cascader
.
length
===
1
)
{
this
.
clientForm
[
item
.
key
]
=
item
.
cascader
[
0
]
this
.
clientForm
[
item
.
itemKey
]
=
''
}
else
if
(
item
.
cascader
.
length
===
2
)
{
this
.
clientForm
[
item
.
itemKey
]
=
item
.
cascader
[
0
]
this
.
clientForm
[
item
.
key
]
=
item
.
cascader
[
1
]
}
else
{
this
.
clientForm
[
item
.
itemKey
]
=
''
this
.
clientForm
[
item
.
key
]
=
''
}
},
setDefault
(
filter
)
{
filter
.
forEach
(
item
=>
{
if
(
item
.
default
)
{
let
keys
=
findWhere
(
item
.
value
,
item
.
default
,
'key'
)
if
(
keys
.
node
)
{
if
(
keys
.
parentNode
)
{
this
.
clientForm
[
item
.
itemKey
]
=
keys
.
parentNode
.
key
this
.
clientForm
[
item
.
key
]
=
keys
.
node
.
key
item
.
cascader
=
[
keys
.
parentNode
.
key
,
keys
.
node
.
key
]
}
else
{
this
.
clientForm
[
item
.
itemKey
]
=
''
this
.
clientForm
[
item
.
key
]
=
keys
.
node
.
key
item
.
cascader
=
[
keys
.
node
.
key
]
}
}
}
})
},
init
(
isCascader
)
{
this
.
$watch
(
'clientForm'
,
(
val
)
=>
{
this
.
$emit
(
'update:clientList'
,
Object
.
assign
({},
val
,
this
.
clientTimeForm
))
},
{
deep
:
true
})
this
.
$watch
(
'clientTimeForm'
,
(
val
)
=>
{
let
perid
=
val
[
this
.
formSearchKey
+
'[period]'
]
this
.
$emit
(
'update:clientList'
,
Object
.
assign
({},
{[
this
.
formSearchKey
+
'[period]'
]:
perid
},
this
.
clientForm
))
},
{
deep
:
true
})
let
_this
=
this
if
(
isCascader
)
{
$
(
document
).
ready
(()
=>
{
$
(
document
).
on
(
'mouseleave'
,
'.el-cascader-menus'
,
()
=>
{
Object
.
keys
(
_this
.
$refs
).
forEach
(
item
=>
{
_this
.
$refs
[
item
][
0
].
menuVisible
=
false
})
})
})
}
},
setSortIcon
()
{
if
(
this
.
clientForm
[
'Filter[sort]'
]
===
''
)
{
return
'fa-sort-amount-desc'
}
else
if
(
this
.
clientForm
[
'Filter[sort]'
]
===
'DESC'
)
{
return
'fa-sort-amount-desc'
}
else
{
return
'fa-sort-amount-asc'
}
},
timeSort
()
{
if
(
this
.
clientForm
[
'Filter[sort]'
]
===
''
)
{
this
.
clientForm
[
'Filter[sort]'
]
=
'ASC'
}
else
if
(
this
.
clientForm
[
'Filter[sort]'
]
===
'ASC'
)
{
this
.
clientForm
[
'Filter[sort]'
]
=
'DESC'
}
else
{
this
.
clientForm
[
'Filter[sort]'
]
=
'ASC'
}
},
setSearchTime
()
{
let
from
=
this
.
clientTimeRange
.
from
let
to
=
this
.
clientTimeRange
.
to
this
.
$emit
(
'update:clientList'
,
Object
.
assign
({},
{
[
this
.
formSearchKey
+
'[from]'
]:
from
,
[
this
.
formSearchKey
+
'[to]'
]:
to
},
this
.
clientTimeForm
,
this
.
clientForm
))
},
resetForm
()
{
Object
.
keys
(
this
.
clientForm
).
forEach
(
item
=>
{
this
.
clientForm
[
item
]
=
''
})
Object
.
keys
(
this
.
clientTimeRange
).
forEach
(
item
=>
{
this
.
clientTimeRange
[
item
]
=
''
})
Object
.
keys
(
this
.
clientTimeForm
).
forEach
(
item
=>
{
this
.
clientTimeForm
[
item
]
=
''
})
}
},
mounted
()
{
},
watch
:
{
'clientTimeRange.from'
(
val
)
{
if
(
new
Date
(
val
)
>=
new
Date
(
this
.
clientTimeRange
.
to
))
{
this
.
clientTimeRange
.
to
=
val
}
},
'clientTimeRange.to'
(
val
)
{
if
(
new
Date
(
val
)
<=
new
Date
(
this
.
clientTimeRange
.
from
))
{
this
.
clientTimeRange
.
from
=
val
}
},
'filter'
(
val
)
{
let
isCascader
=
false
val
.
forEach
(
item
=>
{
if
(
item
.
itemKey
)
{
this
.
$set
(
this
.
clientForm
,
item
.
itemKey
,
''
)
this
.
$set
(
item
,
'cascader'
,
[])
isCascader
=
true
}
this
.
$set
(
this
.
clientForm
,
item
.
key
,
''
)
})
this
.
$nextTick
(()
=>
{
this
.
init
(
isCascader
)
this
.
setDefault
(
val
)
})
},
'formSearchKey'
:
{
handler
(
val
)
{
if
(
val
!==
''
)
{
timeItem
.
forEach
(
item
=>
{
this
.
$set
(
this
.
clientTimeForm
,
val
+
'['
+
item
+
']'
,
''
)
})
}
},
immediate
:
true
}
}
}
</
script
>
<
style
scoped
>
.form-content-time-top
{
background
:
#FFF
;
}
.form-content-time-top
.el-form-item
{
margin
:
7px
0
9px
;
}
.form-content-time-top
.el-col
{
padding
:
0
15px
;
}
</
style
>
<
style
>
.form-content
.el-form-item__label
{
font-size
:
.875rem
;
font-weight
:
normal
;
padding
:
0
2px
0
0
;
}
.form-content-time-top
.el-radio-button__orig-radio
:checked
+
.el-radio-button__inner
{
color
:
#fff
!important
;
background-color
:
#333744
!important
;
border-color
:
#282b35
!important
;
box-shadow
:
-1px
0
0
0
#282b35
;
}
.form-content-time-top
.el-radio-button
:first-child
.el-radio-button__inner
{
border-left
:
1px
solid
#DCDFE6
;
}
.form-content-time-top
.el-radio-button__inner
:hover
{
border-color
:
#DCDFE6
!important
;
}
.form-content-time-top
.form-content-time-range
.el-form-item
.el-form-item__content
{
display
:
flex
;
font-size
:
12px
;
}
</
style
>
src/components/addressBook/list.vue
View file @
9cc5af01
<
template
>
<
template
>
<div>
<section>
<div
class=
"content"
>
</div>
<client-header
ref=
"clientHeader"
title=
"通讯录"
:title-span=
"6"
:model=
"form"
search-key=
"ProjectSearch"
key-code=
"keyword"
type=
"keyword"
:reset-form=
"resetForm"
:search-keyword=
"searchKeyword"
></client-header>
<client-form
ref=
"clientForm"
:filter=
"filter"
@
update:clientList=
"form =>
{ updateForm(form)}"
:form-search-key="formSearchKey">
</client-form>
<div
class=
"page-body-content"
>
<div
v-loading=
"loading"
>
<ScheduleItem
v-for=
"(item, key) in result.list"
:item=
"item"
:key=
"key"
@
update:image=
"imgs =>
{setImage(imgs)}">
</ScheduleItem>
<div
v-if=
"result.list.length === 0"
>
<el-card
class=
"box-card"
>
未查询到数据!
</el-card>
</div>
</div>
<Pagenation
@
update:pager=
"pager =>
{updatePage(pager)}"
:pager.sync="pagenation"
:total="totalcount">
</Pagenation>
</div>
</div>
</section>
</
template
>
</
template
>
<
script
>
<
script
>
import
ScheduleItem
from
'./scheduleItem'
import
clientHeader
from
'../common/clientHeader'
import
clientForm
from
'./addressListForm'
import
Pagenation
from
'../common/schedulePagenation'
import
{
requestAPI
,
api
}
from
'@/lib/commonMixin'
export
default
{
export
default
{
name
:
''
,
name
:
''
,
components
:
{
clientHeader
,
clientForm
,
ScheduleItem
,
Pagenation
},
data
()
{
data
()
{
return
{}
return
{
result
:
{
list
:
[]
},
form
:
{
'AccountSearch[keyword]'
:
''
},
pagenation
:
{
page
:
1
},
totalcount
:
0
,
filter
:
[],
loading
:
false
,
formSearchKey
:
'AccountSearch'
}
},
methods
:
{
searchKeyword
(
search
)
{
this
.
updateForm
(
search
)
},
updateForm
(
form
)
{
Object
.
assign
(
this
.
form
,
form
)
this
.
getList
()
},
resetForm
()
{
this
.
$refs
.
clientForm
.
resetForm
()
Object
.
keys
(
this
.
form
).
forEach
(
item
=>
{
this
.
form
[
item
]
=
''
})
this
.
getList
()
},
updatePage
(
pager
)
{
Object
.
assign
(
this
.
pagenation
,
pager
)
this
.
getList
(
true
)
},
getList
(
toTop
)
{
if
(
this
.
loading
)
{
return
}
this
.
loading
=
true
requestAPI
(
api
.
getAddressBookList
,
{
data
:
{
...
this
.
form
,
page
:
this
.
pagenation
.
page
}
}).
then
(
res
=>
{
this
.
result
.
list
=
res
.
list
// this.pagenation.page = res.pagenation.thispage
this
.
totalcount
=
res
.
pagenation
.
totalcount
// this.totalcount = 8
if
(
toTop
)
{
this
.
$el
.
querySelector
(
'.page-body-content'
).
scrollTo
(
0
,
0
)
}
}).
finally
(
_
=>
{
this
.
loading
=
false
})
},
getFilter
()
{
requestAPI
(
api
.
getAddressBookFilter
).
then
(
res
=>
{
this
.
filter
=
res
})
}
},
},
methods
:
{},
created
()
{
created
()
{
this
.
getFilter
()
this
.
$nextTick
(()
=>
{
this
.
getList
()
})
}
}
}
}
</
script
>
</
script
>
...
...
src/components/addressBook/scheduleItem.vue
View file @
9cc5af01
...
@@ -4,90 +4,59 @@
...
@@ -4,90 +4,59 @@
<el-col
:span=
"4"
:xs=
"24"
class=
"client-schedule-left"
:style=
"
{'background-color': item.bgcolor}">
<el-col
:span=
"4"
:xs=
"24"
class=
"client-schedule-left"
:style=
"
{'background-color': item.bgcolor}">
<el-row
:gutter=
"10"
>
<el-row
:gutter=
"10"
>
<el-col
:span=
"24"
class=
"entity-name"
>
<el-col
:span=
"24"
class=
"entity-name"
>
<i
class=
"fa fa-fw fa-star"
aria-hidden=
"true"
></i>
<img
class=
"user-avatar rounded-circle"
:src=
"item.avatar.avatar"
v-if=
"item.avatar"
>
<a
@
click=
"toView(item)"
v-if=
"Object.keys(item.client).length > 0"
>
{{
item
.
client
.
name
}}
<span>
{{
item
.
name
}}
</span>
</a>
<span
v-else
>
客户名称
{{
noneText
}}
</span>
</el-col>
</el-col>
<el-col
:span=
"12"
class=
"entity-name"
v-if=
"Object.keys(item.createdBy).length > 0"
>
<el-col
:span=
"24"
>
<img
class=
"user-avatar rounded-circle"
:src=
"item.createdBy.avatar.name"
>
<i
class=
"fa fa-fw fa-sitemap"
></i>
<span
class=
"black"
>
{{
item
.
createdBy
.
name
}}
</span>
<span
v-if=
"item.department.name"
>
{{
item
.
department
.
name
}}
</span>
<span
v-else
>
{{
noneText
}}
</span>
</el-col>
</el-col>
<el-col
:span=
"12"
v-else
><i
class=
"fa fa-fw fa-user"
></i>
{{
noneText
}}
<el-col
:span=
"24"
>
<i
class=
"fa fa-fw fa-suitcase"
></i>
<span
v-if=
"item.departmentPosition.name"
>
{{
item
.
departmentPosition
.
name
}}
</span>
<span
v-else
>
{{
noneText
}}
</span>
</el-col>
</el-col>
</el-row>
</el-row>
</el-col>
</el-col>
<el-col
:span=
"20"
:xs=
"24"
class=
"client-schedule-right"
>
<el-col
:span=
"20"
:xs=
"24"
class=
"client-schedule-right"
>
<el-row
:gutter=
"10"
>
<el-row
:gutter=
"10"
>
<el-col
:span=
"6"
:xs=
"24"
class=
"show-picture"
>
合同编号:
<span>
{{
item
.
serial_no
!==
''
?
item
.
serial_no
:
noneText
}}
</span>
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
<span
class=
"border border-info text-info rounded px-1"
>
总额
</span>
:
¥
{{
item
.
amount
!==
''
?
item
.
amount
:
noneText
}}
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
<el-col
:span=
"6"
:xs=
"24"
>
客户经理:
{{
item
.
salesRep
}}
电子邮箱:
</el-col>
<a
:href=
"'mailto:' + item.email"
>
<el-col
:span=
"6"
:xs=
"24"
>
{{
item
.
email
!==
''
?
item
.
email
:
noneText
}}
签订日期:
<span
class=
"date-time"
>
{{
item
.
signed_at
!==
''
?
item
.
signed_at
:
noneText
}}
</span>
</el-col>
</el-row>
<el-row
:gutter=
"10"
>
<el-col
:span=
"6"
:xs=
"24"
>
项目名称:
<a
href=
"javascript:;"
size=
"mini"
@
click
.
prevent
.
stop=
"showProject(item.project)"
v-if=
"Object.keys(item.project).length > 0"
>
{{
Object
.
keys
(
item
.
project
).
length
>
0
?
item
.
project
.
name
:
noneText
}}
</a>
</a>
<span
v-else
>
{{
noneText
}}
</span>
</el-col>
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
<el-col
:span=
"6"
:xs=
"24"
>
合同类型:
性别:
<span
class=
"border border-info text-info rounded px-1"
{{
item
.
sex
!==
''
?
sexs
[
item
.
sex
]
:
noneText
}}
v-if=
"item.contract_type !== ''"
>
{{
[
'产品销售'
,
'运维服务'
][
parseInt
(
item
.
contract_type
)
-
1
]
}}
</span>
<span
v-else
>
{{
noneText
}}
</span>
</el-col>
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
<el-col
:span=
"6"
:xs=
"24"
>
上传合同:
生日:
{{
item
.
birth_date
!==
''
?
item
.
birth_date
:
noneText
}}
<a
:href=
"getScanUrl(item, 'contractScan')"
target=
"_blank"
v-if=
"Object.keys(item.contractScan).length > 0"
>
<i
class=
"fa fa-fw fa-file-pdf-o"
></i>
</a>
<span
v-else
class=
"text-danger"
>
扫描件待上传
</span>
</el-col>
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
<el-col
:span=
"6"
:xs=
"24"
>
上传签收单:
籍贯:
{{
item
.
native_place
!==
''
?
item
.
native_place
:
noneText
}}
<a
:href=
"getScanUrl(item, 'receiptScan')"
target=
"_blank"
v-if=
"Object.keys(item.receiptScan).length > 0"
>
<i
class=
"fa fa-fw fa-file-image-o"
></i>
</a>
<span
v-else
class=
"text-danger"
>
扫描件待上传
</span>
</el-col>
</el-col>
</el-row>
</el-row>
<el-row
:gutter=
"10"
>
<el-row
:gutter=
"10"
>
<el-col
:span=
"6"
:xs=
"24"
>
<el-col
:span=
"6"
:xs=
"24"
>
<span
class=
"border border-danger text-danger rounded px-1"
>
服务截止日期
</span>
:
手机:
{{
item
.
mobile
!==
''
?
item
.
mobile
:
noneText
}}
{{
item
.
expire_date
!==
''
?
item
.
expire_date
:
noneText
}}
</el-col>
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
<el-col
:span=
"6"
:xs=
"24"
>
<span
class=
"border border-danger text-danger rounded px-1"
>
下次巡检日期
</span>
:
毕业院校
:
{{
item
.
remind_date
!==
''
?
item
.
remind_date
:
noneText
}}
{{
item
.
graduate_school
!==
''
?
item
.
graduate_school
:
noneText
}}
</el-col>
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
<el-col
:span=
"6"
:xs=
"24"
>
<span
class=
"border border-danger text-danger rounded px-1"
>
SLA
</span>
:
专业:
{{
item
.
specialty
!==
''
?
item
.
specialty
:
noneText
}}
{{
item
.
sla
!==
''
?
item
.
sla
:
noneText
}}
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
学历:
{{
item
.
education
!==
''
?
item
.
education
:
noneText
}}
</el-col>
</el-col>
</el-row>
</el-row>
<el-row
:gutter=
"10"
>
<el-row
:gutter=
"10"
>
<el-col
:span=
"12"
:xs=
"24"
>
<el-col
:span=
"6"
>
<span
class=
"border border-danger text-danger rounded px-1"
>
备注
</span>
:
座机:
{{
item
.
telephone
!==
''
?
item
.
telephone
:
noneText
}}
{{
item
.
description
!==
''
?
item
.
description
:
noneText
}}
</el-col>
</el-col>
<el-col
:span=
"12"
:xs=
"24"
>
<slot
name=
"opearate"
>
</slot>
</el-col>
</el-row>
</el-row>
</el-col>
</el-col>
</el-row>
</el-row>
...
@@ -103,7 +72,11 @@
...
@@ -103,7 +72,11 @@
data
()
{
data
()
{
return
{
return
{
noneText
:
'(未设置)'
noneText
:
'(未设置)'
,
sexs
:
{
'F'
:
'女'
,
'M'
:
'男'
}
}
}
},
},
methods
:
{
methods
:
{
...
...
src/components/common/keywordHeader.vue
View file @
9cc5af01
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
<el-button
slot=
"append"
type=
"primary"
@
click=
"searchKeyword()"
>
搜索
</el-button>
<el-button
slot=
"append"
type=
"primary"
@
click=
"searchKeyword()"
>
搜索
</el-button>
</el-input>
</el-input>
</el-form-item>
</el-form-item>
<el-form-item
v-if=
"
searchKey
"
>
<el-form-item
v-if=
"
addNewUser
"
>
<el-button
type=
"primary"
size=
"mini"
@
click
.
prevent
.
stop=
"addNewUser"
:disabled=
"createDisabled"
>
<el-button
type=
"primary"
size=
"mini"
@
click
.
prevent
.
stop=
"addNewUser"
:disabled=
"createDisabled"
>
<i
class=
"fa fa-plus faa-pulse animated"
></i>
{{
buttonTitle
}}
<i
class=
"fa fa-plus faa-pulse animated"
></i>
{{
buttonTitle
}}
</el-button>
</el-button>
...
...
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