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
08bb022c
authored
Feb 20, 2024
by
YunaiV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
✨
CRM:完善联系人的编辑、详情
parent
094b1925
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
193 additions
and
213 deletions
+193
-213
src/api/crm/contact/index.ts
+28
-23
src/views/crm/clue/detail/index.vue
+1
-1
src/views/crm/contact/ContactForm.vue
+101
-119
src/views/crm/contact/detail/ContactDetailsHeader.vue
+4
-10
src/views/crm/contact/detail/ContactDetailsInfo.vue
+27
-38
src/views/crm/contact/detail/index.vue
+18
-12
src/views/crm/contact/index.vue
+14
-10
No files found.
src/api/crm/contact/index.ts
View file @
08bb022c
...
@@ -2,29 +2,34 @@ import request from '@/config/axios'
...
@@ -2,29 +2,34 @@ import request from '@/config/axios'
import
{
TransferReqVO
}
from
'@/api/crm/customer'
import
{
TransferReqVO
}
from
'@/api/crm/customer'
export
interface
ContactVO
{
export
interface
ContactVO
{
name
:
string
id
:
number
// 编号
nextTime
:
Date
name
:
string
// 联系人名称
mobile
:
string
customerId
:
number
// 客户编号
telephone
:
string
customerName
?:
string
// 客户名称
email
:
string
contactLastTime
:
Date
// 最后跟进时间
post
:
string
contactLastContent
:
string
// 最后跟进内容
customerId
:
number
contactNextTime
:
Date
// 下次联系时间
detailAddress
:
string
ownerUserId
:
number
// 负责人的用户编号
remark
:
string
ownerUserName
?:
string
// 负责人的用户名称
ownerUserId
:
string
ownerUserDept
?:
string
// 负责人的部门名称
lastTime
:
Date
mobile
:
string
// 手机号
id
:
number
telephone
:
string
// 电话
parentId
:
number
qq
:
string
// QQ
qq
:
number
wechat
:
string
// wechat
wechat
:
string
email
:
string
// email
sex
:
number
areaId
:
number
// 所在地
master
:
boolean
areaName
?:
string
// 所在地名称
creatorName
:
string
detailAddress
:
string
// 详细地址
updateTime
?:
Date
sex
:
number
// 性别
createTime
?:
Date
master
:
boolean
// 是否主联系人
customerName
:
string
post
:
string
// 职务
areaName
:
string
parentId
:
number
// 上级联系人编号
ownerUserName
:
string
parentName
?:
string
// 上级联系人名称
remark
:
string
// 备注
creator
:
string
// 创建人
creatorName
?:
string
// 创建人名称
createTime
:
Date
// 创建时间
updateTime
:
Date
// 更新时间
}
}
export
interface
ContactBusinessReqVO
{
export
interface
ContactBusinessReqVO
{
...
...
src/views/crm/clue/detail/index.vue
View file @
08bb022c
...
@@ -33,7 +33,7 @@
...
@@ -33,7 +33,7 @@
ref=
"permissionListRef"
ref=
"permissionListRef"
:biz-id=
"clue.id!"
:biz-id=
"clue.id!"
:biz-type=
"BizTypeEnum.CRM_CLUE"
:biz-type=
"BizTypeEnum.CRM_CLUE"
:show-action=
"
!permissionListRef?.isPool || fals
e"
:show-action=
"
tru
e"
@
quit-team=
"close"
@
quit-team=
"close"
/>
/>
</el-tab-pane>
</el-tab-pane>
...
...
src/views/crm/contact/ContactForm.vue
View file @
08bb022c
<
template
>
<
template
>
<Dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
:width=
"820"
>
<Dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
>
<el-form
<el-form
ref=
"formRef"
ref=
"formRef"
v-loading=
"formLoading"
v-loading=
"formLoading"
:model=
"formData"
:model=
"formData"
:rules=
"formRules"
:rules=
"formRules"
label-width=
"1
1
0px"
label-width=
"1
0
0px"
>
>
<el-row
:gutter=
"20"
>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"姓名"
prop=
"name"
>
<el-form-item
label=
"
联系人
姓名"
prop=
"name"
>
<el-input
v-model=
"formData.name"
input-style=
"width:190px;"
placeholder=
"请输入姓名"
/>
<el-input
v-model=
"formData.name"
placeholder=
"请输入姓名"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"负责人"
prop=
"ownerUserId"
>
<el-form-item
label=
"负责人"
prop=
"ownerUserId"
>
<el-select
<el-select
v-model=
"formData.ownerUserId"
v-model=
"formData.ownerUserId"
lable-key=
"nickname"
:disabled=
"formType !== 'create'"
placeholder=
"请选择负责人"
class=
"w-1/1"
value-key=
"id"
>
>
<el-option
<el-option
v-for=
"item in user
List
"
v-for=
"item in user
Options
"
:key=
"item.id"
:key=
"item.id"
:label=
"item.nickname"
:label=
"item.nickname"
:value=
"item.id"
:value=
"item.id"
...
@@ -33,13 +32,8 @@
...
@@ -33,13 +32,8 @@
</el-row>
</el-row>
<el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"客户名称"
prop=
"customerName"
>
<el-form-item
label=
"客户名称"
prop=
"customerId"
>
<el-select
<el-select
v-model=
"formData.customerId"
placeholder=
"请选择客户"
class=
"w-1/1"
>
v-model=
"formData.customerId"
lable-key=
"name"
placeholder=
"请选择客户"
value-key=
"id"
>
<el-option
<el-option
v-for=
"item in customerList"
v-for=
"item in customerList"
:key=
"item.id"
:key=
"item.id"
...
@@ -50,98 +44,73 @@
...
@@ -50,98 +44,73 @@
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"性别"
prop=
"sex"
>
<el-form-item
label=
"手机"
prop=
"mobile"
>
<el-select
v-model=
"formData.sex"
placeholder=
"请选择"
>
<el-input
v-model=
"formData.mobile"
placeholder=
"请输入手机"
/>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
<el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"手机号"
prop=
"mobile"
>
<el-form-item
label=
"电话"
prop=
"telephone"
>
<el-input
<el-input
v-model=
"formData.telephone"
placeholder=
"请输入电话"
/>
v-model=
"formData.mobile"
input-style=
"width:190px;"
placeholder=
"请输入手机号"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"
电话"
prop=
"telephone
"
>
<el-form-item
label=
"
邮箱"
prop=
"email
"
>
<el-input
v-model=
"formData.
telephone"
placeholder=
"请输入电话"
style=
"width: 215px
"
/>
<el-input
v-model=
"formData.
email"
placeholder=
"请输入邮箱
"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
<el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"邮箱"
prop=
"email"
>
<el-form-item
label=
"微信"
prop=
"wechat"
>
<el-input
<el-input
v-model=
"formData.wechat"
placeholder=
"请输入微信"
/>
v-model=
"formData.email"
input-style=
"width:190px;"
placeholder=
"请输入邮箱"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"QQ"
prop=
"qq"
>
<el-form-item
label=
"QQ"
prop=
"qq"
>
<el-input
v-model=
"formData.qq"
placeholder=
"请输入
QQ"
style=
"width: 215px
"
/>
<el-input
v-model=
"formData.qq"
placeholder=
"请输入
QQ
"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
<el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"微信"
prop=
"wechat"
>
<el-form-item
label=
"职位"
prop=
"post"
>
<el-input
<el-input
v-model=
"formData.post"
placeholder=
"请输入职位"
/>
v-model=
"formData.wechat"
input-style=
"width:190px;"
placeholder=
"请输入微信"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"下次联系时间"
prop=
"contactNextTime"
>
<el-form-item
label=
"关键决策人"
prop=
"master"
style=
"width: 400px"
>
<el-date-picker
<el-radio-group
v-model=
"formData.master"
>
v-model=
"formData.contactNextTime"
<el-radio
placeholder=
"选择下次联系时间"
v-for=
"dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
type=
"datetime"
:key=
"dict.value"
value-format=
"x"
:label=
"dict.value"
/>
>
{{
dict
.
label
}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
<el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"所在地"
prop=
"areaId"
>
<el-form-item
label=
"性别"
prop=
"sex"
>
<el-tree-select
<el-select
v-model=
"formData.sex"
placeholder=
"请选择"
class=
"w-1/1"
>
v-model=
"formData.areaId"
<el-option
:data=
"areaList"
v-for=
"dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:props=
"defaultProps"
:key=
"dict.value"
:render-after-expand=
"true"
:label=
"dict.label"
/>
:value=
"dict.value"
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"地址"
prop=
"detailAddress"
>
<el-input
v-model=
"formData.detailAddress"
input-style=
"width:190px;"
placeholder=
"请输入地址"
/>
/>
</el-select>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"直属上级"
prop=
"parentId"
>
<el-form-item
label=
"直属上级"
prop=
"parentId"
>
<el-select
v-model=
"formData.parentId"
placeholder=
"请选择"
>
<el-select
v-model=
"formData.parentId"
placeholder=
"请选择
直属上级"
class=
"w-1/1
"
>
<el-option
<el-option
v-for=
"item in
allC
ontactList"
v-for=
"item in
c
ontactList"
:key=
"item.id"
:key=
"item.id"
:disabled=
"item.id == formData.id"
:disabled=
"item.id == formData.id"
:label=
"item.name"
:label=
"item.name"
...
@@ -150,31 +119,41 @@
...
@@ -150,31 +119,41 @@
</el-select>
</el-select>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"职位"
prop=
"post"
>
<el-form-item
label=
"地址"
prop=
"areaId"
>
<el-input
v-model=
"formData.post"
input-style=
"width:190px;"
placeholder=
"请输入职位"
/>
<el-cascader
v-model=
"formData.areaId"
:options=
"areaList"
:props=
"defaultProps"
class=
"w-1/1"
clearable
filterable
placeholder=
"请选择城市"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"关键决策人"
prop=
"master"
style=
"width: 400px"
>
<el-form-item
label=
"详细地址"
prop=
"detailAddress"
>
<el-radio-group
v-model=
"formData.master"
>
<el-input
v-model=
"formData.detailAddress"
placeholder=
"请输入详细地址"
/>
<el-radio
v-for=
"dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
:key=
"dict.value"
:label=
"dict.value"
>
{{
dict
.
label
}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
<el-row>
<el-row>
<el-col
:span=
"24"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"下次联系时间"
prop=
"contactNextTime"
>
<el-date-picker
v-model=
"formData.contactNextTime"
placeholder=
"选择下次联系时间"
type=
"datetime"
value-format=
"x"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"备注"
prop=
"remark"
>
<el-form-item
label=
"备注"
prop=
"remark"
>
<el-input
v-model=
"formData.remark"
placeholder=
"请输入备注"
/>
<el-input
type=
"textarea"
v-model=
"formData.remark"
placeholder=
"请输入备注"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
</el-row>
</el-row>
...
@@ -192,6 +171,7 @@ import * as UserApi from '@/api/system/user'
...
@@ -192,6 +171,7 @@ import * as UserApi from '@/api/system/user'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
*
as
AreaApi
from
'@/api/system/area'
import
*
as
AreaApi
from
'@/api/system/area'
import
{
defaultProps
}
from
'@/utils/tree'
import
{
defaultProps
}
from
'@/utils/tree'
import
{
useUserStore
}
from
'@/store/modules/user'
const
{
t
}
=
useI18n
()
// 国际化
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
message
=
useMessage
()
// 消息弹窗
...
@@ -202,25 +182,23 @@ const formLoading = ref(false) // 表单的加载中:1)修改时的数据加
...
@@ -202,25 +182,23 @@ const formLoading = ref(false) // 表单的加载中:1)修改时的数据加
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
areaList
=
ref
([])
// 地区列表
const
areaList
=
ref
([])
// 地区列表
const
formData
=
ref
({
const
formData
=
ref
({
id
:
undefined
,
name
:
undefined
,
customerId
:
undefined
,
contactNextTime
:
undefined
,
contactNextTime
:
undefined
,
ownerUserId
:
0
,
mobile
:
undefined
,
mobile
:
undefined
,
telephone
:
undefined
,
telephone
:
undefined
,
email
:
undefined
,
customerId
:
undefined
,
customerName
:
undefined
,
detailAddress
:
undefined
,
remark
:
undefined
,
ownerUserId
:
undefined
,
lastTime
:
undefined
,
id
:
undefined
,
parentId
:
undefined
,
name
:
undefined
,
post
:
undefined
,
qq
:
undefined
,
qq
:
undefined
,
wechat
:
undefined
,
wechat
:
undefined
,
email
:
undefined
,
areaId
:
undefined
,
detailAddress
:
undefined
,
sex
:
undefined
,
sex
:
undefined
,
master
:
false
,
master
:
false
,
areaId
:
undefined
post
:
undefined
,
parentId
:
undefined
,
remark
:
undefined
})
})
const
formRules
=
reactive
({
const
formRules
=
reactive
({
name
:
[{
required
:
true
,
message
:
'姓名不能为空'
,
trigger
:
'blur'
}],
name
:
[{
required
:
true
,
message
:
'姓名不能为空'
,
trigger
:
'blur'
}],
...
@@ -229,10 +207,10 @@ const formRules = reactive({
...
@@ -229,10 +207,10 @@ const formRules = reactive({
})
})
const
formRef
=
ref
()
// 表单 Ref
const
formRef
=
ref
()
// 表单 Ref
const
ownerUserList
=
ref
<
any
[]
>
([])
const
ownerUserList
=
ref
<
any
[]
>
([])
const
user
List
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
const
user
Options
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
// TODO 芋艿:统一的客户选择面板
// TODO 芋艿:统一的客户选择面板
const
customerList
=
ref
<
CustomerApi
.
CustomerVO
[]
>
([])
// 客户列表
const
customerList
=
ref
<
CustomerApi
.
CustomerVO
[]
>
([])
// 客户列表
const
allContactList
=
ref
<
ContactApi
.
ContactVO
[]
>
([])
// 所有
联系人列表
const
contactList
=
ref
<
ContactApi
.
ContactVO
[]
>
([])
//
联系人列表
/** 打开弹窗 */
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
...
@@ -240,10 +218,6 @@ const open = async (type: string, id?: number) => {
...
@@ -240,10 +218,6 @@ const open = async (type: string, id?: number) => {
dialogTitle
.
value
=
t
(
'action.'
+
type
)
dialogTitle
.
value
=
t
(
'action.'
+
type
)
formType
.
value
=
type
formType
.
value
=
type
resetForm
()
resetForm
()
allContactList
.
value
=
await
ContactApi
.
getSimpleContactList
()
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
customerList
.
value
=
await
CustomerApi
.
getCustomerSimpleList
()
areaList
.
value
=
await
AreaApi
.
getAreaTree
()
// 修改时,设置数据
// 修改时,设置数据
if
(
id
)
{
if
(
id
)
{
formLoading
.
value
=
true
formLoading
.
value
=
true
...
@@ -253,13 +227,22 @@ const open = async (type: string, id?: number) => {
...
@@ -253,13 +227,22 @@ const open = async (type: string, id?: number) => {
formLoading
.
value
=
false
formLoading
.
value
=
false
}
}
}
}
contactList
.
value
=
await
ContactApi
.
getSimpleContactList
()
customerList
.
value
=
await
CustomerApi
.
getCustomerSimpleList
()
// 获得地区列表
areaList
.
value
=
await
AreaApi
.
getAreaTree
()
// 获得用户列表
userOptions
.
value
=
await
UserApi
.
getSimpleUserList
()
// 默认新建时选中自己
if
(
formType
.
value
===
'create'
)
{
formData
.
value
.
ownerUserId
=
useUserStore
().
getUser
.
id
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
const
submitForm
=
async
()
=>
{
// owerSelectValue(ownerUserList)
// 校验表单
// 校验表单
if
(
!
formRef
)
return
if
(
!
formRef
)
return
const
valid
=
await
formRef
.
value
.
validate
()
const
valid
=
await
formRef
.
value
.
validate
()
...
@@ -285,25 +268,24 @@ const submitForm = async () => {
...
@@ -285,25 +268,24 @@ const submitForm = async () => {
/** 重置表单 */
/** 重置表单 */
const
resetForm
=
()
=>
{
const
resetForm
=
()
=>
{
// TODO zyna:ide 告警,看看怎么去掉哈;
formData
.
value
=
{
formData
.
value
=
{
id
:
undefined
,
name
:
undefined
,
customerId
:
undefined
,
contactNextTime
:
undefined
,
contactNextTime
:
undefined
,
ownerUserId
:
0
,
mobile
:
undefined
,
mobile
:
undefined
,
telephone
:
undefined
,
telephone
:
undefined
,
email
:
undefined
,
customerId
:
undefined
,
detailAddress
:
undefined
,
remark
:
undefined
,
ownerUserId
:
undefined
,
lastTime
:
undefined
,
id
:
undefined
,
parentId
:
undefined
,
name
:
undefined
,
post
:
undefined
,
qq
:
undefined
,
qq
:
undefined
,
wechat
:
undefined
,
wechat
:
undefined
,
email
:
undefined
,
areaId
:
undefined
,
detailAddress
:
undefined
,
sex
:
undefined
,
sex
:
undefined
,
master
:
false
master
:
false
,
post
:
undefined
,
parentId
:
undefined
,
remark
:
undefined
}
}
formRef
.
value
?.
resetFields
()
formRef
.
value
?.
resetFields
()
ownerUserList
.
value
=
[]
ownerUserList
.
value
=
[]
...
...
src/views/crm/contact/detail/ContactDetailsHeader.vue
View file @
08bb022c
...
@@ -16,17 +16,11 @@
...
@@ -16,17 +16,11 @@
</div>
</div>
<ContentWrap
class=
"mt-10px"
>
<ContentWrap
class=
"mt-10px"
>
<el-descriptions
:column=
"5"
direction=
"vertical"
>
<el-descriptions
:column=
"5"
direction=
"vertical"
>
<el-descriptions-item
label=
"客户"
>
<el-descriptions-item
label=
"客户名称"
>
{{
contact
.
customerName
}}
</el-descriptions-item>
{{
contact
.
customerName
}}
<el-descriptions-item
label=
"职务"
>
{{
contact
.
post
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"手机"
>
{{
contact
.
mobile
}}
</el-descriptions-item>
<el-descriptions-item
label=
"职务"
>
{{
contact
.
post
}}
</el-descriptions-item>
<el-descriptions-item
label=
"手机"
>
{{
contact
.
mobile
}}
</el-descriptions-item>
<el-descriptions-item
label=
"创建时间"
>
<el-descriptions-item
label=
"创建时间"
>
{{
contact
.
createTime
?
formatDate
(
contact
.
createTime
)
:
'空'
}}
{{
formatDate
(
contact
.
createTime
)
}}
</el-descriptions-item>
</el-descriptions-item>
</el-descriptions>
</el-descriptions>
</ContentWrap>
</ContentWrap>
...
...
src/views/crm/contact/detail/ContactDetailsInfo.vue
View file @
08bb022c
...
@@ -6,60 +6,49 @@
...
@@ -6,60 +6,49 @@
<span
class=
"text-base font-bold"
>
基本信息
</span>
<span
class=
"text-base font-bold"
>
基本信息
</span>
</
template
>
</
template
>
<el-descriptions
:column=
"4"
>
<el-descriptions
:column=
"4"
>
<el-descriptions-item
label=
"姓名"
>
<el-descriptions-item
label=
"姓名"
>
{{ contact.name }}
</el-descriptions-item>
{{ contact.name }}
<el-descriptions-item
label=
"客户名称"
>
{{ contact.customerName }}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"手机"
>
{{ contact.mobile }}
</el-descriptions-item>
<el-descriptions-item
label=
"客户"
>
<el-descriptions-item
label=
"电话"
>
{{ contact.telephone }}
</el-descriptions-item>
{{ contact.customerName }}
<el-descriptions-item
label=
"邮箱"
>
{{ contact.email }}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"QQ"
>
{{ contact.qq }}
</el-descriptions-item>
<el-descriptions-item
label=
"手机"
>
<el-descriptions-item
label=
"微信"
>
{{ contact.wechat }}
</el-descriptions-item>
{{ contact.mobile }}
<el-descriptions-item
label=
"地址"
>
</el-descriptions-item>
{{ contact.areaName }} {{ contact.detailAddress }}
<el-descriptions-item
label=
"座机"
>
</el-descriptions-item>
{{ contact.telephone }}
<el-descriptions-item
label=
"职务"
>
{{ contact.post }}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"直属上级"
>
{{ contact.parentName }}
</el-descriptions-item>
<el-descriptions-item
label=
"邮箱"
>
<el-descriptions-item
label=
"关键决策人"
>
{{ contact.email }}
<dict-tag
:type=
"DICT_TYPE.INFRA_BOOLEAN_STRING"
:value=
"contact.master"
/>
</el-descriptions-item>
<el-descriptions-item
label=
"QQ"
>
{{ contact.qq }}
</el-descriptions-item>
<el-descriptions-item
label=
"微信"
>
{{ contact.wechat }}
</el-descriptions-item>
<el-descriptions-item
label=
"下次联系时间"
>
{{ contact.nextTime ? formatDate(contact.nextTime) : '空' }}
</el-descriptions-item>
<el-descriptions-item
label=
"所在地"
>
{{ contact.areaName }}
</el-descriptions-item>
<el-descriptions-item
label=
"详细地址"
>
{{ contact.detailAddress }}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"性别"
>
<el-descriptions-item
label=
"性别"
>
<dict-tag
:type=
"DICT_TYPE.SYSTEM_USER_SEX"
:value=
"contact.sex"
/>
<dict-tag
:type=
"DICT_TYPE.SYSTEM_USER_SEX"
:value=
"contact.sex"
/>
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"
备注
"
>
<el-descriptions-item
label=
"
下次联系时间
"
>
{{
contact.remark
}}
{{
formatDate(contact.contactNextTime)
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"备注"
>
{{ contact.remark }}
</el-descriptions-item>
</el-descriptions>
</el-descriptions>
</el-collapse-item>
</el-collapse-item>
<el-collapse-item
name=
"systemInfo"
>
<el-collapse-item
name=
"systemInfo"
>
<
template
#
title
>
<
template
#
title
>
<span
class=
"text-base font-bold"
>
系统信息
</span>
<span
class=
"text-base font-bold"
>
系统信息
</span>
</
template
>
</
template
>
<el-descriptions
:column=
"2"
>
<el-descriptions
:column=
"4"
>
<el-descriptions-item
label=
"负责人"
>
<el-descriptions-item
label=
"负责人"
>
{{ contact.ownerUserName }}
</el-descriptions-item>
{{ contact.ownerUserName }}
<el-descriptions-item
label=
"最后跟进记录"
>
{{ contact.contactLastContent }}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"
创建人
"
>
<el-descriptions-item
label=
"
最后跟进时间
"
>
{{
contact.creatorName
}}
{{
formatDate(contact.contactLastTime)
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
""
>
</el-descriptions-item>
<el-descriptions-item
label=
"创建人"
>
{{ contact.creatorName }}
</el-descriptions-item>
<el-descriptions-item
label=
"创建时间"
>
<el-descriptions-item
label=
"创建时间"
>
{{
contact.createTime ? formatDate(contact.createTime) : '空'
}}
{{
formatDate(contact.createTime)
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"更新时间"
>
<el-descriptions-item
label=
"更新时间"
>
{{
contact.updateTime ? formatDate(contact.updateTime) : '空'
}}
{{
formatDate(contact.updateTime)
}}
</el-descriptions-item>
</el-descriptions-item>
</el-descriptions>
</el-descriptions>
</el-collapse-item>
</el-collapse-item>
...
...
src/views/crm/contact/detail/index.vue
View file @
08bb022c
...
@@ -9,6 +9,9 @@
...
@@ -9,6 +9,9 @@
</ContactDetailsHeader>
</ContactDetailsHeader>
<el-col>
<el-col>
<el-tabs>
<el-tabs>
<el-tab-pane
label=
"跟进记录"
>
<FollowUpList
:biz-id=
"contactId"
:biz-type=
"BizTypeEnum.CRM_CONTACT"
/>
</el-tab-pane>
<el-tab-pane
label=
"详细资料"
>
<el-tab-pane
label=
"详细资料"
>
<ContactDetailsInfo
:contact=
"contact"
/>
<ContactDetailsInfo
:contact=
"contact"
/>
</el-tab-pane>
</el-tab-pane>
...
@@ -20,7 +23,7 @@
...
@@ -20,7 +23,7 @@
ref=
"permissionListRef"
ref=
"permissionListRef"
:biz-id=
"contact.id!"
:biz-id=
"contact.id!"
:biz-type=
"BizTypeEnum.CRM_CONTACT"
:biz-type=
"BizTypeEnum.CRM_CONTACT"
:show-action=
"
!permissionListRef?.isPool || fals
e"
:show-action=
"
tru
e"
@
quit-team=
"close"
@
quit-team=
"close"
/>
/>
</el-tab-pane>
</el-tab-pane>
...
@@ -34,8 +37,8 @@
...
@@ -34,8 +37,8 @@
</el-tabs>
</el-tabs>
</el-col>
</el-col>
<!-- 表单弹窗:添加/修改 -->
<!-- 表单弹窗:添加/修改 -->
<ContactForm
ref=
"formRef"
@
success=
"getContact
Data
(contact.id)"
/>
<ContactForm
ref=
"formRef"
@
success=
"getContact(contact.id)"
/>
<CrmTransferForm
ref=
"
crmT
ransferFormRef"
@
success=
"close"
/>
<CrmTransferForm
ref=
"
t
ransferFormRef"
@
success=
"close"
/>
</
template
>
</
template
>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
...
@@ -49,18 +52,19 @@ import { OperateLogV2VO } from '@/api/system/operatelog'
...
@@ -49,18 +52,19 @@ import { OperateLogV2VO } from '@/api/system/operatelog'
import
{
getOperateLogPage
}
from
'@/api/crm/operateLog'
import
{
getOperateLogPage
}
from
'@/api/crm/operateLog'
import
ContactForm
from
'@/views/crm/contact/ContactForm.vue'
import
ContactForm
from
'@/views/crm/contact/ContactForm.vue'
import
CrmTransferForm
from
'@/views/crm/permission/components/TransferForm.vue'
import
CrmTransferForm
from
'@/views/crm/permission/components/TransferForm.vue'
import
FollowUpList
from
'@/views/crm/followup/index.vue'
defineOptions
({
name
:
'CrmContactDetail'
})
defineOptions
({
name
:
'CrmContactDetail'
})
const
route
=
useRoute
()
const
message
=
useMessage
()
const
message
=
useMessage
()
const
id
=
Number
(
route
.
params
.
id
)
// 联系人编号
const
contactId
=
ref
(
0
)
// 线索编号
const
loading
=
ref
(
true
)
// 加载中
const
loading
=
ref
(
true
)
// 加载中
const
contact
=
ref
<
ContactApi
.
ContactVO
>
({}
as
ContactApi
.
ContactVO
)
// 联系人详情
const
contact
=
ref
<
ContactApi
.
ContactVO
>
({}
as
ContactApi
.
ContactVO
)
// 联系人详情
const
permissionListRef
=
ref
<
InstanceType
<
typeof
PermissionList
>>
()
// 团队成员列表 Ref
const
permissionListRef
=
ref
<
InstanceType
<
typeof
PermissionList
>>
()
// 团队成员列表 Ref
/** 获取详情 */
/** 获取详情 */
const
getContact
Data
=
async
(
id
:
number
)
=>
{
const
getContact
=
async
(
id
:
number
)
=>
{
loading
.
value
=
true
loading
.
value
=
true
try
{
try
{
contact
.
value
=
await
ContactApi
.
getContact
(
id
)
contact
.
value
=
await
ContactApi
.
getContact
(
id
)
...
@@ -77,9 +81,9 @@ const openForm = (type: string, id?: number) => {
...
@@ -77,9 +81,9 @@ const openForm = (type: string, id?: number) => {
}
}
/** 联系人转移 */
/** 联系人转移 */
const
crmT
ransferFormRef
=
ref
<
InstanceType
<
typeof
CrmTransferForm
>>
()
// 联系人转移表单 ref
const
t
ransferFormRef
=
ref
<
InstanceType
<
typeof
CrmTransferForm
>>
()
// 联系人转移表单 ref
const
transfer
=
()
=>
{
const
transfer
=
()
=>
{
crmT
ransferFormRef
.
value
?.
open
(
'联系人转移'
,
contact
.
value
.
id
,
ContactApi
.
transferContact
)
t
ransferFormRef
.
value
?.
open
(
'联系人转移'
,
contact
.
value
.
id
,
ContactApi
.
transferContact
)
}
}
/** 获取操作日志 */
/** 获取操作日志 */
...
@@ -96,19 +100,21 @@ const getOperateLog = async (contactId: number) => {
...
@@ -96,19 +100,21 @@ const getOperateLog = async (contactId: number) => {
}
}
/** 关闭窗口 */
/** 关闭窗口 */
const
{
delView
}
=
useTagsViewStore
()
// 视图操作
const
{
currentRoute
}
=
useRouter
()
// 路由
const
close
=
()
=>
{
const
close
=
()
=>
{
delView
(
unref
(
currentRoute
))
delView
(
unref
(
currentRoute
))
}
}
/** 初始化 */
/** 初始化 */
const
{
delView
}
=
useTagsViewStore
()
// 视图操作
const
{
params
}
=
useRoute
()
const
{
currentRoute
}
=
useRouter
()
// 路由
onMounted
(
async
()
=>
{
onMounted
(
async
()
=>
{
if
(
!
id
)
{
if
(
!
params
.
id
)
{
message
.
warning
(
'参数错误,联系人不能为空!'
)
message
.
warning
(
'参数错误,联系人不能为空!'
)
close
()
close
()
return
return
}
}
await
getContactData
(
id
)
contactId
.
value
=
params
.
id
as
unknown
as
number
await
getContact
(
contactId
.
value
)
})
})
</
script
>
</
script
>
src/views/crm/contact/index.vue
View file @
08bb022c
...
@@ -53,15 +53,6 @@
...
@@ -53,15 +53,6 @@
@
keyup
.
enter=
"handleQuery"
@
keyup
.
enter=
"handleQuery"
/>
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"QQ"
prop=
"qq"
>
<el-input
v-model=
"queryParams.qq"
class=
"!w-240px"
clearable
placeholder=
"请输入QQ"
@
keyup
.
enter=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"微信"
prop=
"wechat"
>
<el-form-item
label=
"微信"
prop=
"wechat"
>
<el-input
<el-input
v-model=
"queryParams.wechat"
v-model=
"queryParams.wechat"
...
@@ -109,6 +100,11 @@
...
@@ -109,6 +100,11 @@
<!-- 列表 -->
<!-- 列表 -->
<ContentWrap>
<ContentWrap>
<el-tabs
v-model=
"activeName"
@
tab-click=
"handleTabClick"
>
<el-tab-pane
label=
"我负责的"
name=
"1"
/>
<el-tab-pane
label=
"我参与的"
name=
"2"
/>
<el-tab-pane
label=
"下属负责的"
name=
"3"
/>
</el-tabs>
<el-table
v-loading=
"loading"
:data=
"list"
:show-overflow-tooltip=
"true"
:stripe=
"true"
>
<el-table
v-loading=
"loading"
:data=
"list"
:show-overflow-tooltip=
"true"
:stripe=
"true"
>
<el-table-column
align=
"center"
fixed=
"left"
label=
"联系人姓名"
prop=
"name"
width=
"160"
>
<el-table-column
align=
"center"
fixed=
"left"
label=
"联系人姓名"
prop=
"name"
width=
"160"
>
<template
#
default=
"scope"
>
<template
#
default=
"scope"
>
...
@@ -224,6 +220,7 @@ import * as ContactApi from '@/api/crm/contact'
...
@@ -224,6 +220,7 @@ import * as ContactApi from '@/api/crm/contact'
import
ContactForm
from
'./ContactForm.vue'
import
ContactForm
from
'./ContactForm.vue'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
{
TabsPaneContext
}
from
'element-plus'
defineOptions
({
name
:
'CrmContact'
})
defineOptions
({
name
:
'CrmContact'
})
...
@@ -237,16 +234,17 @@ const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
...
@@ -237,16 +234,17 @@ const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
const
queryParams
=
reactive
({
const
queryParams
=
reactive
({
pageNo
:
1
,
pageNo
:
1
,
pageSize
:
10
,
pageSize
:
10
,
sceneType
:
'1'
,
// 默认和 activeName 相等
mobile
:
undefined
,
mobile
:
undefined
,
telephone
:
undefined
,
telephone
:
undefined
,
email
:
undefined
,
email
:
undefined
,
customerId
:
undefined
,
customerId
:
undefined
,
name
:
undefined
,
name
:
undefined
,
qq
:
undefined
,
wechat
:
undefined
wechat
:
undefined
})
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
const
exportLoading
=
ref
(
false
)
// 导出的加载中
const
activeName
=
ref
(
'1'
)
// 列表 tab
/** 查询列表 */
/** 查询列表 */
const
getList
=
async
()
=>
{
const
getList
=
async
()
=>
{
...
@@ -272,6 +270,12 @@ const resetQuery = () => {
...
@@ -272,6 +270,12 @@ const resetQuery = () => {
handleQuery
()
handleQuery
()
}
}
/** tab 切换 */
const
handleTabClick
=
(
tab
:
TabsPaneContext
)
=>
{
queryParams
.
sceneType
=
tab
.
paneName
handleQuery
()
}
/** 添加/修改操作 */
/** 添加/修改操作 */
const
formRef
=
ref
()
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
...
...
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