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
Unverified
Commit
038f3d6a
authored
Nov 27, 2023
by
芋道源码
Committed by
Gitee
Nov 27, 2023
Browse files
Options
Browse Files
Download
Plain Diff
!335 crm联系人review修改
Merge pull request !335 from zyna/master
parents
8aa17b67
46a8755c
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
133 additions
and
289 deletions
+133
-289
src/api/crm/contact/index.ts
+8
-6
src/api/crm/customer/index.ts
+5
-0
src/views/crm/contact/ContactForm.vue
+89
-202
src/views/crm/contact/detail/ContactDetails.vue
+15
-25
src/views/crm/contact/detail/index.vue
+7
-22
src/views/crm/contact/index.vue
+9
-34
No files found.
src/api/crm/contact/index.ts
View file @
038f3d6a
/*
/*
* @Author: zyna
* @Author: zyna
* @Date: 2023-11-05 13:34:41
* @Date: 2023-11-05 13:34:41
* @LastEditTime: 2023-11-
11 16:20:19
* @LastEditTime: 2023-11-
26 20:47:04
* @FilePath: \yudao-ui-admin-vue3\src\api\crm\contact\index.ts
* @FilePath: \yudao-ui-admin-vue3\src\api\crm\contact\index.ts
* @Description:
* @Description:
*/
*/
...
@@ -22,13 +22,15 @@ export interface ContactVO {
...
@@ -22,13 +22,15 @@ export interface ContactVO {
id
:
number
id
:
number
parentId
:
number
parentId
:
number
qq
:
number
qq
:
number
we
b
chat
:
string
wechat
:
string
sex
:
number
sex
:
number
policyMakers
:
boolean
master
:
boolean
creatorName
:
string
creatorName
:
string
updateTime
?:
Date
updateTime
?:
Date
createTime
?:
Date
createTime
?:
Date
customerName
:
string
customerName
:
string
,
areaName
:
string
,
ownerUserName
:
string
}
}
// 查询crm联系人列表
// 查询crm联系人列表
...
@@ -60,6 +62,6 @@ export const deleteContact = async (id: number) => {
...
@@ -60,6 +62,6 @@ export const deleteContact = async (id: number) => {
export
const
exportContact
=
async
(
params
)
=>
{
export
const
exportContact
=
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/crm/contact/export-excel`
,
params
})
return
await
request
.
download
({
url
:
`/crm/contact/export-excel`
,
params
})
}
}
export
const
simpleAll
l
ist
=
async
()
=>
{
export
const
simpleAll
L
ist
=
async
()
=>
{
return
await
request
.
get
({
url
:
`/crm/contact/simple
All
list`
})
return
await
request
.
get
({
url
:
`/crm/contact/simple
-all-
list`
})
}
}
src/api/crm/customer/index.ts
View file @
038f3d6a
...
@@ -62,3 +62,7 @@ export const deleteCustomer = async (id: number) => {
...
@@ -62,3 +62,7 @@ export const deleteCustomer = async (id: number) => {
export
const
exportCustomer
=
async
(
params
)
=>
{
export
const
exportCustomer
=
async
(
params
)
=>
{
return
await
request
.
download
({
url
:
`/crm/customer/export-excel`
,
params
})
return
await
request
.
download
({
url
:
`/crm/customer/export-excel`
,
params
})
}
}
//客户列表
export
const
queryAllList
=
async
()
=>
{
return
await
request
.
get
({
url
:
`/crm/customer/query-all-list`
})
}
\ No newline at end of file
src/views/crm/contact/ContactForm.vue
View file @
038f3d6a
<
template
>
<
template
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
:width=
"800"
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisible"
:width=
"820"
>
<el-form
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"110px"
v-loading=
"formLoading"
>
ref=
"formRef"
<el-row
:gutter=
"20"
>
:model=
"formData"
<el-col
:span=
"12"
>
:rules=
"formRules"
label-width=
"130px"
v-loading=
"formLoading"
:inline=
"true"
>
<el-form-item
label=
"姓名"
prop=
"name"
>
<el-form-item
label=
"姓名"
prop=
"name"
>
<el-input
v-model=
"formData.name"
placeholder=
"请输入姓名"
/>
<el-input
input-style=
"width:190px;"
v-model=
"formData.name"
placeholder=
"请输入姓名"
/>
</el-form-item>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"负责人"
prop=
"ownerUserId"
>
<el-form-item
label=
"负责人"
prop=
"ownerUserId"
>
<el-select
<el-select
v-model=
"formData.ownerUserId"
placeholder=
"请选择负责人"
value-key=
"id"
lable-key=
"nickname"
>
v-model=
"ownerUserList"
<el-option
v-for=
"item in userList"
:key=
"item.id"
:label=
"item.nickname"
:value=
"item.id"
/>
placeholder=
"请选择负责人"
multiple
value-key=
"id"
lable-key=
"nickname"
@
click=
"openOwerForm('open')"
>
<el-option
v-for=
"item in ownerUserList"
:key=
"item.id"
:label=
"item.nickname"
:value=
"item"
/>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
<!-- TODO 芋艿:封装成一个组件 -->
<el-form-item
label=
"客户名称"
prop=
"customerName"
>
<el-popover
placement=
"bottom"
:width=
"600"
trigger=
"click"
:teleported=
"false"
:visible=
"showCustomer"
:offset=
"10"
>
<template
#
reference
>
<el-input
placeholder=
"请选择"
@
click=
"openCustomerSelect"
v-model=
"formData.customerName"
/>
</
template
>
<el-table
:data=
"list"
ref=
"multipleTableRef"
@
select=
"handleSelectionChange"
>
<el-table-column
label=
"选择"
type=
"selection"
width=
"55"
/>
<el-table-column
width=
"100"
property=
"id"
label=
"编号"
/>
<el-table-column
width=
"150"
property=
"name"
label=
"客户名称"
/>
<el-table-column
label=
"客户来源"
align=
"center"
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
label=
"客户等级"
align=
"center"
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>
<!-- 分页 -->
<el-row
:gutter=
"20"
>
<el-col>
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
layout=
"sizes, prev, pager, next"
/>
</el-col>
</el-col>
</el-row>
</el-row>
<el-row
:gutter=
"20"
>
<el-row>
<el-col
:span=
"10"
:offset=
"13"
>
<el-col
:span=
"12"
>
<el-button
@
click=
"selectCustomer"
>
确认
</el-button>
<el-form-item
label=
"客户名称"
prop=
"customerName"
>
<el-button
@
click=
"showCustomer = false"
>
取消
</el-button>
<el-select
v-model=
"formData.customerId"
placeholder=
"请选择客户"
value-key=
"id"
lable-key=
"name"
>
</el-col>
<el-option
v-for=
"item in customerList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-row>
</el-select>
</el-popover>
</el-form-item>
</el-form-item>
<el-form-item
label=
"性别"
prop=
"sex"
>
</el-col>
<el-col
:span=
"12"
><el-form-item
label=
"性别"
prop=
"sex"
>
<el-select
v-model=
"formData.sex"
placeholder=
"请选择"
>
<el-select
v-model=
"formData.sex"
placeholder=
"请选择"
>
<el-option
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
v-for=
"dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:key=
"dict.value"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-select>
</el-form-item>
</el-form-item></el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"手机号"
prop=
"mobile"
>
<el-form-item
label=
"手机号"
prop=
"mobile"
>
<el-input
v-model=
"formData.mobile"
placeholder=
"请输入手机号"
/>
<el-input
input-style=
"width:190px;"
v-model=
"formData.mobile"
placeholder=
"请输入手机号"
/>
</el-form-item>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"座机"
prop=
"telephone"
>
<el-form-item
label=
"座机"
prop=
"telephone"
>
<el-input
v-model=
"formData.telephone"
placeholder=
"请输入座机"
style=
"width: 215px"
/>
<el-input
v-model=
"formData.telephone"
placeholder=
"请输入座机"
style=
"width: 215px"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"邮箱"
prop=
"email"
>
<el-form-item
label=
"邮箱"
prop=
"email"
>
<el-input
v-model=
"formData.email"
placeholder=
"请输入邮箱"
/>
<el-input
input-style=
"width:190px;"
v-model=
"formData.email"
placeholder=
"请输入邮箱"
/>
</el-form-item>
</el-form-item>
</el-col>
<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"
style=
"width: 215px"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"微信"
prop=
"webchat"
>
</el-col>
<el-input
v-model=
"formData.webchat"
placeholder=
"请输入微信"
/>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"微信"
prop=
"wechat"
>
<el-input
input-style=
"width:190px;"
v-model=
"formData.wechat"
placeholder=
"请输入微信"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"下次联系时间"
prop=
"nextTime"
>
</el-col>
<el-date-picker
<el-col
:span=
"12"
>
<el-form-item
label=
"下次联系时间"
prop=
"nextTime"
>
v-model=
"formData.nextTime"
<el-date-picker
v-model=
"formData.nextTime"
type=
"date"
value-format=
"x"
placeholder=
"选择下次联系时间"
/>
type=
"date"
value-format=
"x"
placeholder=
"选择下次联系时间"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"所在地"
prop=
"areaId"
>
<el-tree-select
v-model=
"formData.areaId"
:data=
"areaList"
:props=
"defaultProps"
:render-after-expand=
"true"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"地址"
prop=
"address"
>
<el-form-item
label=
"地址"
prop=
"address"
>
<el-input
v-model=
"formData.address"
placeholder=
"请输入地址"
/>
<el-input
input-style=
"width:190px;"
v-model=
"formData.address"
placeholder=
"请输入地址"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-row><el-row>
<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=
"请选择"
>
<el-option
<el-option
v-for=
"item in allContactList"
v-for=
"item in allContactList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
:key=
"item.id"
:disabled=
"item.id == formData.id"
/>
:label=
"item.name"
:value=
"item.id"
:disabled=
"item.id == formData.id"
/>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
</el-col>
<el-form-item
label=
"职位"
prop=
"post"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"职位"
prop=
"post"
>
<el-input
v-model=
"formData.post"
placeholder=
"请输入职位"
/>
<el-input
input-style=
"width:190px;"
v-model=
"formData.post"
placeholder=
"请输入职位"
/>
</el-form-item>
</el-form-item>
</el-col>
<el-form-item
label=
"是否关键决策人"
prop=
"policyMakers"
style=
"width: 400px"
>
</el-row><el-row>
<el-radio-group
v-model=
"formData.policyMakers"
>
<el-col
:span=
"12"
><el-form-item
label=
"是否关键决策人"
prop=
"master"
style=
"width: 400px"
>
<el-radio-group
v-model=
"formData.master"
>
<el-radio
<el-radio
v-for=
"dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
v-for=
"dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
:key=
"dict.value"
:key=
"dict.value"
:label=
"dict.value"
>
:label=
"dict.value"
>
{{
dict
.
label
}}
{{
dict
.
label
}}
</el-radio>
</el-radio>
</el-radio-group>
</el-radio-group>
</el-form-item>
</el-form-item>
<el-form-item
label=
"备注"
prop=
"remark"
>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
><el-form-item
label=
"备注"
prop=
"remark"
>
<el-input
v-model=
"formData.remark"
placeholder=
"请输入备注"
/>
<el-input
v-model=
"formData.remark"
placeholder=
"请输入备注"
/>
</el-form-item>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-form>
<template
#
footer
>
<template
#
footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</
template
>
</Dialog>
</Dialog>
<OwerSelect
ref=
"owerRef"
@
confirmOwerSelect=
"owerSelectValue"
:initOwerUser=
"formData.ownerUserId"
/>
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
*
as
ContactApi
from
'@/api/crm/contact'
import
*
as
ContactApi
from
'@/api/crm/contact'
import
{
DICT_TYPE
,
getIntDictOptions
,
getBoolDictOptions
}
from
'@/utils/dict'
import
{
DICT_TYPE
,
getIntDictOptions
,
getBoolDictOptions
}
from
'@/utils/dict'
import
OwerSelect
from
'./OwerSelect.vue'
import
*
as
UserApi
from
'@/api/system/user'
import
*
as
UserApi
from
'@/api/system/user'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
{
ElTable
}
from
'element-plus'
import
{
ElTable
}
from
'element-plus'
import
*
as
AreaApi
from
'@/api/system/area'
import
{
defaultProps
}
from
'@/utils/tree'
const
{
t
}
=
useI18n
()
// 国际化
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
message
=
useMessage
()
// 消息弹窗
...
@@ -172,6 +133,7 @@ const dialogVisible = ref(false) // 弹窗的是否展示
...
@@ -172,6 +133,7 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const
dialogTitle
=
ref
(
''
)
// 弹窗的标题
const
dialogTitle
=
ref
(
''
)
// 弹窗的标题
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
areaList
=
ref
([])
// 地区列表
const
formData
=
ref
({
const
formData
=
ref
({
nextTime
:
undefined
,
nextTime
:
undefined
,
mobile
:
undefined
,
mobile
:
undefined
,
...
@@ -188,21 +150,10 @@ const formData = ref({
...
@@ -188,21 +150,10 @@ const formData = ref({
name
:
undefined
,
name
:
undefined
,
post
:
undefined
,
post
:
undefined
,
qq
:
undefined
,
qq
:
undefined
,
we
b
chat
:
undefined
,
wechat
:
undefined
,
sex
:
undefined
,
sex
:
undefined
,
policyMakers
:
undefined
master
:
false
,
})
areaId
:
undefined
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
const
list
=
ref
([])
// 列表的数据
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
name
:
null
,
mobile
:
null
,
industryId
:
null
,
level
:
null
,
source
:
null
})
})
const
formRules
=
reactive
({
const
formRules
=
reactive
({
name
:
[{
required
:
true
,
message
:
'姓名不能为空'
,
trigger
:
'blur'
}],
name
:
[{
required
:
true
,
message
:
'姓名不能为空'
,
trigger
:
'blur'
}],
...
@@ -212,56 +163,33 @@ const formRules = reactive({
...
@@ -212,56 +163,33 @@ const formRules = reactive({
const
formRef
=
ref
()
// 表单 Ref
const
formRef
=
ref
()
// 表单 Ref
const
ownerUserList
=
ref
<
any
[]
>
([])
const
ownerUserList
=
ref
<
any
[]
>
([])
const
userList
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
const
userList
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
const
customerList
=
ref
<
CustomerApi
.
CustomerVO
[]
>
([])
// 客户列表
const
allContactList
=
ref
([])
// 所有联系人列表
/** 打开弹窗 */
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
dialogVisible
.
value
=
true
dialogTitle
.
value
=
t
(
'action.'
+
type
)
dialogTitle
.
value
=
t
(
'action.'
+
type
)
formType
.
value
=
type
formType
.
value
=
type
allContactList
.
value
=
await
ContactApi
.
simpleAlllist
()
resetForm
()
resetForm
()
allContactList
.
value
=
await
ContactApi
.
simpleAllList
()
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
customerList
.
value
=
await
CustomerApi
.
queryAllList
()
areaList
.
value
=
await
AreaApi
.
getAreaTree
()
// 修改时,设置数据
// 修改时,设置数据
if
(
id
)
{
if
(
id
)
{
formLoading
.
value
=
true
formLoading
.
value
=
true
try
{
try
{
formData
.
value
=
await
ContactApi
.
getContact
(
id
)
formData
.
value
=
await
ContactApi
.
getContact
(
id
)
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
await
gotOwnerUser
(
formData
.
value
.
ownerUserId
)
}
finally
{
}
finally
{
formLoading
.
value
=
false
formLoading
.
value
=
false
}
}
}
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
CustomerApi
.
getCustomerPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
loading
.
value
=
false
}
}
const
gotOwnerUser
=
(
owerUserId
:
any
)
=>
{
if
(
owerUserId
!==
null
)
{
owerUserId
.
split
(
','
).
forEach
((
item
:
string
)
=>
{
userList
.
value
.
find
((
user
:
{
id
:
any
})
=>
{
if
(
user
.
id
==
item
)
{
ownerUserList
.
value
.
push
(
user
)
}
})
})
}
}
/** 提交表单 */
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
const
submitForm
=
async
()
=>
{
owerSelectValue
(
ownerUserList
)
//
owerSelectValue(ownerUserList)
// 校验表单
// 校验表单
if
(
!
formRef
)
return
if
(
!
formRef
)
return
const
valid
=
await
formRef
.
value
.
validate
()
const
valid
=
await
formRef
.
value
.
validate
()
...
@@ -302,52 +230,11 @@ const resetForm = () => {
...
@@ -302,52 +230,11 @@ const resetForm = () => {
name
:
undefined
,
name
:
undefined
,
post
:
undefined
,
post
:
undefined
,
qq
:
undefined
,
qq
:
undefined
,
we
b
chat
:
undefined
,
wechat
:
undefined
,
sex
:
undefined
,
sex
:
undefined
,
policyMakers
:
undefined
master
:
false
}
}
formRef
.
value
?.
resetFields
()
formRef
.
value
?.
resetFields
()
ownerUserList
.
value
=
[]
ownerUserList
.
value
=
[]
}
}
/** 添加/修改操作 */
// TODO @zyna:owner?拼写要注意哈;
const
owerRef
=
ref
()
const
openOwerForm
=
(
type
:
string
)
=>
{
owerRef
.
value
.
open
(
type
,
ownerUserList
.
value
)
}
const
owerSelectValue
=
(
value
)
=>
{
ownerUserList
.
value
=
value
.
value
formData
.
value
.
ownerUserId
=
undefined
value
.
value
.
forEach
((
item
,
index
)
=>
{
if
(
index
!=
0
)
{
formData
.
value
.
ownerUserId
=
formData
.
value
.
ownerUserId
+
','
+
item
.
id
}
else
{
formData
.
value
.
ownerUserId
=
item
.
id
}
})
}
// 选择客户
const
showCustomer
=
ref
(
false
)
const
openCustomerSelect
=
()
=>
{
showCustomer
.
value
=
!
showCustomer
.
value
queryParams
.
pageNo
=
1
getList
()
}
const
multipleTableRef
=
ref
<
InstanceType
<
typeof
ElTable
>>
()
const
multipleSelection
=
ref
()
const
handleSelectionChange
=
({},
row
)
=>
{
multipleSelection
.
value
=
row
multipleTableRef
.
value
!
.
clearSelection
()
multipleTableRef
.
value
!
.
toggleRowSelection
(
row
,
undefined
)
}
const
selectCustomer
=
()
=>
{
formData
.
value
.
customerId
=
multipleSelection
.
value
.
id
formData
.
value
.
customerName
=
multipleSelection
.
value
.
name
showCustomer
.
value
=
!
showCustomer
.
value
}
const
allContactList
=
ref
([])
// 所有联系人列表
onMounted
(
async
()
=>
{
allContactList
.
value
=
await
ContactApi
.
simpleAlllist
()
})
</
script
>
</
script
>
src/views/crm/contact/detail/ContactDetails.vue
View file @
038f3d6a
<!--
* @Author: zyna
* @Date: 2023-11-26 10:39:46
* @LastEditTime: 2023-11-26 20:43:43
* @FilePath: \yudao-ui-admin-vue3\src\views\crm\contact\detail\ContactDetails.vue
* @Description:
-->
<
template
>
<
template
>
<el-collapse
v-model=
"activeNames"
>
<el-collapse
v-model=
"activeNames"
>
<el-collapse-item
name=
"basicInfo"
>
<el-collapse-item
name=
"basicInfo"
>
...
@@ -24,14 +31,17 @@
...
@@ -24,14 +31,17 @@
{{ contact.qq }}
{{ contact.qq }}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"微信"
>
<el-descriptions-item
label=
"微信"
>
{{ contact.webchat }}
{{ contact.wechat }}
</el-descriptions-item>
<el-descriptions-item
label=
"详细地址"
>
{{ contact.address }}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"下次联系时间"
>
<el-descriptions-item
label=
"下次联系时间"
>
{{ contact.nextTime ? formatDate(contact.nextTime) : '空' }}
{{ contact.nextTime ? formatDate(contact.nextTime) : '空' }}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"所在地"
>
{{ contact.areaName }}
</el-descriptions-item>
<el-descriptions-item
label=
"详细地址"
>
{{ contact.address }}
</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>
...
@@ -46,7 +56,7 @@
...
@@ -46,7 +56,7 @@
</
template
>
</
template
>
<el-descriptions
:column=
"2"
>
<el-descriptions
:column=
"2"
>
<el-descriptions-item
label=
"负责人"
>
<el-descriptions-item
label=
"负责人"
>
{{
gotOwnerUser(contact.ownerUserId)
}}
{{
contact.ownerUserName
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"创建人"
>
<el-descriptions-item
label=
"创建人"
>
{{ contact.creatorName }}
{{ contact.creatorName }}
...
@@ -66,29 +76,9 @@
...
@@ -66,29 +76,9 @@
import
*
as
ContactApi
from
'@/api/crm/contact'
import
*
as
ContactApi
from
'@/api/crm/contact'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
formatDate
}
from
'@/utils/formatTime'
import
{
formatDate
}
from
'@/utils/formatTime'
import
*
as
UserApi
from
'@/api/system/user'
const
{
contact
}
=
defineProps
<
{
contact
:
ContactApi
.
ContactVO
}
>
()
const
{
contact
}
=
defineProps
<
{
contact
:
ContactApi
.
ContactVO
}
>
()
// 展示的折叠面板
// 展示的折叠面板
const
activeNames
=
ref
([
'basicInfo'
,
'systemInfo'
])
const
activeNames
=
ref
([
'basicInfo'
,
'systemInfo'
])
const
gotOwnerUser
=
(
owerUserId
:
string
)
=>
{
let
ownerName
=
''
if
(
owerUserId
!==
null
&&
owerUserId
!=
undefined
)
{
owerUserId
.
split
(
','
).
forEach
((
item
:
string
,
index
:
number
)
=>
{
if
(
index
!=
0
)
{
ownerName
=
ownerName
+
','
+
userList
.
value
.
find
((
user
:
{
id
:
any
})
=>
user
.
id
==
item
)?.
nickname
}
else
{
ownerName
=
userList
.
value
.
find
((
user
:
{
id
:
any
})
=>
user
.
id
==
item
)?.
nickname
||
''
}
})
}
return
ownerName
}
const
userList
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
/** 初始化 **/
onMounted
(
async
()
=>
{
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
})
</
script
>
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
<
style
scoped
lang=
"scss"
></
style
>
src/views/crm/contact/detail/index.vue
View file @
038f3d6a
...
@@ -63,33 +63,18 @@
...
@@ -63,33 +63,18 @@
<!-- TODO wanwan:这个 tab 拉满哈,可以更好看; -->
<!-- TODO wanwan:这个 tab 拉满哈,可以更好看; -->
<el-col
:span=
"18"
>
<el-col
:span=
"18"
>
<el-tabs>
<el-tabs>
<el-tab-pane
label=
"
详细资料
"
>
<el-tab-pane
label=
"
基本信息
"
>
<!-- TODO wanwan:这个 ml-2 是不是可以优化下,不要整个左移,而是里面的内容有个几 px 的偏移,不顶在框里 -->
<!-- TODO wanwan:这个 ml-2 是不是可以优化下,不要整个左移,而是里面的内容有个几 px 的偏移,不顶在框里 -->
<ContactDetails
class=
"ml-2"
:contact=
"contact"
/>
<ContactDetails
class=
"ml-2"
:contact=
"contact"
/>
</el-tab-pane>
</el-tab-pane>
<el-tab-pane
label=
"活动"
lazy
>
活动
</el-tab-pane>
<el-tab-pane
label=
"跟进记录"
lazy
>
跟进记录
</el-tab-pane>
<el-tab-pane
label=
"邮件"
lazy
>
邮件
</el-tab-pane>
<el-tab-pane
label=
"工商信息"
lazy
>
工商信息
</el-tab-pane>
<!-- TODO wanwan 以下标签上的数量需要接口统计返回 -->
<el-tab-pane
label=
"客户"
lazy
>
<template
#
label
>
客户
<el-badge
:value=
"12"
class=
"item"
type=
"primary"
/>
</
template
>
客户
</el-tab-pane>
<el-tab-pane
label=
"团队成员"
lazy
>
<
template
#
label
>
团队成员
<el-badge
:value=
"2"
class=
"item"
type=
"primary"
/>
</
template
>
团队成员
</el-tab-pane>
<el-tab-pane
label=
"商机"
lazy
>
商机
</el-tab-pane>
<el-tab-pane
label=
"商机"
lazy
>
商机
</el-tab-pane>
<el-tab-pane
label=
"合同"
lazy
>
<el-tab-pane
label=
"附件"
lazy
>
附件
</el-tab-pane>
<
template
#
label
>
合同
<el-badge
:value=
"3"
class=
"item"
type=
"primary"
/>
</
template
>
<!-- TODO wanwan 以下标签上的数量需要接口统计返回 -->
合同
<el-tab-pane
label=
"操作记录"
lazy
>
</el-tab-pane>
<template
#
label
>
操作记录
<el-badge
:value=
"12"
class=
"item"
type=
"primary"
/>
</
template
>
<el-tab-pane
label=
"回款"
lazy
>
操作记录
<
template
#
label
>
回款
<el-badge
:value=
"4"
class=
"item"
type=
"primary"
/>
</
template
>
回款
</el-tab-pane>
</el-tab-pane>
<el-tab-pane
label=
"回访"
lazy
>
回访
</el-tab-pane>
<el-tab-pane
label=
"发票"
lazy
>
发票
</el-tab-pane>
</el-tabs>
</el-tabs>
</el-col>
</el-col>
...
...
src/views/crm/contact/index.vue
View file @
038f3d6a
...
@@ -55,9 +55,9 @@
...
@@ -55,9 +55,9 @@
class=
"!w-240px"
class=
"!w-240px"
/>
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"微信"
prop=
"we
b
chat"
>
<el-form-item
label=
"微信"
prop=
"wechat"
>
<el-input
<el-input
v-model=
"queryParams.we
b
chat"
v-model=
"queryParams.wechat"
placeholder=
"请输入微信"
placeholder=
"请输入微信"
clearable
clearable
@
keyup
.
enter=
"handleQuery"
@
keyup
.
enter=
"handleQuery"
...
@@ -109,20 +109,16 @@
...
@@ -109,20 +109,16 @@
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"职位"
align=
"center"
prop=
"post"
/>
<el-table-column
label=
"职位"
align=
"center"
prop=
"post"
/>
<el-table-column
label=
"是否关键决策人"
align=
"center"
prop=
"
policyMakers
"
>
<el-table-column
label=
"是否关键决策人"
align=
"center"
prop=
"
master
"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.INFRA_BOOLEAN_STRING"
:value=
"scope.row.policyMakers"
/>
<dict-tag
:type=
"DICT_TYPE.INFRA_BOOLEAN_STRING"
:value=
"scope.row.master"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"直属上级"
align=
"center"
prop=
"parentId"
>
<
template
#
default=
"scope"
>
{{
allContactList
.
find
((
contact
)
=>
contact
.
id
===
scope
.
row
.
parentId
)?.
name
}}
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"直属上级"
align=
"center"
prop=
"parentName"
/>
<el-table-column
label=
"手机号"
align=
"center"
prop=
"mobile"
/>
<el-table-column
label=
"手机号"
align=
"center"
prop=
"mobile"
/>
<el-table-column
label=
"座机"
align=
"center"
prop=
"telephone"
/>
<el-table-column
label=
"座机"
align=
"center"
prop=
"telephone"
/>
<el-table-column
label=
"QQ"
align=
"center"
prop=
"qq"
/>
<el-table-column
label=
"QQ"
align=
"center"
prop=
"qq"
/>
<el-table-column
label=
"微信"
align=
"center"
prop=
"we
b
chat"
/>
<el-table-column
label=
"微信"
align=
"center"
prop=
"wechat"
/>
<el-table-column
label=
"邮箱"
align=
"center"
prop=
"email"
/>
<el-table-column
label=
"邮箱"
align=
"center"
prop=
"email"
/>
<el-table-column
label=
"地址"
align=
"center"
prop=
"address"
/>
<el-table-column
label=
"地址"
align=
"center"
prop=
"address"
/>
<el-table-column
<el-table-column
...
@@ -142,7 +138,7 @@
...
@@ -142,7 +138,7 @@
/>
/>
<el-table-column
label=
"负责人"
align=
"center"
prop=
"ownerUserId"
>
<el-table-column
label=
"负责人"
align=
"center"
prop=
"ownerUserId"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
{{
gotOwnerUser
(
scope
.
row
.
ownerUserId
)
}}
{{
scope
.
row
.
ownerUserName
}}
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<!-- <el-table-column label="所属部门" align="center" prop="ownerUserId" /> -->
<!-- <el-table-column label="所属部门" align="center" prop="ownerUserId" /> -->
...
@@ -239,13 +235,12 @@ const queryParams = reactive({
...
@@ -239,13 +235,12 @@ const queryParams = reactive({
name
:
null
,
name
:
null
,
post
:
null
,
post
:
null
,
qq
:
null
,
qq
:
null
,
we
b
chat
:
null
,
wechat
:
null
,
sex
:
null
,
sex
:
null
,
policyMakers
:
null
policyMakers
:
null
})
})
const
queryFormRef
=
ref
()
// 搜索的表单
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
const
exportLoading
=
ref
(
false
)
// 导出的加载中
const
userList
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
/** 查询列表 */
/** 查询列表 */
const
getList
=
async
()
=>
{
const
getList
=
async
()
=>
{
...
@@ -305,35 +300,15 @@ const handleExport = async () => {
...
@@ -305,35 +300,15 @@ const handleExport = async () => {
}
}
}
}
// TODO @zyna:这个负责人的读取,放在后端好点
const
gotOwnerUser
=
(
owerUserId
:
string
)
=>
{
let
ownerName
=
''
if
(
owerUserId
!==
null
)
{
owerUserId
.
split
(
','
).
forEach
((
item
:
string
,
index
:
number
)
=>
{
if
(
index
!=
0
)
{
ownerName
=
ownerName
+
','
+
userList
.
value
.
find
((
user
:
{
id
:
any
})
=>
user
.
id
==
item
)?.
nickname
}
else
{
ownerName
=
userList
.
value
.
find
((
user
:
{
id
:
any
})
=>
user
.
id
==
item
)?.
nickname
||
''
}
})
}
return
ownerName
}
/** 打开客户详情 */
/** 打开客户详情 */
const
{
push
}
=
useRouter
()
const
{
push
}
=
useRouter
()
const
openDetail
=
(
id
:
number
)
=>
{
const
openDetail
=
(
id
:
number
)
=>
{
push
({
name
:
'CrmContactDetail'
,
params
:
{
id
}
})
push
({
name
:
'CrmContactDetail'
,
params
:
{
id
}
})
}
}
// TODO @zyna:这个上级的读取,放在后端读取,更合适;因为可能数据量比较大
const
allContactList
=
ref
([])
//所有联系人列表
const
allCustomerList
=
ref
([])
//客户列表
/** 初始化 **/
/** 初始化 **/
onMounted
(
async
()
=>
{
onMounted
(
async
()
=>
{
await
getList
()
await
getList
()
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
allContactList
.
value
=
await
ContactApi
.
simpleAlllist
()
})
})
</
script
>
</
script
>
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