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
51518241
authored
Jan 14, 2024
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
crm-客户:公海抽离,完善跟进
parent
d29dfef7
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
411 additions
and
83 deletions
+411
-83
src/api/crm/business/index.ts
+6
-1
src/api/crm/contact/index.ts
+1
-1
src/api/crm/customer/index.ts
+4
-5
src/router/modules/remaining.ts
+4
-2
src/views/crm/contact/ContactForm.vue
+16
-16
src/views/crm/contact/index.vue
+56
-47
src/views/crm/customer/detail/index.vue
+2
-2
src/views/crm/customer/pool/index.vue
+279
-0
src/views/crm/followup/FollowUpRecordForm.vue
+37
-8
src/views/crm/followup/components/ContactList.vue
+6
-1
No files found.
src/api/crm/business/index.ts
View file @
51518241
...
...
@@ -36,6 +36,11 @@ export const getBusiness = async (id: number) => {
return
await
request
.
get
({
url
:
`/crm/business/get?id=`
+
id
})
}
// 获得 CRM 商机列表(精简)
export
const
getSimpleBusinessList
=
async
()
=>
{
return
await
request
.
get
({
url
:
`/crm/business/simple-all-list`
})
}
// 新增 CRM 商机
export
const
createBusiness
=
async
(
data
:
BusinessVO
)
=>
{
return
await
request
.
post
({
url
:
`/crm/business/create`
,
data
})
...
...
@@ -63,5 +68,5 @@ export const getBusinessPageByContact = async (params) => {
// 获得 CRM 商机列表
export
const
getBusinessListByIds
=
async
(
val
:
number
[])
=>
{
return
await
request
.
get
({
url
:
'/crm/business/list-by-ids'
,
params
:
{
ids
:
val
}
})
return
await
request
.
get
({
url
:
'/crm/business/list-by-ids'
,
params
:
{
ids
:
val
.
join
(
','
)
}
})
}
src/api/crm/contact/index.ts
View file @
51518241
...
...
@@ -73,7 +73,7 @@ export const getSimpleContactList = async () => {
// 获得 CRM 联系人列表
export
const
getContactListByIds
=
async
(
val
:
number
[])
=>
{
return
await
request
.
get
({
url
:
'/crm/contact/list-by-ids'
,
params
:
{
ids
:
val
}
})
return
await
request
.
get
({
url
:
'/crm/contact/list-by-ids'
,
params
:
{
ids
:
val
.
join
(
','
)
}
})
}
// 批量新增联系人商机关联
...
...
src/api/crm/customer/index.ts
View file @
51518241
...
...
@@ -64,8 +64,8 @@ export const exportCustomer = async (params: any) => {
}
// 客户列表
export
const
queryAll
List
=
async
()
=>
{
return
await
request
.
get
({
url
:
`/crm/customer/
query-all-list
`
})
export
const
getSimpleCustomer
List
=
async
()
=>
{
return
await
request
.
get
({
url
:
`/crm/customer/
list-all-simple
`
})
}
// 查询客户操作日志
...
...
@@ -80,13 +80,12 @@ export const lockCustomer = async (id: number, lockStatus: boolean) => {
return
await
request
.
put
({
url
:
`/crm/customer/lock`
,
data
:
{
id
,
lockStatus
}
})
}
// TODO @puhui999:方法名,改成和后端一致哈
// 领取公海客户
export
const
receive
=
async
(
ids
:
any
[])
=>
{
export
const
receive
Customer
=
async
(
ids
:
any
[])
=>
{
return
await
request
.
put
({
url
:
'/crm/customer/receive'
,
params
:
{
ids
:
ids
.
join
(
','
)
}
})
}
// 客户放入公海
export
const
putPool
=
async
(
id
:
number
)
=>
{
export
const
put
Customer
Pool
=
async
(
id
:
number
)
=>
{
return
await
request
.
put
({
url
:
`/crm/customer/put-pool?id=
${
id
}
`
})
}
src/router/modules/remaining.ts
View file @
51518241
...
...
@@ -504,7 +504,8 @@ const remainingRouter: AppRouteRecordRaw[] = [
meta
:
{
title
:
'客户详情'
,
noCache
:
true
,
hidden
:
true
hidden
:
true
,
activeMenu
:
'/crm/customer/index'
},
component
:
()
=>
import
(
'@/views/crm/customer/detail/index.vue'
)
},
...
...
@@ -514,7 +515,8 @@ const remainingRouter: AppRouteRecordRaw[] = [
meta
:
{
title
:
'联系人详情'
,
noCache
:
true
,
hidden
:
true
hidden
:
true
,
activeMenu
:
'/crm/contact'
},
component
:
()
=>
import
(
'@/views/crm/contact/detail/index.vue'
)
}
...
...
src/views/crm/contact/ContactForm.vue
View file @
51518241
<
template
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisib
le"
:width=
"820"
>
<Dialog
v-model=
"dialogVisible"
:title=
"dialogTit
le"
:width=
"820"
>
<el-form
ref=
"formRef"
v-loading=
"formLoading"
:model=
"formData"
:rules=
"formRules"
label-width=
"110px"
v-loading=
"formLoading"
>
<el-row
:gutter=
"20"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"姓名"
prop=
"name"
>
<el-input
input-style=
"width:190px;"
v-model=
"formData.name
"
placeholder=
"请输入姓名"
/>
<el-input
v-model=
"formData.name"
input-style=
"width:190px;
"
placeholder=
"请输入姓名"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"负责人"
prop=
"ownerUserId"
>
<el-select
v-model=
"formData.ownerUserId"
lable-key=
"nickname"
placeholder=
"请选择负责人"
value-key=
"id"
lable-key=
"nickname"
>
<el-option
v-for=
"item in userList"
...
...
@@ -36,9 +36,9 @@
<el-form-item
label=
"客户名称"
prop=
"customerName"
>
<el-select
v-model=
"formData.customerId"
lable-key=
"name"
placeholder=
"请选择客户"
value-key=
"id"
lable-key=
"name"
>
<el-option
v-for=
"item in customerList"
...
...
@@ -66,8 +66,8 @@
<el-col
:span=
"12"
>
<el-form-item
label=
"手机号"
prop=
"mobile"
>
<el-input
input-style=
"width:190px;"
v-model=
"formData.mobile"
input-style=
"width:190px;"
placeholder=
"请输入手机号"
/>
</el-form-item>
...
...
@@ -82,8 +82,8 @@
<el-col
:span=
"12"
>
<el-form-item
label=
"邮箱"
prop=
"email"
>
<el-input
input-style=
"width:190px;"
v-model=
"formData.email"
input-style=
"width:190px;"
placeholder=
"请输入邮箱"
/>
</el-form-item>
...
...
@@ -98,8 +98,8 @@
<el-col
:span=
"12"
>
<el-form-item
label=
"微信"
prop=
"wechat"
>
<el-input
input-style=
"width:190px;"
v-model=
"formData.wechat"
input-style=
"width:190px;"
placeholder=
"请输入微信"
/>
</el-form-item>
...
...
@@ -108,9 +108,9 @@
<el-form-item
label=
"下次联系时间"
prop=
"contactNextTime"
>
<el-date-picker
v-model=
"formData.contactNextTime"
placeholder=
"选择下次联系时间"
type=
"datetime"
value-format=
"x"
placeholder=
"选择下次联系时间"
/>
</el-form-item>
</el-col>
...
...
@@ -129,8 +129,8 @@
<el-col
:span=
"12"
>
<el-form-item
label=
"地址"
prop=
"detailAddress"
>
<el-input
input-style=
"width:190px;"
v-model=
"formData.detailAddress"
input-style=
"width:190px;"
placeholder=
"请输入地址"
/>
</el-form-item>
...
...
@@ -143,16 +143,16 @@
<el-option
v-for=
"item in allContactList"
:key=
"item.id"
:disabled=
"item.id == formData.id"
:label=
"item.name"
:value=
"item.id"
:disabled=
"item.id == formData.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"职位"
prop=
"post"
>
<el-input
input-style=
"width:190px;"
v-model=
"formData.post
"
placeholder=
"请输入职位"
/>
<el-input
v-model=
"formData.post"
input-style=
"width:190px;
"
placeholder=
"请输入职位"
/>
</el-form-item>
</el-col>
</el-row>
...
...
@@ -180,14 +180,14 @@
</el-row>
</el-form>
<template
#
footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading
"
>
确 定
</el-button>
<el-button
:disabled=
"formLoading"
type=
"primary"
@
click=
"submitForm
"
>
确 定
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
*
as
ContactApi
from
'@/api/crm/contact'
import
{
DICT_TYPE
,
get
IntDictOptions
,
getBool
DictOptions
}
from
'@/utils/dict'
import
{
DICT_TYPE
,
get
BoolDictOptions
,
getInt
DictOptions
}
from
'@/utils/dict'
import
*
as
UserApi
from
'@/api/system/user'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
*
as
AreaApi
from
'@/api/system/area'
...
...
@@ -242,7 +242,7 @@ const open = async (type: string, id?: number) => {
resetForm
()
allContactList
.
value
=
await
ContactApi
.
getSimpleContactList
()
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
customerList
.
value
=
await
CustomerApi
.
queryAll
List
()
customerList
.
value
=
await
CustomerApi
.
getSimpleCustomer
List
()
areaList
.
value
=
await
AreaApi
.
getAreaTree
()
// 修改时,设置数据
if
(
id
)
{
...
...
src/views/crm/contact/index.vue
View file @
51518241
...
...
@@ -2,21 +2,21 @@
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
:model=
"queryParams"
class=
"-mb-15px"
label-width=
"68px"
>
<el-form-item
label=
"客户"
prop=
"customerId"
>
<el-select
v-model=
"queryParams.customerId"
class=
"!w-240px"
clearable
lable-key=
"name"
placeholder=
"请选择客户"
value-key=
"id"
lable-key=
"name"
@
keyup
.
enter=
"handleQuery"
clearable
>
<el-option
v-for=
"item in customerList"
...
...
@@ -30,8 +30,8 @@
<el-input
v-model=
"queryParams.name"
class=
"!w-240px"
placeholder=
"请输入姓名"
clearable
placeholder=
"请输入姓名"
@
keyup
.
enter=
"handleQuery"
/>
</el-form-item>
...
...
@@ -39,8 +39,8 @@
<el-input
v-model=
"queryParams.mobile"
class=
"!w-240px"
placeholder=
"请输入手机号"
clearable
placeholder=
"请输入手机号"
@
keyup
.
enter=
"handleQuery"
/>
</el-form-item>
...
...
@@ -48,8 +48,8 @@
<el-input
v-model=
"queryParams.telephone"
class=
"!w-240px"
placeholder=
"请输入电话"
clearable
placeholder=
"请输入电话"
@
keyup
.
enter=
"handleQuery"
/>
</el-form-item>
...
...
@@ -57,8 +57,8 @@
<el-input
v-model=
"queryParams.qq"
class=
"!w-240px"
placeholder=
"请输入QQ"
clearable
placeholder=
"请输入QQ"
@
keyup
.
enter=
"handleQuery"
/>
</el-form-item>
...
...
@@ -66,8 +66,8 @@
<el-input
v-model=
"queryParams.wechat"
class=
"!w-240px"
placeholder=
"请输入微信"
clearable
placeholder=
"请输入微信"
@
keyup
.
enter=
"handleQuery"
/>
</el-form-item>
...
...
@@ -75,25 +75,33 @@
<el-input
v-model=
"queryParams.email"
class=
"!w-240px"
placeholder=
"请输入电子邮箱"
clearable
placeholder=
"请输入电子邮箱"
@
keyup
.
enter=
"handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button
@
click=
"handleQuery"
>
<Icon
icon=
"ep:search"
class=
"mr-5px"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
>
<Icon
icon=
"ep:refresh"
class=
"mr-5px"
/>
重置
</el-button>
<el-button
type=
"primary"
@
click=
"openForm('create')"
v-hasPermi=
"['crm:contact:create']"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
新增
<el-button
@
click=
"handleQuery"
>
<Icon
class=
"mr-5px"
icon=
"ep:search"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
>
<Icon
class=
"mr-5px"
icon=
"ep:refresh"
/>
重置
</el-button>
<el-button
v-hasPermi=
"['crm:contact:create']"
type=
"primary"
@
click=
"openForm('create')"
>
<Icon
class=
"mr-5px"
icon=
"ep:plus"
/>
新增
</el-button>
<el-button
type=
"success"
v-hasPermi=
"['crm:contact:export']"
:loading=
"exportLoading"
plain
type=
"success"
@
click=
"handleExport"
:loading=
"exportLoading"
v-hasPermi=
"['crm:contact:export']"
>
<Icon
icon=
"ep:download"
class=
"mr-5px"
/>
导出
<Icon
class=
"mr-5px"
icon=
"ep:download"
/>
导出
</el-button>
</el-form-item>
</el-form>
...
...
@@ -101,30 +109,30 @@
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:s
tripe=
"true"
:show-overflow-tooltip
=
"true"
>
<el-table-column
label=
"姓名"
fixed=
"left"
align=
"center
"
prop=
"name"
width=
"140"
>
<el-table
v-loading=
"loading"
:data=
"list"
:s
how-overflow-tooltip=
"true"
:stripe
=
"true"
>
<el-table-column
align=
"center"
fixed=
"left"
label=
"姓名
"
prop=
"name"
width=
"140"
>
<template
#
default=
"scope"
>
<el-link
type=
"primary"
:underline=
"false
"
@
click=
"openDetail(scope.row.id)"
>
<el-link
:underline=
"false"
type=
"primary
"
@
click=
"openDetail(scope.row.id)"
>
{{
scope
.
row
.
name
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
label=
"客户名称"
fixed=
"left"
align=
"center
"
prop=
"customerName"
width=
"120"
>
<el-table-column
align=
"center"
fixed=
"left"
label=
"客户名称
"
prop=
"customerName"
width=
"120"
>
<
template
#
default=
"scope"
>
<el-link
type=
"primary"
:underline=
"false"
type=
"primary"
@
click=
"openCustomerDetail(scope.row.customerId)"
>
{{
scope
.
row
.
customerName
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
label=
"手机"
align=
"center
"
prop=
"mobile"
width=
"120"
/>
<el-table-column
label=
"电话"
align=
"center
"
prop=
"telephone"
width=
"120"
/>
<el-table-column
label=
"邮箱"
align=
"center
"
prop=
"email"
width=
"120"
/>
<el-table-column
label=
"职位"
align=
"center
"
prop=
"post"
width=
"120"
/>
<el-table-column
label=
"地址"
align=
"center
"
prop=
"detailAddress"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"手机
"
prop=
"mobile"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"电话
"
prop=
"telephone"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"邮箱
"
prop=
"email"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"职位
"
prop=
"post"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"地址
"
prop=
"detailAddress"
width=
"120"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
...
...
@@ -132,56 +140,56 @@
prop=
"contactNextTime"
width=
"180px"
/>
<el-table-column
label=
"备注"
align=
"center
"
prop=
"remark"
/>
<el-table-column
label=
"关键决策人"
align=
"center
"
prop=
"master"
width=
"100"
>
<el-table-column
align=
"center"
label=
"备注
"
prop=
"remark"
/>
<el-table-column
align=
"center"
label=
"关键决策人
"
prop=
"master"
width=
"100"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.INFRA_BOOLEAN_STRING"
:value=
"scope.row.master"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"直属上级"
align=
"center
"
prop=
"parentName"
width=
"140"
/>
<el-table-column
align=
"center"
label=
"直属上级
"
prop=
"parentName"
width=
"140"
/>
<el-table-column
label=
"最后跟进时间
"
:formatter=
"dateFormatter
"
align=
"center"
label=
"最后跟进时间"
prop=
"contactLastTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"性别"
align=
"center
"
prop=
"sex"
>
<el-table-column
align=
"center"
label=
"性别
"
prop=
"sex"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.SYSTEM_USER_SEX"
:value=
"scope.row.sex"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"负责人"
align=
"center
"
prop=
"ownerUserName"
width=
"120"
/>
<el-table-column
label=
"创建人"
align=
"center
"
prop=
"creatorName"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"负责人
"
prop=
"ownerUserName"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"创建人
"
prop=
"creatorName"
width=
"120"
/>
<el-table-column
label=
"更新时间
"
:formatter=
"dateFormatter
"
align=
"center"
label=
"更新时间"
prop=
"updateTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"创建时间
"
:formatter=
"dateFormatter
"
align=
"center"
label=
"创建时间"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"操作"
align=
"center"
fixed=
"right
"
width=
"200"
>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作
"
width=
"200"
>
<
template
#
default=
"scope"
>
<el-button
v-hasPermi=
"['crm:contact:update']"
link
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['crm:contact:update']"
>
编辑
</el-button>
<el-button
v-hasPermi=
"['crm:contact:delete']"
link
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['crm:contact:delete']"
>
删除
</el-button>
...
...
@@ -190,9 +198,9 @@
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
v-model:page=
"queryParams.pageNo"
:total=
"total"
@
pagination=
"getList"
/>
</ContentWrap>
...
...
@@ -201,7 +209,7 @@
<ContactForm
ref=
"formRef"
@
success=
"getList"
/>
</template>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
download
from
'@/utils/download'
import
*
as
ContactApi
from
'@/api/crm/contact'
...
...
@@ -295,6 +303,7 @@ const { push } = useRouter()
const
openDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmContactDetail'
,
params
:
{
id
}
})
}
/** 打开客户详情 */
const
openCustomerDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmCustomerDetail'
,
params
:
{
id
}
})
...
...
@@ -303,6 +312,6 @@ const openCustomerDetail = (id: number) => {
/** 初始化 **/
onMounted
(
async
()
=>
{
await
getList
()
customerList
.
value
=
await
CustomerApi
.
queryAll
List
()
customerList
.
value
=
await
CustomerApi
.
getSimpleCustomer
List
()
})
</
script
>
src/views/crm/customer/detail/index.vue
View file @
51518241
...
...
@@ -113,7 +113,7 @@ const handleUnlock = async () => {
/** 领取客户 */
const
handleReceive
=
async
()
=>
{
await
message
.
confirm
(
`确定领取客户【
${
customer
.
value
.
name
}
】 吗?`
)
await
CustomerApi
.
receive
([
unref
(
customerId
.
value
)])
await
CustomerApi
.
receive
Customer
([
unref
(
customerId
.
value
)])
message
.
success
(
`领取客户【
${
customer
.
value
.
name
}
】成功`
)
await
getCustomer
()
}
...
...
@@ -121,7 +121,7 @@ const handleReceive = async () => {
/** 客户放入公海 */
const
handlePutPool
=
async
()
=>
{
await
message
.
confirm
(
`确定将客户【
${
customer
.
value
.
name
}
】放入公海吗?`
)
await
CustomerApi
.
putPool
(
unref
(
customerId
.
value
))
await
CustomerApi
.
put
Customer
Pool
(
unref
(
customerId
.
value
))
message
.
success
(
`客户【
${
customer
.
value
.
name
}
】放入公海成功`
)
close
()
}
...
...
src/views/crm/customer/pool/index.vue
0 → 100644
View file @
51518241
<
template
>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
ref=
"queryFormRef"
:inline=
"true"
:model=
"queryParams"
class=
"-mb-15px"
label-width=
"68px"
>
<el-form-item
label=
"客户名称"
prop=
"name"
>
<el-input
v-model=
"queryParams.name"
class=
"!w-240px"
clearable
placeholder=
"请输入客户名称"
@
keyup
.
enter=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"手机"
prop=
"mobile"
>
<el-input
v-model=
"queryParams.mobile"
class=
"!w-240px"
clearable
placeholder=
"请输入手机"
@
keyup
.
enter=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"所属行业"
prop=
"industryId"
>
<el-select
v-model=
"queryParams.industryId"
class=
"!w-240px"
clearable
placeholder=
"请选择所属行业"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"客户等级"
prop=
"level"
>
<el-select
v-model=
"queryParams.level"
class=
"!w-240px"
clearable
placeholder=
"请选择客户等级"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"客户来源"
prop=
"source"
>
<el-select
v-model=
"queryParams.source"
class=
"!w-240px"
clearable
placeholder=
"请选择客户来源"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
@
click=
"handleQuery"
>
<Icon
class=
"mr-5px"
icon=
"ep:search"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery(undefined)"
>
<Icon
class=
"mr-5px"
icon=
"ep:refresh"
/>
重置
</el-button>
<el-button
v-hasPermi=
"['crm:customer:export']"
:loading=
"exportLoading"
plain
type=
"success"
@
click=
"handleExport"
>
<Icon
class=
"mr-5px"
icon=
"ep:download"
/>
导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:show-overflow-tooltip=
"true"
:stripe=
"true"
>
<el-table-column
align=
"center"
label=
"编号"
prop=
"id"
/>
<el-table-column
align=
"center"
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=
"mobile"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"电话"
prop=
"telephone"
width=
"120"
/>
<el-table-column
align=
"center"
label=
"客户来源"
prop=
"source"
width=
"100"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.CRM_CUSTOMER_SOURCE"
:value=
"scope.row.source"
/>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"所属行业"
prop=
"industryId"
width=
"120"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.CRM_CUSTOMER_INDUSTRY"
:value=
"scope.row.industryId"
/>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"客户等级"
prop=
"level"
width=
"120"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.CRM_CUSTOMER_LEVEL"
:value=
"scope.row.level"
/>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"网址"
prop=
"website"
width=
"200"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"下次联系时间"
prop=
"contactNextTime"
width=
"180px"
/>
<el-table-column
align=
"center"
label=
"备注"
prop=
"remark"
width=
"200"
/>
<el-table-column
align=
"center"
label=
"成交状态"
prop=
"dealStatus"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.INFRA_BOOLEAN_STRING"
:value=
"scope.row.dealStatus"
/>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"距离进入公海"
prop=
"poolDay"
>
<
template
#
default=
"scope"
>
{{
scope
.
row
.
poolDay
}}
天
</
template
>
</el-table-column>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"最后跟进时间"
prop=
"contactLastTime"
width=
"180px"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"创建时间"
prop=
"updateTime"
width=
"180px"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"创建时间"
prop=
"createTime"
width=
"180px"
/>
<el-table-column
align=
"center"
label=
"负责人"
prop=
"ownerUserName"
width=
"100px"
/>
<el-table-column
align=
"center"
label=
"所属部门"
prop=
"ownerUserDeptName"
width=
"100px"
/>
<el-table-column
align=
"center"
label=
"创建人"
prop=
"creatorName"
width=
"100px"
/>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
min-width=
"150"
>
<
template
#
default=
"scope"
>
<el-link
:underline=
"false"
type=
"primary"
@
click=
"openDetail(scope.row.id)"
>
详情
</el-link>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit=
"queryParams.pageSize"
v-model:page=
"queryParams.pageNo"
:total=
"total"
@
pagination=
"getList"
/>
</ContentWrap>
</template>
<
script
lang=
"ts"
setup
>
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
download
from
'@/utils/download'
import
*
as
CustomerApi
from
'@/api/crm/customer'
defineOptions
({
name
:
'CrmCustomer'
})
const
message
=
useMessage
()
// 消息弹窗
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
const
list
=
ref
([])
// 列表的数据
const
queryParams
=
ref
({
pageNo
:
1
,
pageSize
:
10
,
name
:
''
,
mobile
:
''
,
industryId
:
undefined
,
level
:
undefined
,
source
:
undefined
,
sceneType
:
undefined
,
pool
:
true
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
CustomerApi
.
getCustomerPage
(
queryParams
.
value
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
value
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
queryParams
.
value
=
{
pageNo
:
1
,
pageSize
:
10
,
name
:
''
,
mobile
:
''
,
industryId
:
undefined
,
level
:
undefined
,
source
:
undefined
,
sceneType
:
undefined
,
pool
:
true
}
handleQuery
()
}
/** 打开客户详情 */
const
{
currentRoute
,
push
}
=
useRouter
()
const
openDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmCustomerDetail'
,
params
:
{
id
}
})
}
/** 导出按钮操作 */
const
handleExport
=
async
()
=>
{
try
{
// 导出的二次确认
await
message
.
exportConfirm
()
// 发起导出
exportLoading
.
value
=
true
const
data
=
await
CustomerApi
.
exportCustomer
(
queryParams
.
value
)
download
.
excel
(
data
,
'客户.xls'
)
}
catch
{
}
finally
{
exportLoading
.
value
=
false
}
}
/** 监听路由变化更新列表 */
watch
(
()
=>
currentRoute
.
value
,
()
=>
{
getList
()
}
)
/** 初始化 **/
onMounted
(()
=>
{
getList
()
})
</
script
>
src/views/crm/followup/FollowUpRecordForm.vue
View file @
51518241
...
...
@@ -37,21 +37,43 @@
</el-col>
<el-col
:span=
"24"
>
<el-form-item
label=
"关联联系人"
prop=
"contactIds"
>
<el-button
@
click=
"submitForm"
>
<Icon
class=
"mr-5px"
icon=
"ep:plus"
/>
选择添加联系人
</el-button>
<el-select
v-model=
"formData.contactIds"
multiple
placeholder=
"请选择"
>
<el-option
v-for=
"item in allContactList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
<contact-list
v-model:contactIds=
"formData.contactIds"
/>
</el-form-item>
<!--
<el-form-item
label=
"关联联系人"
prop=
"contactIds"
>
-->
<!--
<el-button
@
click=
"handleAddContact"
>
-->
<!--
<Icon
class=
"mr-5px"
icon=
"ep:plus"
/>
-->
<!-- 选择添加联系人-->
<!--
</el-button>
-->
<!--
<contact-list
v-model:contactIds=
"formData.contactIds"
/>
-->
<!--
</el-form-item>
-->
</el-col>
<el-col
:span=
"24"
>
<el-form-item
label=
"关联商机"
prop=
"businessIds"
>
<el-button
@
click=
"submitForm"
>
<Icon
class=
"mr-5px"
icon=
"ep:plus"
/>
选择添加商机
</el-button>
<el-select
v-model=
"formData.businessIds"
multiple
placeholder=
"请选择"
>
<el-option
v-for=
"item in allBusinessList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
<business-list
v-model:businessIds=
"formData.businessIds"
/>
</el-form-item>
<!--
<el-form-item
label=
"关联商机"
prop=
"businessIds"
>
-->
<!--
<el-button
@
click=
"handleAddBusiness"
>
-->
<!--
<Icon
class=
"mr-5px"
icon=
"ep:plus"
/>
-->
<!-- 选择添加商机-->
<!--
</el-button>
-->
<!--
<business-list
v-model:businessIds=
"formData.businessIds"
/>
-->
<!--
</el-form-item>
-->
</el-col>
</el-row>
</el-form>
...
...
@@ -65,6 +87,8 @@
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
FollowUpRecordApi
,
FollowUpRecordVO
}
from
'@/api/crm/followup'
import
{
BusinessList
,
ContactList
}
from
'./components'
import
*
as
ContactApi
from
'@/api/crm/contact'
import
*
as
BusinessApi
from
'@/api/crm/business'
/** 跟进记录 表单 */
defineOptions
({
name
:
'FollowUpRecordForm'
})
...
...
@@ -82,7 +106,10 @@ const formRules = reactive({
content
:
[{
required
:
true
,
message
:
'跟进内容不能为空'
,
trigger
:
'blur'
}],
nextTime
:
[{
required
:
true
,
message
:
'下次联系时间不能为空'
,
trigger
:
'blur'
}]
})
const
formRef
=
ref
()
// 表单 Ref
const
allContactList
=
ref
<
ContactApi
.
ContactVO
[]
>
([])
// 所有联系人列表
const
allBusinessList
=
ref
<
BusinessApi
.
BusinessVO
[]
>
([])
// 所有商家列表
/** 打开弹窗 */
const
open
=
async
(
bizType
:
number
,
bizId
:
number
,
type
:
string
,
id
?:
number
)
=>
{
...
...
@@ -92,6 +119,8 @@ const open = async (bizType: number, bizId: number, type: string, id?: number) =
resetForm
()
formData
.
value
.
bizType
=
bizType
formData
.
value
.
bizId
=
bizId
allContactList
.
value
=
await
ContactApi
.
getSimpleContactList
()
allBusinessList
.
value
=
await
BusinessApi
.
getSimpleBusinessList
()
// 修改时,设置数据
if
(
id
)
{
formLoading
.
value
=
true
...
...
src/views/crm/followup/components/ContactList.vue
View file @
51518241
...
...
@@ -67,13 +67,18 @@ const props = withDefaults(defineProps<{ contactIds: number[] }>(), {
contactIds
:
()
=>
[]
})
const
list
=
ref
<
ContactApi
.
ContactVO
[]
>
([]
as
ContactApi
.
ContactVO
[])
const
getContactList
=
async
()
=>
{
list
.
value
=
(
await
ContactApi
.
getContactListByIds
(
props
.
contactIds
))
as
unknown
as
ContactApi
.
ContactVO
[]
}
watch
(
()
=>
props
.
contactIds
,
(
val
)
=>
{
if
(
!
val
||
val
.
length
===
0
)
{
return
}
list
.
value
=
ContactApi
.
getContactListByIds
(
val
)
as
unknown
as
ContactApi
.
ContactVO
[]
getContactList
()
}
)
const
emits
=
defineEmits
<
{
...
...
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