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
e04d1ca5
Commit
e04d1ca5
authored
Apr 05, 2019
by
高宇
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完成商机信息;
parent
3e3b0988
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1098 additions
and
112 deletions
+1098
-112
index.ejs
index.ejs
+1
-1
project.js
src/apis/project.js
+10
-19
multipleEngineer.vue
src/components/common/multipleEngineer.vue
+68
-0
multipleInput.vue
src/components/common/multipleInput.vue
+5
-3
scheduleItem.vue
src/components/common/scheduleItem.vue
+59
-28
singleCalcInput.vue
src/components/common/singleCalcInput.vue
+52
-0
singleDatePicker.vue
src/components/common/singleDatePicker.vue
+1
-0
singleInput.vue
src/components/common/singleInput.vue
+1
-0
list.vue
src/components/project/list.vue
+42
-4
addProject.vue
src/components/project/operation/addProject.vue
+41
-0
editProject.vue
src/components/project/operation/editProject.vue
+41
-0
operationProject.vue
src/components/project/operation/operationProject.vue
+460
-0
projectListForm.vue
src/components/project/projectListForm.vue
+0
-1
projectOfClient.vue
src/components/project/projectOfClient/projectOfClient.vue
+184
-0
schedulePagenation.vue
src/components/project/schedulePagenation.vue
+48
-43
singleItemMixin.js
src/lib/singleItemMixin.js
+44
-3
project.js
src/routes/project.js
+31
-0
vupVueSdk.js
static/vupVueSdk.js
+10
-10
No files found.
index.ejs
View file @
e04d1ca5
...
...
@@ -37,7 +37,7 @@
],
homePage
:
{
appName
:
portalName
,
url
:
'/
lis
t'
url
:
'/
projec
t'
}
}
...
...
src/apis/project.js
View file @
e04d1ca5
...
...
@@ -8,25 +8,16 @@ export default {
getProjectList
:
{
url
:
'/vue/project/list'
},
// 删除
日志
del
WorkLog
:
{
url
:
'/vue/
work-log
/delete'
// 删除
商机
del
Project
:
{
url
:
'/vue/
project
/delete'
},
// 获取工作日志新建 option
get
WorkLog
NewOptions
:
{
url
:
'/vue/
work-log
/get-new'
get
Project
NewOptions
:
{
url
:
'/vue/
project
/get-new'
},
// 获取工作日志编辑
getWorkLogEdit
:
{
url
:
'/vue/work-log/get-edit'
},
// 工作日志编辑
saveWorkLogEdit
:
{
url
:
'/vue/work-log/save-edit'
},
// 工作日志新建
saveWorkLogAdd
:
{
url
:
'/vue/work-log/save-new'
getProjectEdit
:
{
url
:
'/vue/project/get-edit'
},
// 留言
...
...
@@ -48,9 +39,9 @@ export default {
getClient
:
{
url
:
'/vue/client/get-edit'
},
// 获取客户
工作日志
列表
get
WorkLog
Client
:
{
url
:
'/vue/
work-log
/of-client'
// 获取客户
商机
列表
get
Project
Client
:
{
url
:
'/vue/
project
/of-client'
},
// 搜索客户名称列表
...
...
src/components/common/multipleEngineer.vue
0 → 100644
View file @
e04d1ca5
<
template
>
<section
class=
"multiple-input"
>
<el-row
:gutter=
"10"
>
<el-col
:span=
"4"
:class=
"['client-label', 'text-right',
{'required': required}]">
<span>
{{
label
}}
</span>
</el-col>
<el-col
:span=
"14"
>
<div
class=
"engineer-box pull-left"
v-for=
"(item, key) in engineer"
:key=
"key"
>
<div
class=
"engineer-name pull-left"
>
<el-checkbox
v-model=
"item.disabled"
>
{{
item
.
name
}}
</el-checkbox>
</div>
<div
class=
"engineer-percent pull-right"
>
<el-select
v-model=
"item[item.key]"
size=
"mini"
:disabled=
"!item.disabled"
>
<el-option
v-for=
"item in contribution"
:key=
"item"
:label=
"item * 10 + '%'"
:value=
"item / 10"
>
</el-option>
</el-select>
</div>
</div>
</el-col>
<el-col
:span=
"6"
>
<slot
name=
"formError"
></slot>
</el-col>
</el-row>
</section>
</
template
>
<
script
>
// 多级选择支持用户占比
import
itemMixin
from
'../../lib/singleItemMixin'
let
contribution
=
()
=>
{
let
a
=
[]
for
(
let
i
=
10
;
i
>=
0
;
i
--
)
{
a
.
push
(
i
)
}
return
a
}
export
default
{
name
:
''
,
mixins
:
[
itemMixin
],
data
()
{
return
{
contribution
:
contribution
()
}
},
methods
:
{},
created
()
{
}
}
</
script
>
<
style
scoped
>
.engineer-box
{
width
:
130px
;
margin
:
0
10px
5px
0
;
}
.engineer-box
.engineer-name
{
width
:
60px
;
}
.engineer-box
.engineer-percent
{
width
:
70px
;
}
</
style
>
src/components/common/multipleInput.vue
View file @
e04d1ca5
...
...
@@ -3,12 +3,14 @@
<el-row
:gutter=
"10"
>
<el-col
:span=
"4"
:class=
"['client-label', 'text-right',
{'required': required}]">
<span>
{{
label
}}
</span>
{{
item
}}
</el-col>
<el-col
:span=
"14"
>
<span
v-for=
"(i, key) in item"
:key=
"key"
>
<span
v-for=
"(i, key) in item
s
"
:key=
"key"
>
<el-input
v-model=
"i[multipleKey]"
:placeholder=
"label"
size=
"mini"
>
<el-button
slot=
"append"
v-if=
"key === 0"
icon=
"el-icon-plus"
@
click=
"addItem(item)"
></el-button>
<el-button
slot=
"append"
v-else
icon=
"el-icon-minus"
@
click=
"delItem(item, key)"
></el-button>
<template
slot=
"prepend"
>
{{
setPerText
(
key
)
}}
</
template
>
<el-button
slot=
"append"
v-if=
"key === 0"
icon=
"el-icon-plus"
@
click=
"addItem(items)"
></el-button>
<el-button
slot=
"append"
v-else
icon=
"el-icon-minus"
@
click=
"delItem(items, key)"
></el-button>
</el-input>
</span>
</el-col>
...
...
src/components/common/scheduleItem.vue
View file @
e04d1ca5
...
...
@@ -5,19 +5,19 @@
<el-row
:gutter=
"10"
>
<el-col
:span=
"24"
class=
"entity-name"
>
<i
class=
"fa fa-star"
aria-hidden=
"true"
></i>
<router-link
:to=
"toView(item)"
v-if=
"Object.keys(item.client).length > 0"
>
{{
item
.
client
.
name
}}
<router-link
:to=
"toView(item)"
v-if=
"Object.keys(item.client).length > 0"
>
{{
item
.
client
.
name
}}
</router-link>
<span
v-else
>
客户名称
{{
noneText
}}
</span>
</el-col>
<el-col
:span=
"24"
class=
"entity-name"
>
<i
class=
"fa fa-th-list"
aria-hidden=
"true"
></i>
<span>
{{
item
.
project_title
}}
</span>
<span>
{{
item
.
project_title
}}
</span>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
class=
"entity-name"
>
<img
class=
"user-avatar rounded-circle"
:src=
"item.createdBy.avatar.name"
>
<span
>
{{
item
.
createdBy
.
name
}}
</span>
<span
class=
"np"
>
{{
item
.
createdBy
.
name
}}
</span>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
class=
"entity-name"
>
<span
class=
"border rounded px-1"
>
{{
Object
.
keys
(
item
.
projectStatus
).
length
===
0
?
noneText
:
item
.
projectStatus
.
name
}}
</span>
</el-col>
</el-row>
...
...
@@ -55,12 +55,39 @@
</span>
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
售前支持: {{item.projectArchitects.length === 0 ? noneText : item.projectArchitects.map(i => i.name).join(' ')
}}
售前支持: {{item.projectArchitects.length === 0 ? noneText : item.projectArchitects.map(i => i.name).join(' ')}}
</el-col>
<el-col
:span=
"6"
:xs=
"24"
class=
"show-picture"
>
成交日期:
<span
class=
"date-time"
>
{{item.bargain_date !== '' ? item.bargain_date : noneText}}
</span>
</el-col>
</el-row>
<el-row
:gutter=
"10"
>
<el-col
:span=
"6"
:xs=
"24"
>
采购方式:
<span
class=
"border border-success text-success rounded px-1"
v-if=
"Object.keys(item.purchaseType).length > 0"
>
{{item.purchaseType.name}}
</span>
<span
v-else
>
{{noneText}}
</span>
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
商机来源:
<span
class=
"border border-success text-success rounded px-1"
v-if=
"Object.keys(item.opportunityFrom).length > 0"
>
{{item.opportunityFrom.name}}
</span>
<span
v-else
>
{{noneText}}
</span>
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
<span
class=
"border border-danger text-danger rounded px-1"
>
阶段停留
</span>
:
{{item.remain_display !== '' ? item.remain_display + '天' : noneText}}
</el-col>
<el-col
:span=
"6"
:xs=
"24"
>
创建时间: {{item.created_at !== '' ? item.created_at : noneText}}
</el-col>
</el-row>
<el-row
:gutter=
"10"
v-if=
"item.project_status === 3"
>
<el-col
:span=
"6"
>
未回款金额:
<span
:class=
"[{'text-danger': parseInt(item.collected) === 0}]"
>
¥{{ parseInt(item.budget) - parseInt(item.collected) }}
</span>
</el-col>
<el-col
:span=
"6"
>
未开发票:
<span
:class=
"[{'text-danger': parseInt(item.issued_invoices === '' ? 0 : item.issued_invoices) === 0}]"
>
¥{{ parseInt(item.budget) - parseInt(item.issued_invoices === '' ? 0 : item.issued_invoices) }}
</span>
</el-col>
</el-row>
<el-row
:gutter=
"10"
>
<el-col
:span=
"24"
:xs=
"24"
>
<span
class=
"border border-danger text-danger rounded px-1"
>
商机内容
</span>
:
...
...
@@ -104,6 +131,7 @@
},
toView
(
item
)
{
let
obj
=
{
app
:
'project'
,
name
:
'ofClient'
,
params
:
{
id
:
item
.
client_id
...
...
@@ -169,6 +197,27 @@
@include
c
(
'schedule-item'
)
{
margin-bottom
:
10px
;
font-size
:
12px
;
.border
{
border
:
1px
solid
#dee2e6
;
}
.border-success
{
border-color
:
#28a745
!
important
;
}
.border-danger
{
border-color
:
#dc3545
;
}
.text-success
{
color
:
#28a745
!
important
;
}
.text-danger
{
color
:
#E45744
;
}
.rounded
{
border-radius
:
.25rem
!
important
;
}
.px-1
{
padding
:
0
.25rem
;
}
}
@include
c
(
'schedule-item:first-child'
)
{
...
...
@@ -198,7 +247,10 @@
}
span
{
display
:
inline-block
;
padding-left
:
5px
;
padding-left
:
3px
;
}
span
.np
{
padding-left
:
0
;
}
@include
e
(
'private'
)
{
display
:
inline-block
;
...
...
@@ -213,27 +265,6 @@
@include
c
(
'schedule-right'
)
{
height
:
100%
;
padding
:
10px
15px
6px
;
.border
{
border
:
1px
solid
#dee2e6
;
}
.border-success
{
border-color
:
#28a745
!
important
;
}
.border-danger
{
border-color
:
#dc3545
;
}
.text-success
{
color
:
#28a745
!
important
;
}
.text-danger
{
color
:
#E45744
;
}
.rounded
{
border-radius
:
.25rem
!
important
;
}
.px-1
{
padding
:
0
.25rem
;
}
>
.el-row
{
>
.el-col
{
margin-bottom
:
4px
;
...
...
src/components/common/singleCalcInput.vue
0 → 100644
View file @
e04d1ca5
<
template
>
<section
class=
"single-calc-input"
>
<el-row
:gutter=
"10"
>
<el-col
:span=
"4"
:class=
"['client-label', 'text-right',
{'required': required}]">
<span>
{{
label
}}
</span>
{{
item
}}
</el-col>
<el-col
:span=
"14"
>
<el-input
:value=
"calcValue"
placeholder=
""
:disabled=
"disabled"
size=
"mini"
></el-input>
</el-col>
<el-col
:span=
"6"
>
<slot
name=
"formError"
></slot>
<span>
{{
errorText
}}
</span>
</el-col>
</el-row>
</section>
</
template
>
<
script
>
import
itemMixin
from
'../../lib/singleItemMixin'
export
default
{
name
:
''
,
mixins
:
[
itemMixin
],
data
()
{
return
{
errorText
:
''
}
},
computed
:
{
calcValue
()
{
let
sum
=
0
this
.
minuendItem
.
map
(
i
=>
{
sum
+=
parseInt
(
i
.
name
===
''
?
0
:
i
.
name
)
})
let
calc
=
parseInt
(
this
.
calcItem
===
''
?
0
:
this
.
calcItem
)
-
sum
if
(
calc
>
0
)
{
return
calc
}
else
{
this
.
errorText
=
''
return
0
}
}
},
methods
:
{},
created
()
{
}
}
</
script
>
<
style
scoped
>
</
style
>
src/components/common/singleDatePicker.vue
View file @
e04d1ca5
...
...
@@ -6,6 +6,7 @@
</el-col>
<el-col
:span=
"14"
>
<el-date-picker
size=
"mini"
v-model=
"timeItem"
type=
"date"
placeholder=
"选择日期"
...
...
src/components/common/singleInput.vue
View file @
e04d1ca5
...
...
@@ -41,6 +41,7 @@
display
:
block
;
line-height
:
1.5
;
color
:
#6c757d
;
font-size
:
12px
;
}
</
style
>
<
style
>
...
...
src/components/project/list.vue
View file @
e04d1ca5
...
...
@@ -22,21 +22,32 @@
:item=
"item"
:key=
"key"
@
update:image=
"imgs =>
{setImage(imgs)}">
<span
slot=
"opearate"
>
<span
slot=
"opearate"
>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
:disabled=
"!item.can_delete"
@
click=
"del
Log
(item.id)"
>
@
click=
"del
Project
(item.id)"
>
<i
class=
"fa fa-trash-o faa-shake"
></i>
删除
</el-button>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
:disabled=
"!item.can_schedule"
>
<i
class=
"fa fa-th-list"
></i>
新建待办事项
</el-button>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
:disabled=
"!item.can_update"
@
click=
"edit
Log
(item)"
>
@
click=
"edit
Project
(item)"
>
<i
class=
"fa fa-edit"
></i>
编辑
</el-button>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
:disabled=
"!item.can_update"
>
<i
class=
"fa fa-tag"
></i>
批注
</el-button>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
...
...
@@ -105,9 +116,36 @@
}
},
methods
:
{
delProject
(
id
)
{
this
.
$confirm
(
'确认删除吗?'
,
'提示'
).
then
(()
=>
{
requestAPI
(
api
.
delProject
,
{
data
:
{
id
}
}).
then
(()
=>
{
this
.
$message
(
'删除成功!'
)
this
.
getList
()
},
error
=>
{
if
(
Array
.
isArray
(
error
.
msg
))
{
error
.
msg
.
forEach
(
item
=>
{
this
.
$notify
.
error
({
title
:
'错误'
,
message
:
item
.
error
})
})
}
})
}).
catch
(
_
=>
{
})
},
addNewProject
()
{
this
.
$router
.
push
({
name
:
'addProject'
})
},
editProject
(
row
)
{
this
.
$router
.
push
({
name
:
'editProject'
,
params
:
{
id
:
row
.
id
}})
},
searchKeyword
()
{
searchKeyword
(
search
)
{
this
.
updateForm
(
search
)
},
updateForm
(
form
)
{
Object
.
assign
(
this
.
form
,
form
)
...
...
src/components/project/operation/addProject.vue
0 → 100644
View file @
e04d1ca5
<
template
>
<section>
<operation-project
ref=
"operationProject"
type=
"add"
:error-data=
"errorData"
>
<span
slot=
"operationBtn"
>
<el-button
type=
"primary"
@
click=
"saveProject"
size=
"mini"
>
保存
</el-button>
<el-button
@
click=
"close"
size=
"mini"
>
关闭
</el-button>
</span>
</operation-project>
</section>
</
template
>
<
script
>
import
operationProject
from
'./operationProject'
export
default
{
name
:
''
,
components
:
{
operationProject
},
data
()
{
return
{
errorData
:
{}
}
},
methods
:
{
saveProject
()
{},
close
()
{}
},
created
()
{
},
mounted
()
{
this
.
$refs
.
operationProject
.
initAdd
()
}
}
</
script
>
<
style
scoped
>
</
style
>
src/components/project/operation/editProject.vue
0 → 100644
View file @
e04d1ca5
<
template
>
<section>
<operation-project
ref=
"operationProject"
type=
"edit"
:error-data=
"errorData"
>
<span
slot=
"operationBtn"
>
<el-button
type=
"primary"
@
click=
"saveProject"
size=
"mini"
>
保存
</el-button>
<el-button
@
click=
"close"
size=
"mini"
>
关闭
</el-button>
</span>
</operation-project>
</section>
</
template
>
<
script
>
import
operationProject
from
'./operationProject'
export
default
{
name
:
''
,
components
:
{
operationProject
},
data
()
{
return
{
errorData
:
{}
}
},
methods
:
{
saveProject
()
{},
close
()
{}
},
created
()
{
},
mounted
()
{
this
.
$refs
.
operationProject
.
initEdit
()
}
}
</
script
>
<
style
scoped
>
</
style
>
src/components/project/operation/operationProject.vue
0 → 100644
View file @
e04d1ca5
<
template
>
<div
class=
"project-add-edit-form auto-template-form"
>
<el-form
:model=
"Projects"
size=
"mini"
>
<el-form-item
:show-message=
"false"
:error=
"errorData['client_id'] ? errorData['client_id'] : ''"
>
<single-search-input
:required=
"true"
:form-serch-item=
"Projects.client_id"
:form-show-text=
"searchText"
label=
"客户名称"
@
update:searchItem=
"val =>
{Projects.client_id = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'client_id'
]
}}
</span>
</single-search-input>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['project_title'] ? errorData['project_title'] : ''"
>
<single-input
label=
"项目名称"
:required=
"true"
:form-item=
"Projects.project_title"
@
update:item=
"val =>
{Projects.project_title = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'project_title'
]
}}
</span>
</single-input>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['budget'] ? errorData['budget'] : ''"
>
<single-input
label=
"商机金额"
:required=
"true"
:form-item=
"Projects.budget"
@
update:item=
"val =>
{Projects.budget = val}"
tips="注意:商机状态一旦“成交”,商机金额将不可再修改!">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'budget'
]
}}
</span>
</single-input>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['invoices'] ? errorData['invoices'] : ''"
v-if=
"Projects.project_status === 3"
>
<multiple-input
label=
"已开发票金额"
:form-item=
"Projects.invoices"
:set-prepend=
"setPrepend"
set-prepend-text=
"笔发票"
multiple-key=
"name"
@
update:item=
"val =>
{Projects.invoices = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'invoices'
]
}}
</span>
</multiple-input>
</el-form-item>
<el-form-item
:show-messge=
"false"
v-if=
"Projects.project_status === 3"
>
<single-calc-input
label=
"未开发票金额"
:calc-item=
"Projects.budget"
:minuend-item=
"Projects.invoices"
error-text=
""
:disabled=
"true"
></single-calc-input>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['paymentCollections'] ? errorData['paymentCollections'] : ''"
v-if=
"Projects.project_status === 3"
>
<multiple-input
label=
"已回款金额"
:form-item=
"Projects.paymentCollections"
:set-prepend=
"setPrepend"
set-prepend-text=
"笔回款"
multiple-key=
"name"
@
update:item=
"val =>
{Projects.paymentCollections = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'paymentCollections'
]
}}
</span>
</multiple-input>
</el-form-item>
<el-form-item
:show-messge=
"false"
v-if=
"Projects.project_status === 3"
>
<single-calc-input
label=
"未回款金额"
:calc-item=
"Projects.budget"
:minuend-item=
"Projects.paymentCollections"
error-text=
""
:disabled=
"true"
></single-calc-input>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['profit_pct'] ? errorData['profit_pct'] : ''"
>
<single-input
label=
"利润率"
:required=
"true"
:form-item=
"Projects.profit_pct"
@
update:item=
"val =>
{Projects.profit_pct = val}"
tips="注意:商机状态一旦“成交”,商机金额将不可再修改!">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'profit_pct'
]
}}
</span>
</single-input>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['project_status'] ? errorData['project_status'] : ''"
>
<!--clientFrom-->
<single-radio
:form-item=
"Projects.project_status"
label=
"商机状态"
:required=
"true"
:options-list=
"getOptions('project_status')"
@
update:item=
"val =>
{Projects.project_status = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'project_status'
]
}}
</span>
</single-radio>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['project_progress'] ? errorData['project_progress'] : ''"
>
<!--clientFrom-->
<single-radio
:form-item=
"Projects.project_progress"
label=
"销售阶段"
:required=
"true"
:options-list=
"getOptions('project_progress')"
@
update:item=
"val =>
{Projects.project_progress = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'project_progress'
]
}}
</span>
</single-radio>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['salesForecast'] ? errorData['salesForecast'] : ''"
>
<!--clientFrom-->
<single-radio
:form-item=
"Projects.salesForecast"
label=
"销售预测"
:required=
"true"
:options-list=
"getOptions('salesForecast')"
@
update:item=
"val =>
{Projects.salesForecast = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'salesForecast'
]
}}
</span>
</single-radio>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['bargain_date'] ? errorData['bargain_date'] : ''"
>
<!--clientFrom-->
<single-date-picker
:form-time-item=
"Projects.bargain_date"
label=
"成交日期"
@
update:item=
"val =>
{Projects.bargain_date = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'bargain_date'
]
}}
</span>
</single-date-picker>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['engineer_id'] ? errorData['engineer_id'] : ''"
>
<multiple-engineer
label=
"售前支持"
:form-item=
"ProjectArchitects.engineer_id"
engineer-key=
"engineer_id"
:options-list=
"getOptions('engineer_id', 'ProjectArchitects')"
@
update:item=
"val =>
{ProjectArchitects.engineer_id = val}">
</multiple-engineer>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['contract_type'] ? errorData['contract_type'] : ''"
>
<!--clientFrom-->
<single-radio
:form-item=
"Projects.contract_type"
label=
"合同类型"
:required=
"true"
:options-list=
"getOptions('contract_type')"
@
update:item=
"val =>
{Projects.contract_type = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'contract_type'
]
}}
</span>
</single-radio>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['projectTags'] ? errorData['projectTags'] : ''"
>
<!--clientFrom-->
<single-checkbox
:form-item=
"Projects.projectTags"
label=
"商机类型"
:required=
"true"
:options-list=
"getOptions('projectTags')"
@
update:item=
"val =>
{Projects.projectTags = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'projectTags'
]
}}
</span>
</single-checkbox>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['purchaseType'] ? errorData['purchaseType'] : ''"
>
<!--clientFrom-->
<single-radio
:form-item=
"Projects.purchaseType"
label=
"采购方式"
:required=
"true"
:options-list=
"getOptions('purchaseType')"
@
update:item=
"val =>
{Projects.purchaseType = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'purchaseType'
]
}}
</span>
</single-radio>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['opportunityFrom'] ? errorData['opportunityFrom'] : ''"
>
<!--clientFrom-->
<single-radio
:form-item=
"Projects.opportunityFrom"
label=
"商机来源"
:required=
"true"
:options-list=
"getOptions('opportunityFrom')"
@
update:item=
"val =>
{Projects.opportunityFrom = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'opportunityFrom'
]
}}
</span>
</single-radio>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['description'] ? errorData['description'] : ''"
>
<single-input
label=
"商机内容"
:required=
"true"
type=
"textarea"
:rows=
"4"
:form-item=
"Projects.description"
@
update:item=
"val =>
{Projects.description = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'description'
]
}}
</span>
</single-input>
</el-form-item>
<el-form-item
:show-message=
"false"
:error=
"errorData['comment'] ? errorData['comment'] : ''"
>
<single-input
label=
"商机批注"
type=
"textarea"
:rows=
"4"
:form-item=
"Projects.comment"
@
update:item=
"val =>
{Projects.comment = val}">
<span
slot=
"formError"
class=
"el-form-item__error"
>
{{
errorData
[
'comment'
]
}}
</span>
</single-input>
</el-form-item>
<el-form-item>
<el-row
:gutter=
"10"
>
<el-col
:offset=
"4"
:span=
"14"
>
<slot
name=
"operationBtn"
>
</slot>
</el-col>
</el-row>
</el-form-item>
</el-form>
</div>
</
template
>
<
script
>
import
{
requestAPI
,
api
}
from
'@/lib/commonMixin'
import
singleSearchInput
from
'../../common/singleSearchInput'
import
singleInput
from
'../../common/singleInput'
import
multipleInput
from
'../../common/multipleInput'
import
singleCalcInput
from
'../../common/singleCalcInput'
import
singleRadio
from
'../../common/singleRadio'
import
singleDatePicker
from
'../../common/singleDatePicker'
import
multipleEngineer
from
'../../common/multipleEngineer'
import
singleCheckbox
from
'../../common/singleCheckbox'
export
default
{
name
:
''
,
data
()
{
return
{
Projects
:
{
id
:
''
,
client_id
:
''
,
project_status
:
0
,
project_progress
:
0
,
budget
:
''
,
profit_pct
:
''
,
bargain_date
:
''
,
description
:
''
,
project_title
:
''
,
collected
:
''
,
uncollected
:
''
,
projectTags
:
''
,
salesForecast
:
0
,
purchaseType
:
''
,
opportunityFrom
:
''
,
invoices
:
[],
paymentCollections
:
[],
contract_type
:
0
},
ProjectArchitects
:
{
engineer_id
:
[]
},
options
:
{
'Projects[contract_type]'
:
{
value
:
[
{
key
:
1
,
name
:
'产品销售'
},
{
key
:
2
,
name
:
'运维服务'
}
]
}
},
optionsKey
:
'Projects'
,
searchText
:
''
}
},
components
:
{
singleRadio
,
singleDatePicker
,
singleSearchInput
,
singleInput
,
multipleInput
,
singleCalcInput
,
multipleEngineer
,
singleCheckbox
// singleSelect
},
methods
:
{
getOptions
(
key
,
searchKey
)
{
let
sKey
=
searchKey
||
this
.
optionsKey
let
option
=
this
.
options
[
sKey
+
'['
+
key
+
']'
]
if
(
option
)
{
return
option
.
value
}
return
[]
},
setPrepend
(
index
,
text
)
{
return
'第'
+
(
index
+
1
)
+
text
},
setMultipleData
()
{
if
(
this
.
Projects
.
paymentCollections
.
length
===
0
)
{
this
.
Projects
.
paymentCollections
.
push
({
key
:
'new'
,
name
:
''
})
}
if
(
this
.
Projects
.
invoices
.
length
===
0
)
{
this
.
Projects
.
invoices
.
push
({
key
:
'new'
,
name
:
''
})
}
},
initAdd
()
{
if
(
this
.
$route
.
params
.
clientId
)
{
this
.
Projects
.
client_id
=
this
.
$route
.
params
.
clientId
requestAPI
(
api
.
getClient
,
{
data
:
{
id
:
this
.
$route
.
params
.
clientId
}
}).
then
(
res
=>
{
this
.
searchText
=
res
.
model
.
name
})
}
requestAPI
(
api
.
getProjectNewOptions
).
then
(
res
=>
{
Object
.
keys
(
res
.
options
).
forEach
(
key
=>
{
this
.
$set
(
this
.
options
,
key
,
res
.
options
[
key
])
})
})
this
.
setMultipleData
()
},
initEdit
()
{
requestAPI
(
api
.
getProjectEdit
,
{
data
:
{
id
:
this
.
$route
.
params
.
id
}
}).
then
(
res
=>
{
Object
.
keys
(
res
.
options
).
forEach
(
item
=>
{
if
(
res
.
options
[
item
].
value
)
{
res
.
options
[
item
].
value
.
forEach
(
i
=>
{
if
(
i
.
child
)
{
this
.
scenarioOptionIds
.
push
(
i
)
}
})
}
if
(
!
this
.
options
[
item
])
{
if
(
item
===
'Projects[project_tags]'
)
{
this
.
$set
(
this
.
options
,
'Projects[projectTags]'
,
res
.
options
[
item
])
}
else
{
this
.
$set
(
this
.
options
,
item
,
res
.
options
[
item
])
}
}
else
{
Object
.
assign
(
this
.
options
[
item
],
res
.
options
[
item
])
}
})
Object
.
keys
(
this
.
Projects
).
forEach
(
item
=>
{
if
(
res
.
model
[
item
])
{
if
(
Array
.
isArray
(
res
.
model
[
item
]))
{
console
.
log
(
item
)
this
.
Projects
[
item
]
=
res
.
model
[
item
].
map
(
i
=>
i
.
key
)
}
else
if
(
typeof
res
.
model
[
item
].
key
!==
'undefined'
)
{
console
.
log
(
item
)
this
.
Projects
[
item
]
=
res
.
model
[
item
].
key
}
else
{
this
.
Projects
[
item
]
=
res
.
model
[
item
]
}
}
})
Object
.
keys
(
this
.
ProjectArchitects
).
forEach
(
item
=>
{
if
(
item
===
'engineer_id'
)
{
this
.
Projects
[
item
]
=
[]
}
else
if
(
res
.
model
[
item
]
===
''
)
{
this
.
ProjectArchitects
[
item
]
=
[]
}
else
{
this
.
ProjectArchitects
[
item
]
=
res
.
model
[
item
]
}
})
if
(
res
.
model
.
client
)
{
this
.
searchText
=
res
.
model
.
client
.
name
this
.
Projects
.
client_id
=
res
.
model
.
client
.
key
}
})
}
},
created
()
{
},
props
:
[
'errorData'
],
watch
:
{
'Projects.project_status'
(
val
)
{
if
(
val
===
3
)
{
this
.
$alert
(
'请确认成交日期和商机金额与合同相符。'
)
}
},
'ProjectArchitects.engineer_id'
(
val
)
{
console
.
log
(
val
)
}
}
}
</
script
>
<
style
lang=
"scss"
>
.project-add-edit-form
{
height
:
400px
;
overflow-y
:
auto
;
}
.auto-template-form
{
.el-form-item
{
margin-bottom
:
10px
;
}
.client-label
{
position
:
relative
;
font-size
:
12px
;
}
.multiple-input
.el-checkbox__label
{
padding-left
:
2px
;
}
.client-label
span
{
padding-right
:
10px
;
}
.client-label.required
:after
{
content
:
"*"
;
color
:
#eb7567
;
position
:
absolute
;
top
:
3px
;
right
:
6px
;
}
.el-form-item__error
{
position
:
static
;
}
}
</
style
>
src/components/project/projectListForm.vue
View file @
e04d1ca5
...
...
@@ -213,7 +213,6 @@
this
.
$set
(
this
.
clientTimeForm
,
val
+
'['
+
item
+
']'
,
''
)
})
}
console
.
log
(
val
)
},
immediate
:
true
}
...
...
src/components/project/projectOfClient/projectOfClient.vue
0 → 100644
View file @
e04d1ca5
<
template
>
<section>
<div
class=
"content"
>
<client-header
ref=
"clientHeader"
:title=
"'客户名称:' + model.name"
:title-span=
"12"
type=
""
></client-header>
<div
class=
"page-body-content"
>
<client-nav
:trigger=
"addProject"
trigger-text=
"新建商机"
></client-nav>
<div
v-loading=
"loading"
>
<ScheduleItem
v-for=
"(item, key) in result.list"
:item=
"item"
:key=
"key"
@
update:image=
"imgs =>
{setImage(imgs)}">
<span
slot=
"opearate"
>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
:disabled=
"!item.can_delete"
@
click=
"delProject(item.id)"
>
<i
class=
"fa fa-trash-o faa-shake"
></i>
删除
</el-button>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
:disabled=
"!item.can_schedule"
>
<i
class=
"fa fa-th-list"
></i>
新建待办事项
</el-button>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
:disabled=
"!item.can_update"
@
click=
"editProject(item)"
>
<i
class=
"fa fa-edit"
></i>
编辑
</el-button>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
:disabled=
"!item.can_update"
>
<i
class=
"fa fa-tag"
></i>
批注
</el-button>
<el-button
class=
"pull-right"
type=
"primary"
size=
"mini"
@
click
.
prevent
.
stop=
"leaveMessageSch(item)"
>
<span
:class=
"['badge',
{'badge-unread': item.unread > 0}]"
v-if="item.commentCount">
{{
item
.
commentCount
.
comment
}}
</span>
<i
class=
"fa fa-commenting"
></i>
留言
</el-button>
</span>
</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
>
<
script
>
import
{
requestAPI
,
api
}
from
'@/lib/commonMixin'
import
ScheduleItem
from
'../../common/scheduleItem'
import
clientHeader
from
'../../common/clientHeader'
import
Pagenation
from
'../schedulePagenation'
export
default
{
name
:
''
,
data
()
{
return
{
client_id
:
''
,
loading
:
false
,
clientName
:
''
,
model
:
{
name
:
''
},
result
:
{
list
:
[]
},
detailModel
:
[],
pagenation
:
{
page
:
1
},
totalcount
:
0
,
tableList
:
[]
}
},
components
:
{
ScheduleItem
,
clientHeader
,
Pagenation
},
methods
:
{
delProject
(
id
)
{
this
.
$confirm
(
'确认删除吗?'
,
'提示'
).
then
(()
=>
{
requestAPI
(
api
.
delProject
,
{
data
:
{
id
}
}).
then
(()
=>
{
this
.
$message
(
'删除成功!'
)
this
.
getList
()
},
error
=>
{
if
(
Array
.
isArray
(
error
.
msg
))
{
error
.
msg
.
forEach
(
item
=>
{
this
.
$notify
.
error
({
title
:
'错误'
,
message
:
item
.
error
})
})
}
})
}).
catch
(
_
=>
{
})
},
addProject
()
{
this
.
$router
.
push
({
name
:
'addProjectClient'
,
params
:
{
clientId
:
this
.
$route
.
params
.
id
}})
},
editProject
(
row
)
{
this
.
$router
.
push
({
name
:
'editProjectClient'
,
params
:
{
id
:
row
.
id
,
clientId
:
row
.
client_id
}})
},
getList
()
{
if
(
this
.
loading
)
{
return
}
this
.
loading
=
true
requestAPI
(
api
.
getProjectClient
,
{
data
:
{
id
:
this
.
$route
.
params
.
id
}
}).
then
(
res
=>
{
this
.
result
.
list
=
res
.
list
// this.pagenation.page = res.pagenation.thispage
this
.
totalcount
=
res
.
pagenation
.
totalcount
}).
finally
(
_
=>
{
this
.
loading
=
false
})
}
},
created
()
{
requestAPI
(
api
.
getClient
,
{
data
:
{
id
:
this
.
$route
.
params
.
id
}
}).
then
(
res
=>
{
Object
.
keys
(
res
.
model
).
forEach
(
item
=>
{
this
.
$set
(
this
.
model
,
item
,
res
.
model
[
item
])
})
this
.
getList
()
},
error
=>
{
if
(
Array
.
isArray
(
error
.
msg
))
{
error
.
msg
.
forEach
(
item
=>
{
this
.
$notify
.
error
({
title
:
'错误'
,
message
:
item
.
error
})
})
}
})
}
}
</
script
>
<
style
scoped
>
.badge
{
border-radius
:
2px
;
color
:
#333744
;
background
:
#ffffff
;
vertical-align
:
baseline
;
display
:
inline
;
padding
:
2px
6px
;
text-align
:
center
;
}
</
style
>
src/components/project/schedulePagenation.vue
View file @
e04d1ca5
<
template
>
<section
class=
"pull-right"
>
<el-pagination
v-if=
"total >
0
"
class=
""
background
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
:current-page=
"pager.page"
:page-sizes=
"[10, 20, 40, 60, 80, 100]"
:page-size=
"pager.pagesize"
layout=
"total, prev, pager, next, jumper"
:total=
"total"
>
<section
class=
"pull-right
page-footer
"
>
<el-pagination
v-if=
"total >
pager.pagesize
"
class=
""
background
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
:current-page=
"pager.page"
:page-sizes=
"[10, 20, 40, 60, 80, 100]"
:page-size=
"pager.pagesize"
layout=
"total, prev, pager, next, jumper"
:total=
"total"
>
</el-pagination>
<span
v-else
>
总计
{{
total
}}
条 当前显示第1至第
{{
total
}}
条
</span>
</section>
</
template
>
<
script
>
export
default
{
props
:
{
total
:
{
type
:
Number
,
default
:
0
}
},
data
()
{
return
{
pager
:
{
page
:
1
,
pagesize
:
20
},
totalcount
:
0
}
},
created
()
{
// this.$emit('update:pager', this.pager)
},
methods
:
{
handleSizeChange
(
val
)
{
this
.
pager
.
page
=
1
this
.
pager
.
pagesize
=
val
// this.totalcount = this.total
this
.
$emit
(
'update:pager'
,
this
.
pager
)
// this.$parent.loadList()
export
default
{
props
:
{
total
:
{
type
:
Number
,
default
:
0
}
},
data
()
{
return
{
pager
:
{
page
:
1
,
pagesize
:
20
},
totalcount
:
0
}
},
handleCurrentChange
(
val
)
{
this
.
pager
.
page
=
val
// this.totalcount = this.total
this
.
$emit
(
'update:pager'
,
this
.
pager
)
// this.$parent.loadList()
created
()
{
// this.$emit('update:pager', this.pager)
},
methods
:
{
handleSizeChange
(
val
)
{
this
.
pager
.
page
=
1
this
.
pager
.
pagesize
=
val
// this.totalcount = this.total
this
.
$emit
(
'update:pager'
,
this
.
pager
)
// this.$parent.loadList()
},
handleCurrentChange
(
val
)
{
this
.
pager
.
page
=
val
// this.totalcount = this.total
this
.
$emit
(
'update:pager'
,
this
.
pager
)
// this.$parent.loadList()
}
}
}
}
</
script
>
<
style
scoped
>
.page-footer
{
padding
:
0
30px
;
}
</
style
>
src/lib/singleItemMixin.js
View file @
e04d1ca5
...
...
@@ -14,7 +14,8 @@ export default {
endDateTime
:
{
date
:
''
,
time
:
''
}
},
engineer
:
[]
}
},
props
:
{
...
...
@@ -28,6 +29,9 @@ export default {
formTimeItem
:
{
type
:
String
},
calcItem
:
''
,
minuendItem
:
Array
,
disabled
:
false
,
startDateTimeItem
:
{
type
:
String
},
...
...
@@ -79,7 +83,10 @@ export default {
multipleKey
:
{
type
:
String
,
default
:
'name'
}
},
setPrepend
:
Function
,
setPrependText
:
''
,
engineerKey
:
''
},
methods
:
{
addItem
(
items
)
{
...
...
@@ -90,13 +97,17 @@ export default {
},
delItem
(
items
,
key
)
{
items
.
splice
(
key
,
1
)
},
setPerText
(
index
)
{
if
(
this
.
setPrepend
)
{
return
this
.
setPrepend
(
index
,
this
.
setPrependText
)
}
}
},
watch
:
{
'formItem'
:
{
handler
(
val
)
{
if
(
Array
.
isArray
(
val
))
{
console
.
log
(
val
)
this
.
items
=
val
}
else
{
this
.
item
=
val
...
...
@@ -114,6 +125,21 @@ export default {
'item'
(
val
)
{
this
.
$emit
(
'update:item'
,
val
)
},
'optionsList'
:
{
handler
(
val
)
{
if
(
this
.
engineerKey
)
{
val
.
forEach
(
item
=>
{
this
.
engineer
.
push
({
name
:
item
.
name
,
disabled
:
false
,
[
item
.
key
]:
''
,
key
:
item
.
key
})
})
}
},
immediate
:
true
},
'items'
:
{
handler
(
val
)
{
this
.
$emit
(
'update:item'
,
val
)
...
...
@@ -125,6 +151,21 @@ export default {
},
'inputSelectItem'
(
val
)
{
this
.
$emit
(
'update:inputSelect'
,
val
)
},
'engineer'
:
{
handler
(
val
)
{
let
engine
=
val
.
filter
(
i
=>
{
if
(
i
[
i
.
key
]
!==
''
)
{
return
typeof
i
[
i
.
key
]
!==
'undefined'
}
}).
map
(
i
=>
{
return
{
[
i
.
key
]:
i
[
i
.
key
]
}
})
this
.
$emit
(
'update:item'
,
engine
)
},
deep
:
true
}
}
}
src/routes/project.js
View file @
e04d1ca5
import
projectList
from
'../components/project/list'
import
projectOfClient
from
'../components/project/projectOfClient/projectOfClient'
import
addProject
from
'../components/project/operation/addProject'
import
editProject
from
'../components/project/operation/editProject'
const
projectTitle
=
'金畅逍BMS - '
const
routes
=
[
{
...
...
@@ -8,6 +11,34 @@ const routes = [
meta
:
{
title
:
projectTitle
+
'商机列表'
}
},
{
path
:
'/ofClient/:id'
,
name
:
'ofClient'
,
component
:
projectOfClient
,
meta
:
{
title
:
projectTitle
+
'客户信息'
}
},
{
path
:
'/addProject'
,
name
:
'addProject'
,
component
:
addProject
},
{
path
:
'/editProject/:id'
,
name
:
'editProject'
,
component
:
editProject
},
{
path
:
'/addProjectClient/:clientId'
,
name
:
'addProjectClient'
,
component
:
addProject
},
{
path
:
'/editProjectClient/:id/:clientId'
,
name
:
'editProjectClient'
,
component
:
editProject
}
]
export
default
routes
static/vupVueSdk.js
View file @
e04d1ca5
This source diff could not be displayed because it is too large. You can
view the blob
instead.
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