Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
d9e1ffd5
authored
Feb 25, 2024
by
puhui999
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'yudao/dev' into dev-crm
parents
41e5cf66
12972cdf
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
300 additions
and
100 deletions
+300
-100
src/api/crm/backlog/index.ts
+0
-5
src/api/crm/contact/index.ts
+15
-0
src/api/crm/contract/index.ts
+10
-0
src/api/crm/statistics/rank.ts
+10
-10
src/views/crm/backlog/components/ContractAuditList.vue
+74
-18
src/views/crm/backlog/components/ContractRemindList.vue
+73
-19
src/views/crm/backlog/components/CustomerFollowList.vue
+7
-4
src/views/crm/backlog/components/common.ts
+3
-2
src/views/crm/backlog/index.vue
+15
-14
src/views/crm/contact/components/ContactList.vue
+67
-2
src/views/crm/contract/index.vue
+1
-1
src/views/crm/statistics/rank/ContactsCountRank.vue
+3
-3
src/views/crm/statistics/rank/ContractCountRank.vue
+3
-3
src/views/crm/statistics/rank/ContractPriceRank.vue
+3
-3
src/views/crm/statistics/rank/CustomerCountRank.vue
+3
-3
src/views/crm/statistics/rank/FollowCountRank.vue
+3
-3
src/views/crm/statistics/rank/FollowCustomerCountRank.vue
+3
-3
src/views/crm/statistics/rank/ProductSalesRank.vue
+3
-3
src/views/crm/statistics/rank/ReceivablePriceRank.vue
+3
-3
src/views/crm/statistics/rank/index.vue
+1
-1
No files found.
src/api/crm/backlog/index.ts
View file @
d9e1ffd5
import
request
from
'@/config/axios'
// TODO 芋艿:融合下
// 3. 获得分配给我的客户数量
export
const
getFollowCustomerCount
=
async
()
=>
{
return
await
request
.
get
({
url
:
'/crm/customer/follow-customer-count'
})
}
// 5. 获得待审核合同数量
export
const
getCheckContractCount
=
async
()
=>
{
return
await
request
.
get
({
url
:
'/crm/contract/check-contract-count'
})
...
...
src/api/crm/contact/index.ts
View file @
d9e1ffd5
...
...
@@ -37,6 +37,11 @@ export interface ContactBusinessReqVO {
businessIds
:
number
[]
}
export
interface
ContactBusiness2ReqVO
{
businessId
:
number
contactIds
:
number
[]
}
// 查询 CRM 联系人列表
export
const
getContactPage
=
async
(
params
)
=>
{
return
await
request
.
get
({
url
:
`/crm/contact/page`
,
params
})
...
...
@@ -87,11 +92,21 @@ export const createContactBusinessList = async (data: ContactBusinessReqVO) => {
return
await
request
.
post
({
url
:
`/crm/contact/create-business-list`
,
data
})
}
// 批量新增联系人商机关联
export
const
createContactBusinessList2
=
async
(
data
:
ContactBusiness2ReqVO
)
=>
{
return
await
request
.
post
({
url
:
`/crm/contact/create-business-list2`
,
data
})
}
// 解除联系人商机关联
export
const
deleteContactBusinessList
=
async
(
data
:
ContactBusinessReqVO
)
=>
{
return
await
request
.
delete
({
url
:
`/crm/contact/delete-business-list`
,
data
})
}
// 解除联系人商机关联
export
const
deleteContactBusinessList2
=
async
(
data
:
ContactBusiness2ReqVO
)
=>
{
return
await
request
.
delete
({
url
:
`/crm/contact/delete-business-list2`
,
data
})
}
// 联系人转移
export
const
transferContact
=
async
(
data
:
TransferReqVO
)
=>
{
return
await
request
.
put
({
url
:
'/crm/contact/transfer'
,
data
})
...
...
src/api/crm/contract/index.ts
View file @
d9e1ffd5
...
...
@@ -101,3 +101,13 @@ export const submitContract = async (id: number) => {
export
const
transferContract
=
async
(
data
:
TransferReqVO
)
=>
{
return
await
request
.
put
({
url
:
'/crm/contract/transfer'
,
data
})
}
// 获得待审核合同数量
export
const
getAuditContractCount
=
async
()
=>
{
return
await
request
.
get
({
url
:
'/crm/contract/audit-count'
})
}
// 获得即将到期(提醒)的合同数量
export
const
getRemindContractCount
=
async
()
=>
{
return
await
request
.
get
({
url
:
'/crm/contract/remind-count'
})
}
src/api/crm/
bi
/rank.ts
→
src/api/crm/
statistics
/rank.ts
View file @
d9e1ffd5
import
request
from
'@/config/axios'
export
interface
Bi
RankRespVO
{
export
interface
Statistics
RankRespVO
{
count
:
number
nickname
:
string
deptName
:
string
}
// 排行 API
export
const
RankApi
=
{
export
const
Statistics
RankApi
=
{
// 获得合同排行榜
getContractPriceRank
:
(
params
:
any
)
=>
{
return
request
.
get
({
url
:
'/crm/
bi
-rank/get-contract-price-rank'
,
url
:
'/crm/
statistics
-rank/get-contract-price-rank'
,
params
})
},
// 获得回款排行榜
getReceivablePriceRank
:
(
params
:
any
)
=>
{
return
request
.
get
({
url
:
'/crm/
bi
-rank/get-receivable-price-rank'
,
url
:
'/crm/
statistics
-rank/get-receivable-price-rank'
,
params
})
},
// 签约合同排行
getContractCountRank
:
(
params
:
any
)
=>
{
return
request
.
get
({
url
:
'/crm/
bi
-rank/get-contract-count-rank'
,
url
:
'/crm/
statistics
-rank/get-contract-count-rank'
,
params
})
},
// 产品销量排行
getProductSalesRank
:
(
params
:
any
)
=>
{
return
request
.
get
({
url
:
'/crm/
bi
-rank/get-product-sales-rank'
,
url
:
'/crm/
statistics
-rank/get-product-sales-rank'
,
params
})
},
// 新增客户数排行
getCustomerCountRank
:
(
params
:
any
)
=>
{
return
request
.
get
({
url
:
'/crm/
bi
-rank/get-customer-count-rank'
,
url
:
'/crm/
statistics
-rank/get-customer-count-rank'
,
params
})
},
// 新增联系人数排行
getContactsCountRank
:
(
params
:
any
)
=>
{
return
request
.
get
({
url
:
'/crm/
bi
-rank/get-contacts-count-rank'
,
url
:
'/crm/
statistics
-rank/get-contacts-count-rank'
,
params
})
},
// 跟进次数排行
getFollowCountRank
:
(
params
:
any
)
=>
{
return
request
.
get
({
url
:
'/crm/
bi
-rank/get-follow-count-rank'
,
url
:
'/crm/
statistics
-rank/get-follow-count-rank'
,
params
})
},
// 跟进客户数排行
getFollowCustomerCountRank
:
(
params
:
any
)
=>
{
return
request
.
get
({
url
:
'/crm/
bi
-rank/get-follow-customer-count-rank'
,
url
:
'/crm/
statistics
-rank/get-follow-customer-count-rank'
,
params
})
}
...
...
src/views/crm/backlog/
tables/CheckContrac
t.vue
→
src/views/crm/backlog/
components/ContractAuditLis
t.vue
View file @
d9e1ffd5
...
...
@@ -30,8 +30,14 @@
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:show-overflow-tooltip=
"true"
:stripe=
"true"
>
<el-table-column
align=
"center"
fixed=
"left"
label=
"合同编号"
prop=
"no"
width=
"130"
/>
<el-table-column
align=
"center"
label=
"合同名称"
prop=
"name"
width=
"130"
/>
<el-table-column
align=
"center"
fixed=
"left"
label=
"合同编号"
prop=
"no"
width=
"180"
/>
<el-table-column
align=
"center"
fixed=
"left"
label=
"合同名称"
prop=
"name"
width=
"160"
>
<template
#
default=
"scope"
>
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openDetail(scope.row.id)"
>
{{
scope
.
row
.
name
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"客户名称"
prop=
"customerName"
width=
"120"
>
<
template
#
default=
"scope"
>
<el-link
...
...
@@ -43,8 +49,24 @@
</el-link>
</
template
>
</el-table-column>
<!-- TODO @puhui999:做了商机详情后,可以把这个超链接加上 -->
<el-table-column
align=
"center"
label=
"商机名称"
prop=
"businessName"
width=
"130"
/>
<el-table-column
align=
"center"
label=
"商机名称"
prop=
"businessName"
width=
"130"
>
<
template
#
default=
"scope"
>
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openBusinessDetail(scope.row.businessId)"
>
{{
scope
.
row
.
businessName
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"合同金额(元)"
prop=
"totalPrice"
width=
"140"
:formatter=
"erpPriceTableColumnFormatter"
/>
<el-table-column
align=
"center"
label=
"下单时间"
...
...
@@ -54,13 +76,6 @@
/>
<el-table-column
align=
"center"
label=
"合同金额"
prop=
"price"
width=
"130"
:formatter=
"fenToYuanFormat"
/>
<el-table-column
align=
"center"
label=
"合同开始时间"
prop=
"startTime"
width=
"120"
...
...
@@ -78,17 +93,24 @@
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openContactDetail(scope.row.
c
ontactId)"
@
click=
"openContactDetail(scope.row.
signC
ontactId)"
>
{{
scope
.
row
.
c
ontactName
}}
{{
scope
.
row
.
signC
ontactName
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"公司签约人"
prop=
"signUserName"
width=
"130"
/>
<el-table-column
align=
"center"
label=
"备注"
prop=
"remark"
width=
"
13
0"
/>
<el-table-column
align=
"center"
label=
"备注"
prop=
"remark"
width=
"
20
0"
/>
<!-- TODO @puhui999:后续可加 【已收款金额】、【未收款金额】 -->
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"最后跟进时间"
prop=
"contactLastTime"
width=
"180px"
/>
<el-table-column
align=
"center"
label=
"负责人"
prop=
"ownerUserName"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"
创建人"
prop=
"creatorName"
width=
"120
"
/>
<el-table-column
align=
"center"
label=
"
所属部门"
prop=
"ownerUserDeptName"
width=
"100px
"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
...
...
@@ -103,11 +125,24 @@
prop=
"createTime"
width=
"180px"
/>
<el-table-column
align=
"center"
label=
"创建人"
prop=
"creatorName"
width=
"120"
/>
<el-table-column
align=
"center"
fixed=
"right"
label=
"合同状态"
prop=
"auditStatus"
width=
"120"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.CRM_AUDIT_STATUS"
:value=
"scope.row.auditStatus"
/>
</
template
>
</el-table-column>
<el-table-column
fixed=
"right"
label=
"操作"
width=
"90"
>
<
template
#
default=
"scope"
>
<el-button
link
v-hasPermi=
"['crm:contract:update']"
type=
"primary"
@
click=
"handleProcessDetail(scope.row)"
>
查看审批
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
...
...
@@ -122,9 +157,9 @@
<
script
setup
lang=
"ts"
name=
"CheckContract"
>
import
{
dateFormatter
,
dateFormatter2
}
from
'@/utils/formatTime'
import
*
as
ContractApi
from
'@/api/crm/contract'
import
{
fenToYuanFormat
}
from
'@/utils/formatter'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
AUDIT_STATUS
}
from
'./common'
import
{
erpPriceTableColumnFormatter
}
from
'@/utils'
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
...
...
@@ -132,7 +167,8 @@ const list = ref([]) // 列表的数据
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
auditStatus
:
20
sceneType
:
1
,
// 我负责的
auditStatus
:
10
})
const
queryFormRef
=
ref
()
// 搜索的表单
...
...
@@ -154,8 +190,18 @@ const handleQuery = () => {
getList
()
}
/** 查看审批 */
const
handleProcessDetail
=
(
row
:
ContractApi
.
ContractVO
)
=>
{
push
({
name
:
'BpmProcessInstanceDetail'
,
query
:
{
id
:
row
.
processInstanceId
}
})
}
/** 打开合同详情 */
const
{
push
}
=
useRouter
()
const
openDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmContractDetail'
,
params
:
{
id
}
})
}
/** 打开客户详情 */
const
{
push
}
=
useRouter
()
// 路由
const
openCustomerDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmCustomerDetail'
,
params
:
{
id
}
})
}
...
...
@@ -165,6 +211,16 @@ const openContactDetail = (id: number) => {
push
({
name
:
'CrmContactDetail'
,
params
:
{
id
}
})
}
/** 打开商机详情 */
const
openBusinessDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmBusinessDetail'
,
params
:
{
id
}
})
}
/** 激活时 */
onActivated
(
async
()
=>
{
await
getList
()
})
/** 初始化 **/
onMounted
(()
=>
{
getList
()
...
...
src/views/crm/backlog/
tables/EndContrac
t.vue
→
src/views/crm/backlog/
components/ContractRemindLis
t.vue
View file @
d9e1ffd5
...
...
@@ -30,8 +30,14 @@
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:show-overflow-tooltip=
"true"
:stripe=
"true"
>
<el-table-column
align=
"center"
fixed=
"left"
label=
"合同编号"
prop=
"no"
width=
"130"
/>
<el-table-column
align=
"center"
label=
"合同名称"
prop=
"name"
width=
"130"
/>
<el-table-column
align=
"center"
fixed=
"left"
label=
"合同编号"
prop=
"no"
width=
"180"
/>
<el-table-column
align=
"center"
fixed=
"left"
label=
"合同名称"
prop=
"name"
width=
"160"
>
<template
#
default=
"scope"
>
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openDetail(scope.row.id)"
>
{{
scope
.
row
.
name
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"客户名称"
prop=
"customerName"
width=
"120"
>
<
template
#
default=
"scope"
>
<el-link
...
...
@@ -43,8 +49,24 @@
</el-link>
</
template
>
</el-table-column>
<!-- TODO @puhui999:做了商机详情后,可以把这个超链接加上 -->
<el-table-column
align=
"center"
label=
"商机名称"
prop=
"businessName"
width=
"130"
/>
<el-table-column
align=
"center"
label=
"商机名称"
prop=
"businessName"
width=
"130"
>
<
template
#
default=
"scope"
>
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openBusinessDetail(scope.row.businessId)"
>
{{
scope
.
row
.
businessName
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"合同金额(元)"
prop=
"totalPrice"
width=
"140"
:formatter=
"erpPriceTableColumnFormatter"
/>
<el-table-column
align=
"center"
label=
"下单时间"
...
...
@@ -54,13 +76,6 @@
/>
<el-table-column
align=
"center"
label=
"合同金额"
prop=
"price"
width=
"130"
:formatter=
"fenToYuanFormat"
/>
<el-table-column
align=
"center"
label=
"合同开始时间"
prop=
"startTime"
width=
"120"
...
...
@@ -78,17 +93,24 @@
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openContactDetail(scope.row.
c
ontactId)"
@
click=
"openContactDetail(scope.row.
signC
ontactId)"
>
{{
scope
.
row
.
c
ontactName
}}
{{
scope
.
row
.
signC
ontactName
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"公司签约人"
prop=
"signUserName"
width=
"130"
/>
<el-table-column
align=
"center"
label=
"备注"
prop=
"remark"
width=
"
13
0"
/>
<el-table-column
align=
"center"
label=
"备注"
prop=
"remark"
width=
"
20
0"
/>
<!-- TODO @puhui999:后续可加 【已收款金额】、【未收款金额】 -->
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"最后跟进时间"
prop=
"contactLastTime"
width=
"180px"
/>
<el-table-column
align=
"center"
label=
"负责人"
prop=
"ownerUserName"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"
创建人"
prop=
"creatorName"
width=
"120
"
/>
<el-table-column
align=
"center"
label=
"
所属部门"
prop=
"ownerUserDeptName"
width=
"100px
"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
...
...
@@ -103,11 +125,24 @@
prop=
"createTime"
width=
"180px"
/>
<el-table-column
align=
"center"
label=
"创建人"
prop=
"creatorName"
width=
"120"
/>
<el-table-column
align=
"center"
fixed=
"right"
label=
"合同状态"
prop=
"auditStatus"
width=
"120"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.CRM_AUDIT_STATUS"
:value=
"scope.row.auditStatus"
/>
</
template
>
</el-table-column>
<el-table-column
fixed=
"right"
label=
"操作"
width=
"90"
>
<
template
#
default=
"scope"
>
<el-button
link
v-hasPermi=
"['crm:contract:update']"
type=
"primary"
@
click=
"handleProcessDetail(scope.row)"
>
查看审批
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
...
...
@@ -125,8 +160,7 @@ import * as ContractApi from '@/api/crm/contract'
import
{
fenToYuanFormat
}
from
'@/utils/formatter'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
CONTRACT_EXPIRY_TYPE
}
from
'./common'
const
{
push
}
=
useRouter
()
// 路由
import
{
erpPriceTableColumnFormatter
}
from
'@/utils'
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
...
...
@@ -134,6 +168,7 @@ const list = ref([]) // 列表的数据
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
sceneType
:
'1'
,
// 自己负责的
expiryType
:
1
})
const
queryFormRef
=
ref
()
// 搜索的表单
...
...
@@ -156,6 +191,17 @@ const handleQuery = () => {
getList
()
}
/** 查看审批 */
const
handleProcessDetail
=
(
row
:
ContractApi
.
ContractVO
)
=>
{
push
({
name
:
'BpmProcessInstanceDetail'
,
query
:
{
id
:
row
.
processInstanceId
}
})
}
/** 打开合同详情 */
const
{
push
}
=
useRouter
()
const
openDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmContractDetail'
,
params
:
{
id
}
})
}
/** 打开客户详情 */
const
openCustomerDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmCustomerDetail'
,
params
:
{
id
}
})
...
...
@@ -166,10 +212,18 @@ const openContactDetail = (id: number) => {
push
({
name
:
'CrmContactDetail'
,
params
:
{
id
}
})
}
/** 打开商机详情 */
const
openBusinessDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmBusinessDetail'
,
params
:
{
id
}
})
}
/** 激活时 */
onActivated
(
async
()
=>
{
await
getList
()
})
/** 初始化 **/
onMounted
(()
=>
{
getList
()
})
</
script
>
<
style
scoped
></
style
>
src/views/crm/backlog/components/CustomerFollowList.vue
View file @
d9e1ffd5
...
...
@@ -130,8 +130,8 @@ const list = ref([]) // 列表的数据
const
queryParams
=
ref
({
pageNo
:
1
,
pageSize
:
10
,
followUpStatus
:
false
,
sceneType
:
1
sceneType
:
1
,
followUpStatus
:
false
})
const
queryFormRef
=
ref
()
// 搜索的表单
...
...
@@ -158,10 +158,13 @@ const openDetail = (id: number) => {
push
({
name
:
'CrmCustomerDetail'
,
params
:
{
id
}
})
}
/** 激活时 */
onActivated
(
async
()
=>
{
await
getList
()
})
/** 初始化 **/
onMounted
(()
=>
{
getList
()
})
</
script
>
<
style
scoped
></
style
>
src/views/crm/backlog/components/common.ts
View file @
d9e1ffd5
...
...
@@ -20,8 +20,9 @@ export const CONTACT_STATUS = [
/** 审批状态 */
export
const
AUDIT_STATUS
=
[
{
label
:
'已审批'
,
value
:
20
},
{
label
:
'待审批'
,
value
:
10
}
{
label
:
'待审批'
,
value
:
10
},
{
label
:
'审核通过'
,
value
:
20
},
{
label
:
'审核不通过'
,
value
:
30
}
]
/** 回款提醒类型 */
...
...
src/views/crm/backlog/index.vue
View file @
d9e1ffd5
...
...
@@ -17,9 +17,9 @@
<el-col
:span=
"20"
:xs=
"24"
>
<CustomerTodayContactList
v-if=
"leftMenu === 'customerTodayContact'"
/>
<ClueFollowList
v-if=
"leftMenu === 'clueFollow'"
/>
<C
heckContract
v-if=
"leftMenu === 'checkContrac
t'"
/>
<C
ontractAuditList
v-if=
"leftMenu === 'contractAudi
t'"
/>
<CheckReceivables
v-if=
"leftMenu === 'checkReceivables'"
/>
<
EndContract
v-if=
"leftMenu === 'endContract
'"
/>
<
ContractRemindList
v-if=
"leftMenu === 'contractRemind
'"
/>
<CustomerFollowList
v-if=
"leftMenu === 'customerFollow'"
/>
<CustomerPutPoolRemindList
v-if=
"leftMenu === 'customerPutPoolRemind'"
/>
<RemindReceivables
v-if=
"leftMenu === 'remindReceivables'"
/>
...
...
@@ -33,25 +33,26 @@ import CustomerFollowList from './components/CustomerFollowList.vue'
import
CustomerTodayContactList
from
'./components/CustomerTodayContactList.vue'
import
CustomerPutPoolRemindList
from
'./components/CustomerPutPoolRemindList.vue'
import
ClueFollowList
from
'./components/ClueFollowList.vue'
import
CheckContract
from
'./tables/CheckContract.vue'
import
CheckReceivables
from
'./tables/CheckReceivables.vue'
import
EndContract
from
'./tables/EndContract.vue'
import
ContractAuditList
from
'./components/ContractAuditList.vue'
import
ContractRemindList
from
'./components/ContractRemindList.vue'
import
RemindReceivables
from
'./tables/RemindReceivables.vue'
import
CheckReceivables
from
'./tables/CheckReceivables.vue'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
*
as
ClueApi
from
'@/api/crm/clue'
import
*
as
ContractApi
from
'@/api/crm/contract'
defineOptions
({
name
:
'CrmBacklog'
})
const
leftMenu
=
ref
(
'customerTodayContact'
)
const
customerTodayContactCount
=
ref
(
0
)
const
clueFollowCount
=
ref
(
0
)
const
customerFollowCount
=
ref
(
0
)
const
customerPutPoolRemindCount
=
ref
(
0
)
const
checkContractCount
=
ref
(
0
)
const
customerTodayContactCount
=
ref
(
0
)
const
contractAuditCount
=
ref
(
0
)
const
contractRemindCount
=
ref
(
0
)
const
checkReceivablesCount
=
ref
(
0
)
const
remindReceivablesCount
=
ref
(
0
)
const
endContractCount
=
ref
(
0
)
const
leftSides
=
ref
([
{
...
...
@@ -76,8 +77,8 @@ const leftSides = ref([
},
{
name
:
'待审核合同'
,
menu
:
'c
heckContrac
t'
,
count
:
c
heckContrac
tCount
menu
:
'c
ontractAudi
t'
,
count
:
c
ontractAudi
tCount
},
{
name
:
'待审核回款'
,
...
...
@@ -91,8 +92,8 @@ const leftSides = ref([
},
{
name
:
'即将到期的合同'
,
menu
:
'
endContract
'
,
count
:
endContract
Count
menu
:
'
contractRemind
'
,
count
:
contractRemind
Count
}
])
...
...
@@ -110,10 +111,10 @@ const getCount = () => {
)
CustomerApi
.
getFollowCustomerCount
().
then
((
count
)
=>
(
customerFollowCount
.
value
=
count
))
ClueApi
.
getFollowClueCount
().
then
((
count
)
=>
(
clueFollowCount
.
value
=
count
))
BacklogApi
.
getCheckContractCount
().
then
((
count
)
=>
(
checkContractCount
.
value
=
count
))
ContractApi
.
getAuditContractCount
().
then
((
count
)
=>
(
contractAuditCount
.
value
=
count
))
ContractApi
.
getRemindContractCount
().
then
((
count
)
=>
(
contractRemindCount
.
value
=
count
))
BacklogApi
.
getCheckReceivablesCount
().
then
((
count
)
=>
(
checkReceivablesCount
.
value
=
count
))
BacklogApi
.
getRemindReceivablePlanCount
().
then
((
count
)
=>
(
remindReceivablesCount
.
value
=
count
))
BacklogApi
.
getEndContractCount
().
then
((
count
)
=>
(
endContractCount
.
value
=
count
))
}
/** 激活时 */
...
...
src/views/crm/contact/components/ContactList.vue
View file @
d9e1ffd5
...
...
@@ -5,11 +5,32 @@
<Icon
class=
"mr-5px"
icon=
"system-uicons:contacts"
/>
创建联系人
</el-button>
<el-button
@
click=
"openBusinessModal"
v-hasPermi=
"['crm:contact:create-business']"
v-if=
"queryParams.businessId"
>
<Icon
class=
"mr-5px"
icon=
"ep:circle-plus"
/>
关联
</el-button>
<el-button
@
click=
"deleteContactBusinessList"
v-hasPermi=
"['crm:contact:delete-business']"
v-if=
"queryParams.businessId"
>
<Icon
class=
"mr-5px"
icon=
"ep:remove"
/>
解除关联
</el-button>
</el-row>
<!-- 列表 -->
<ContentWrap
class=
"mt-10px"
>
<el-table
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
>
<el-table
ref=
"contactRef"
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
>
<el-table-column
type=
"selection"
width=
"55"
v-if=
"queryParams.businessId"
/>
<el-table-column
label=
"姓名"
fixed=
"left"
align=
"center"
prop=
"name"
>
<template
#
default=
"scope"
>
<el-link
type=
"primary"
:underline=
"false"
@
click=
"openDetail(scope.row.id)"
>
...
...
@@ -37,12 +58,19 @@
<!-- 表单弹窗:添加 -->
<ContactForm
ref=
"formRef"
@
success=
"getList"
/>
<!-- 关联商机选择弹框 -->
<ContactListModal
ref=
"contactModalRef"
:customer-id=
"props.customerId"
@
success=
"createContactBusinessList"
/>
</template>
<
script
setup
lang=
"ts"
>
import
*
as
ContactApi
from
'@/api/crm/contact'
import
ContactForm
from
'./../ContactForm.vue'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
BizTypeEnum
}
from
'@/api/crm/permission'
import
ContactListModal
from
'./ContactListModal.vue'
defineOptions
({
name
:
'CrmContactList'
})
const
props
=
defineProps
<
{
...
...
@@ -58,8 +86,10 @@ const list = ref([]) // 列表的数据
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
customerId
:
undefined
as
unknown
// 允许 undefined + number
customerId
:
undefined
as
unknown
,
// 允许 undefined + number
businessId
:
undefined
as
unknown
// 允许 undefined + number
})
const
message
=
useMessage
()
/** 查询列表 */
const
getList
=
async
()
=>
{
...
...
@@ -106,6 +136,41 @@ const openDetail = (id: number) => {
push
({
name
:
'CrmContactDetail'
,
params
:
{
id
}
})
}
/** 打开联系人与商机的关联弹窗 */
const
contactModalRef
=
ref
()
const
openBusinessModal
=
()
=>
{
contactModalRef
.
value
.
open
()
}
const
createContactBusinessList
=
async
(
contactIds
:
number
[])
=>
{
const
data
=
{
businessId
:
props
.
bizId
,
contactIds
:
contactIds
}
as
ContactApi
.
ContactBusiness2ReqVO
contactRef
.
value
.
getSelectionRows
().
forEach
((
row
:
ContactApi
.
ContactVO
)
=>
{
data
.
businessIds
.
push
(
row
.
id
)
})
await
ContactApi
.
createContactBusinessList2
(
data
)
// 刷新列表
message
.
success
(
'关联联系人成功'
)
handleQuery
()
}
/** 解除联系人与商机的关联 */
const
contactRef
=
ref
()
const
deleteContactBusinessList
=
async
()
=>
{
const
data
=
{
businessId
:
props
.
bizId
,
contactIds
:
contactRef
.
value
.
getSelectionRows
().
map
((
row
:
ContactApi
.
ContactVO
)
=>
row
.
id
)
}
as
ContactApi
.
ContactBusiness2ReqVO
if
(
data
.
contactIds
.
length
===
0
)
{
return
message
.
error
(
'未选择联系人'
)
}
await
ContactApi
.
deleteContactBusinessList2
(
data
)
// 刷新列表
message
.
success
(
'取关联系人成功'
)
handleQuery
()
}
/** 监听打开的 bizId + bizType,从而加载最新的列表 */
watch
(
()
=>
[
props
.
bizId
,
props
.
bizType
],
...
...
src/views/crm/contract/index.vue
View file @
d9e1ffd5
...
...
@@ -79,7 +79,7 @@
<el-tab-pane
label=
"下属负责的"
name=
"3"
/>
</el-tabs>
<el-table
v-loading=
"loading"
:data=
"list"
:show-overflow-tooltip=
"true"
:stripe=
"true"
>
<el-table-column
align=
"center"
fixed=
"left"
label=
"合同编号"
prop=
"no"
width=
"1
6
0"
/>
<el-table-column
align=
"center"
fixed=
"left"
label=
"合同编号"
prop=
"no"
width=
"1
8
0"
/>
<el-table-column
align=
"center"
fixed=
"left"
label=
"合同名称"
prop=
"name"
width=
"160"
>
<template
#
default=
"scope"
>
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openDetail(scope.row.id)"
>
...
...
src/views/crm/
bi
/rank/ContactsCountRank.vue
→
src/views/crm/
statistics
/rank/ContactsCountRank.vue
View file @
d9e1ffd5
...
...
@@ -18,7 +18,7 @@
</el-card>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
RankApi
,
BiRankRespVO
}
from
'@/api/crm/bi
/rank'
import
{
StatisticsRankApi
,
StatisticsRankRespVO
}
from
'@/api/crm/statistics
/rank'
import
{
EChartsOption
}
from
'echarts'
import
{
clone
}
from
'lodash-es'
...
...
@@ -26,7 +26,7 @@ defineOptions({ name: 'ContactsCountRank' })
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
const
loading
=
ref
(
false
)
// 加载中
const
list
=
ref
<
Bi
RankRespVO
[]
>
([])
// 列表的数据
const
list
=
ref
<
Statistics
RankRespVO
[]
>
([])
// 列表的数据
/** 柱状图配置:横向 */
const
echartsOption
=
reactive
<
EChartsOption
>
({
...
...
@@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({
const
loadData
=
async
()
=>
{
// 1. 加载排行数据
loading
.
value
=
true
const
rankingList
=
await
RankApi
.
getContactsCountRank
(
props
.
queryParams
)
const
rankingList
=
await
Statistics
RankApi
.
getContactsCountRank
(
props
.
queryParams
)
// 2.1 更新 Echarts 数据
if
(
echartsOption
.
dataset
&&
echartsOption
.
dataset
[
'source'
])
{
echartsOption
.
dataset
[
'source'
]
=
clone
(
rankingList
).
reverse
()
...
...
src/views/crm/
bi
/rank/ContractCountRank.vue
→
src/views/crm/
statistics
/rank/ContractCountRank.vue
View file @
d9e1ffd5
...
...
@@ -18,7 +18,7 @@
</el-card>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
RankApi
,
BiRankRespVO
}
from
'@/api/crm/bi
/rank'
import
{
StatisticsRankApi
,
StatisticsRankRespVO
}
from
'@/api/crm/statistics
/rank'
import
{
EChartsOption
}
from
'echarts'
import
{
clone
}
from
'lodash-es'
...
...
@@ -26,7 +26,7 @@ defineOptions({ name: 'ContractCountRank' })
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
const
loading
=
ref
(
false
)
// 加载中
const
list
=
ref
<
Bi
RankRespVO
[]
>
([])
// 列表的数据
const
list
=
ref
<
Statistics
RankRespVO
[]
>
([])
// 列表的数据
/** 柱状图配置:横向 */
const
echartsOption
=
reactive
<
EChartsOption
>
({
...
...
@@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({
const
loadData
=
async
()
=>
{
// 1. 加载排行数据
loading
.
value
=
true
const
rankingList
=
await
RankApi
.
getContractCountRank
(
props
.
queryParams
)
const
rankingList
=
await
Statistics
RankApi
.
getContractCountRank
(
props
.
queryParams
)
// 2.1 更新 Echarts 数据
if
(
echartsOption
.
dataset
&&
echartsOption
.
dataset
[
'source'
])
{
echartsOption
.
dataset
[
'source'
]
=
clone
(
rankingList
).
reverse
()
...
...
src/views/crm/
bi
/rank/ContractPriceRank.vue
→
src/views/crm/
statistics
/rank/ContractPriceRank.vue
View file @
d9e1ffd5
...
...
@@ -18,7 +18,7 @@
</el-card>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
RankApi
,
BiRankRespVO
}
from
'@/api/crm/bi
/rank'
import
{
StatisticsRankApi
,
StatisticsRankRespVO
}
from
'@/api/crm/statistics
/rank'
import
{
EChartsOption
}
from
'echarts'
import
{
clone
}
from
'lodash-es'
...
...
@@ -26,7 +26,7 @@ defineOptions({ name: 'ContractPriceRank' })
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
const
loading
=
ref
(
false
)
// 加载中
const
list
=
ref
<
Bi
RankRespVO
[]
>
([])
// 列表的数据
const
list
=
ref
<
Statistics
RankRespVO
[]
>
([])
// 列表的数据
/** 柱状图配置:横向 */
const
echartsOption
=
reactive
<
EChartsOption
>
({
...
...
@@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({
const
loadData
=
async
()
=>
{
// 1. 加载排行数据
loading
.
value
=
true
const
rankingList
=
await
RankApi
.
getContractPriceRank
(
props
.
queryParams
)
const
rankingList
=
await
Statistics
RankApi
.
getContractPriceRank
(
props
.
queryParams
)
// 2.1 更新 Echarts 数据
if
(
echartsOption
.
dataset
&&
echartsOption
.
dataset
[
'source'
])
{
echartsOption
.
dataset
[
'source'
]
=
clone
(
rankingList
).
reverse
()
...
...
src/views/crm/
bi
/rank/CustomerCountRank.vue
→
src/views/crm/
statistics
/rank/CustomerCountRank.vue
View file @
d9e1ffd5
...
...
@@ -18,7 +18,7 @@
</el-card>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
RankApi
,
BiRankRespVO
}
from
'@/api/crm/bi
/rank'
import
{
StatisticsRankApi
,
StatisticsRankRespVO
}
from
'@/api/crm/statistics
/rank'
import
{
EChartsOption
}
from
'echarts'
import
{
clone
}
from
'lodash-es'
...
...
@@ -26,7 +26,7 @@ defineOptions({ name: 'CustomerCountRank' })
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
const
loading
=
ref
(
false
)
// 加载中
const
list
=
ref
<
Bi
RankRespVO
[]
>
([])
// 列表的数据
const
list
=
ref
<
Statistics
RankRespVO
[]
>
([])
// 列表的数据
/** 柱状图配置:横向 */
const
echartsOption
=
reactive
<
EChartsOption
>
({
...
...
@@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({
const
loadData
=
async
()
=>
{
// 1. 加载排行数据
loading
.
value
=
true
const
rankingList
=
await
RankApi
.
getCustomerCountRank
(
props
.
queryParams
)
const
rankingList
=
await
Statistics
RankApi
.
getCustomerCountRank
(
props
.
queryParams
)
// 2.1 更新 Echarts 数据
if
(
echartsOption
.
dataset
&&
echartsOption
.
dataset
[
'source'
])
{
echartsOption
.
dataset
[
'source'
]
=
clone
(
rankingList
).
reverse
()
...
...
src/views/crm/
bi
/rank/FollowCountRank.vue
→
src/views/crm/
statistics
/rank/FollowCountRank.vue
View file @
d9e1ffd5
...
...
@@ -18,7 +18,7 @@
</el-card>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
RankApi
,
BiRankRespVO
}
from
'@/api/crm/bi
/rank'
import
{
StatisticsRankApi
,
StatisticsRankRespVO
}
from
'@/api/crm/statistics
/rank'
import
{
EChartsOption
}
from
'echarts'
import
{
clone
}
from
'lodash-es'
...
...
@@ -26,7 +26,7 @@ defineOptions({ name: 'FollowCountRank' })
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
const
loading
=
ref
(
false
)
// 加载中
const
list
=
ref
<
Bi
RankRespVO
[]
>
([])
// 列表的数据
const
list
=
ref
<
Statistics
RankRespVO
[]
>
([])
// 列表的数据
/** 柱状图配置:横向 */
const
echartsOption
=
reactive
<
EChartsOption
>
({
...
...
@@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({
const
loadData
=
async
()
=>
{
// 1. 加载排行数据
loading
.
value
=
true
const
rankingList
=
await
RankApi
.
getFollowCountRank
(
props
.
queryParams
)
const
rankingList
=
await
Statistics
RankApi
.
getFollowCountRank
(
props
.
queryParams
)
// 2.1 更新 Echarts 数据
if
(
echartsOption
.
dataset
&&
echartsOption
.
dataset
[
'source'
])
{
echartsOption
.
dataset
[
'source'
]
=
clone
(
rankingList
).
reverse
()
...
...
src/views/crm/
bi
/rank/FollowCustomerCountRank.vue
→
src/views/crm/
statistics
/rank/FollowCustomerCountRank.vue
View file @
d9e1ffd5
...
...
@@ -18,7 +18,7 @@
</el-card>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
RankApi
,
BiRankRespVO
}
from
'@/api/crm/bi
/rank'
import
{
StatisticsRankApi
,
StatisticsRankRespVO
}
from
'@/api/crm/statistics
/rank'
import
{
EChartsOption
}
from
'echarts'
import
{
clone
}
from
'lodash-es'
...
...
@@ -26,7 +26,7 @@ defineOptions({ name: 'FollowCustomerCountRank' })
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
const
loading
=
ref
(
false
)
// 加载中
const
list
=
ref
<
Bi
RankRespVO
[]
>
([])
// 列表的数据
const
list
=
ref
<
Statistics
RankRespVO
[]
>
([])
// 列表的数据
/** 柱状图配置:横向 */
const
echartsOption
=
reactive
<
EChartsOption
>
({
...
...
@@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({
const
loadData
=
async
()
=>
{
// 1. 加载排行数据
loading
.
value
=
true
const
rankingList
=
await
RankApi
.
getFollowCustomerCountRank
(
props
.
queryParams
)
const
rankingList
=
await
Statistics
RankApi
.
getFollowCustomerCountRank
(
props
.
queryParams
)
// 2.1 更新 Echarts 数据
if
(
echartsOption
.
dataset
&&
echartsOption
.
dataset
[
'source'
])
{
echartsOption
.
dataset
[
'source'
]
=
clone
(
rankingList
).
reverse
()
...
...
src/views/crm/
bi
/rank/ProductSalesRank.vue
→
src/views/crm/
statistics
/rank/ProductSalesRank.vue
View file @
d9e1ffd5
...
...
@@ -18,7 +18,7 @@
</el-card>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
RankApi
,
BiRankRespVO
}
from
'@/api/crm/bi
/rank'
import
{
StatisticsRankApi
,
StatisticsRankRespVO
}
from
'@/api/crm/statistics
/rank'
import
{
EChartsOption
}
from
'echarts'
import
{
clone
}
from
'lodash-es'
...
...
@@ -26,7 +26,7 @@ defineOptions({ name: 'ProductSalesRank' })
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
const
loading
=
ref
(
false
)
// 加载中
const
list
=
ref
<
Bi
RankRespVO
[]
>
([])
// 列表的数据
const
list
=
ref
<
Statistics
RankRespVO
[]
>
([])
// 列表的数据
/** 柱状图配置:横向 */
const
echartsOption
=
reactive
<
EChartsOption
>
({
...
...
@@ -80,7 +80,7 @@ const echartsOption = reactive<EChartsOption>({
const
loadData
=
async
()
=>
{
// 1. 加载排行数据
loading
.
value
=
true
const
rankingList
=
await
RankApi
.
getProductSalesRank
(
props
.
queryParams
)
const
rankingList
=
await
Statistics
RankApi
.
getProductSalesRank
(
props
.
queryParams
)
// 2.1 更新 Echarts 数据
if
(
echartsOption
.
dataset
&&
echartsOption
.
dataset
[
'source'
])
{
echartsOption
.
dataset
[
'source'
]
=
clone
(
rankingList
).
reverse
()
...
...
src/views/crm/
bi
/rank/ReceivablePriceRank.vue
→
src/views/crm/
statistics
/rank/ReceivablePriceRank.vue
View file @
d9e1ffd5
...
...
@@ -18,7 +18,7 @@
</el-card>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
RankApi
,
BiRankRespVO
}
from
'@/api/crm/bi
/rank'
import
{
StatisticsRankApi
,
StatisticsRankRespVO
}
from
'@/api/crm/statistics
/rank'
import
{
EChartsOption
}
from
'echarts'
import
{
clone
}
from
'lodash-es'
...
...
@@ -26,7 +26,7 @@ defineOptions({ name: 'ReceivablePriceRank' })
const
props
=
defineProps
<
{
queryParams
:
any
}
>
()
// 搜索参数
const
loading
=
ref
(
false
)
// 加载中
const
list
=
ref
<
Bi
RankRespVO
[]
>
([])
// 列表的数据
const
list
=
ref
<
Statistics
RankRespVO
[]
>
([])
// 列表的数据
/** 柱状图配置:横向 */
const
echartsOption
=
reactive
<
EChartsOption
>
({
...
...
@@ -81,7 +81,7 @@ const echartsOption = reactive<EChartsOption>({
const
loadData
=
async
()
=>
{
// 1. 加载排行数据
loading
.
value
=
true
const
rankingList
=
await
RankApi
.
getReceivablePriceRank
(
props
.
queryParams
)
const
rankingList
=
await
Statistics
RankApi
.
getReceivablePriceRank
(
props
.
queryParams
)
// 2.1 更新 Echarts 数据
if
(
echartsOption
.
dataset
&&
echartsOption
.
dataset
[
'source'
])
{
echartsOption
.
dataset
[
'source'
]
=
clone
(
rankingList
).
reverse
()
...
...
src/views/crm/
bi
/rank/index.vue
→
src/views/crm/
statistics
/rank/index.vue
View file @
d9e1ffd5
...
...
@@ -90,7 +90,7 @@ import * as DeptApi from '@/api/system/dept'
import
{
beginOfDay
,
defaultShortcuts
,
endOfDay
,
formatDate
}
from
'@/utils/formatTime'
import
{
useUserStore
}
from
'@/store/modules/user'
defineOptions
({
name
:
'Crm
Bi
Rank'
})
defineOptions
({
name
:
'Crm
Statistics
Rank'
})
const
queryParams
=
reactive
({
deptId
:
useUserStore
().
getUser
.
deptId
,
...
...
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