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
631c105f
authored
Dec 30, 2023
by
芋道源码
Committed by
Gitee
Dec 30, 2023
Browse files
Options
Browse Files
Download
Plain Diff
!346 feat:新增公共操作日志详情组件
Merge pull request !346 from puhui999/dev-crm
parents
8aa49f2e
261d8b2a
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
252 additions
and
27 deletions
+252
-27
src/api/crm/customer/index.ts
+5
-0
src/api/system/operatelog/index.ts
+26
-0
src/components/OperateLogV2/index.ts
+3
-0
src/components/OperateLogV2/src/OperateLogV2.vue
+170
-0
src/views/crm/customer/CustomerForm.vue
+9
-9
src/views/crm/customer/detail/CustomerDetailsHeader.vue
+6
-3
src/views/crm/customer/detail/CustomerDetailsInfo.vue
+13
-12
src/views/crm/customer/detail/index.vue
+20
-3
No files found.
src/api/crm/customer/index.ts
View file @
631c105f
...
@@ -67,3 +67,8 @@ export const exportCustomer = async (params) => {
...
@@ -67,3 +67,8 @@ export const exportCustomer = async (params) => {
export
const
queryAllList
=
async
()
=>
{
export
const
queryAllList
=
async
()
=>
{
return
await
request
.
get
({
url
:
`/crm/customer/query-all-list`
})
return
await
request
.
get
({
url
:
`/crm/customer/query-all-list`
})
}
}
// 查询客户操作日志
export
const
getOperateLogPage
=
async
(
params
)
=>
{
return
await
request
.
get
({
url
:
'/crm/customer/operate-log-page'
,
params
})
}
src/api/system/operatelog/index.ts
View file @
631c105f
...
@@ -23,6 +23,32 @@ export type OperateLogVO = {
...
@@ -23,6 +23,32 @@ export type OperateLogVO = {
resultData
:
string
resultData
:
string
}
}
export
type
OperateLogV2VO
=
{
id
:
number
userNickname
:
string
traceId
:
string
userType
:
number
userId
:
number
userName
:
string
type
:
string
subType
:
string
bizId
:
number
action
:
string
extra
:
string
requestMethod
:
string
requestUrl
:
string
userIp
:
string
userAgent
:
string
creator
:
string
creatorName
:
string
createTime
:
Date
// 数据扩展-渲染时使用
title
:
string
// 操作标题(如果为空则取 name 值)
colSize
:
number
// 变更记录行数
contentStrList
:
string
[]
tagsContentList
:
string
[]
}
// 查询操作日志列表
// 查询操作日志列表
export
const
getOperateLogPage
=
(
params
:
PageParam
)
=>
{
export
const
getOperateLogPage
=
(
params
:
PageParam
)
=>
{
return
request
.
get
({
url
:
'/system/operate-log/page'
,
params
})
return
request
.
get
({
url
:
'/system/operate-log/page'
,
params
})
...
...
src/components/OperateLogV2/index.ts
0 → 100644
View file @
631c105f
import
OperateLogV2
from
'./src/OperateLogV2.vue'
export
{
OperateLogV2
}
src/components/OperateLogV2/src/OperateLogV2.vue
0 → 100644
View file @
631c105f
<
template
>
<div
class=
"p-20px"
>
<el-timeline>
<el-timeline-item
v-for=
"(log, index) in logDataList"
:key=
"index"
:timestamp=
"formatDate(log.createTime)"
placement=
"top"
>
<div
class=
"el-timeline-right-content"
>
<el-row>
<el-col
:span=
"24"
class=
"mb-10px"
>
=======================
<el-tag
class=
"mr-10px"
type=
"success"
>
{{
log
.
userName
}}
</el-tag>
<span>
{{
log
.
title
}}
</span>
=======================
</el-col>
<!-- 先处理一下有几行-->
<template
v-for=
"colNum in log.colSize"
:key=
"colNum + 'col'"
>
<el-col
:span=
"24"
class=
"mb-10px"
>
<!-- 处理每一行-->
<template
v-for=
"(tagVal, index2) in log.tagsContentList.slice(
(colNum - 1) * 3,
3 * colNum
)"
:key=
"index2"
>
<el-tag
class=
"mx-10px"
>
{{
tagVal
}}
</el-tag>
<span>
{{
log
.
contentStrList
[
index2
]
}}
</span>
</
template
>
</el-col>
</template>
</el-row>
</div>
<
template
#
dot
>
<span
:style=
"
{ backgroundColor: getUserTypeColor(log.userType) }" class="dot-node-style">
{{
getDictLabel
(
DICT_TYPE
.
USER_TYPE
,
log
.
userType
)[
0
]
}}
</span>
</
template
>
</el-timeline-item>
</el-timeline>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
OperateLogV2VO
}
from
'@/api/system/operatelog'
import
{
formatDate
}
from
'@/utils/formatTime'
import
{
DICT_TYPE
,
getDictLabel
,
getDictObj
}
from
'@/utils/dict'
import
{
ElTag
}
from
'element-plus'
const
props
=
defineProps
<
{
logList
:
OperateLogV2VO
[]
// 操作日志列表
}
>
()
defineOptions
({
name
:
'OperateLogV2'
})
/** 获得 userType 颜色 */
const
getUserTypeColor
=
(
type
:
number
)
=>
{
const
dict
=
getDictObj
(
DICT_TYPE
.
USER_TYPE
,
type
)
switch
(
dict
?.
colorType
)
{
case
'success'
:
return
'#67C23A'
case
'info'
:
return
'#909399'
case
'warning'
:
return
'#E6A23C'
case
'danger'
:
return
'#F56C6C'
}
return
'#409EFF'
}
const
logDataList
=
ref
<
OperateLogV2VO
[]
>
([])
// 操作日志列表
// 提取 tag 所需内容和位置
const
renderTags
=
(
content
:
string
)
=>
{
let
newStr
=
unref
(
content
).
slice
()
// 去掉引用
newStr
=
newStr
.
replaceAll
(
'【】'
,
'【空】'
).
replaceAll
(
';'
,
''
)
// 处理掉分号 特殊:处理一下空的情况
const
regex
=
/【
([^
【】
]
+
)
】/g
const
fg
=
'|'
// 原始位置替换符号
let
match
:
any
[]
|
null
let
matchStr
:
string
[]
=
[]
let
oldStr
:
string
[]
=
[]
while
((
match
=
regex
.
exec
(
newStr
))
!==
null
)
{
matchStr
.
push
(
match
[
1
])
// 提取值
oldStr
.
push
(
match
[
0
])
// 原值
}
// 为什么重新循环不放在 while 中一起是因为替换重新赋值过后 match 值就不准确了
oldStr
.
forEach
((
item
)
=>
{
newStr
=
newStr
.
replace
(
item
,
fg
)
})
return
[
newStr
.
split
(
fg
),
matchStr
]
}
const
initLog
=
()
=>
{
logDataList
.
value
=
props
.
logList
.
map
((
logItem
)
=>
{
const
keyValue
=
renderTags
(
logItem
.
action
)
// 挂载数据
logItem
.
contentStrList
=
keyValue
[
0
]
if
(
keyValue
[
0
][
0
]
===
'从'
)
{
logItem
.
title
=
logItem
.
subType
}
else
{
logItem
.
title
=
keyValue
[
0
][
0
]
logItem
.
contentStrList
.
splice
(
0
,
1
)
}
logItem
.
colSize
=
keyValue
[
0
].
length
/
3
// 变更记录行数
logItem
.
tagsContentList
=
keyValue
[
1
]
return
logItem
})
}
watch
(
()
=>
props
.
logList
.
length
,
(
newObj
)
=>
{
if
(
newObj
)
{
initLog
()
console
.
log
(
logDataList
.
value
)
}
},
{
immediate
:
true
,
deep
:
true
}
)
</
script
>
<
style
lang=
"scss"
scoped
>
//
时间线样式调整
:deep
(
.el-timeline
)
{
margin
:
10px
0
0
160px
;
.el-timeline-item__wrapper
{
position
:
relative
;
top
:
-20px
;
.el-timeline-item__timestamp
{
position
:
absolute
!important
;
top
:
10px
;
left
:
-150px
;
}
}
.el-timeline-right-content
{
display
:
flex
;
align-items
:
center
;
min-height
:
30px
;
padding
:
10px
;
background-color
:
#fff
;
&::before
{
position
:
absolute
;
top
:
10px
;
left
:
13px
;
/* 将伪元素水平居中 */
border-color
:
transparent
#fff
transparent
transparent
;
/* 尖角颜色,左侧朝向 */
border-style
:
solid
;
border-width
:
8px
;
/* 调整尖角大小 */
content
:
''
;
/* 必须设置 content 属性 */
}
}
}
.dot-node-style
{
position
:
absolute
;
left
:
-5px
;
display
:
flex
;
width
:
20px
;
height
:
20px
;
font-size
:
10px
;
color
:
#fff
;
border-radius
:
50%
;
justify-content
:
center
;
align-items
:
center
;
}
</
style
>
src/views/crm/customer/CustomerForm.vue
View file @
631c105f
<
template
>
<
template
>
<Dialog
:title=
"dialogTitle"
v-model=
"dialogVisib
le"
>
<Dialog
v-model=
"dialogVisible"
:title=
"dialogTit
le"
>
<el-form
<el-form
ref=
"formRef"
ref=
"formRef"
v-loading=
"formLoading"
:model=
"formData"
:model=
"formData"
:rules=
"formRules"
:rules=
"formRules"
label-width=
"100px"
label-width=
"100px"
v-loading=
"formLoading"
>
>
<el-row>
<el-row>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
<el-form-item
label=
"所属行业"
prop=
"industryId"
>
<el-form-item
label=
"所属行业"
prop=
"industryId"
>
<el-select
v-model=
"formData.industryId"
placeholder=
"请选择所属行业"
>
<el-select
v-model=
"formData.industryId"
placeholder=
"请选择所属行业"
>
<el-option
<el-option
v-for=
"dict in get
Str
DictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
v-for=
"dict in get
Int
DictOptions(DICT_TYPE.CRM_CUSTOMER_INDUSTRY)"
:key=
"dict.value"
:key=
"dict.value"
:label=
"dict.label"
:label=
"dict.label"
:value=
"dict.value"
:value=
"dict.value"
...
@@ -31,7 +31,7 @@
...
@@ -31,7 +31,7 @@
<el-form-item
label=
"客户来源"
prop=
"source"
>
<el-form-item
label=
"客户来源"
prop=
"source"
>
<el-select
v-model=
"formData.source"
placeholder=
"请选择客户来源"
>
<el-select
v-model=
"formData.source"
placeholder=
"请选择客户来源"
>
<el-option
<el-option
v-for=
"dict in get
Str
DictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
v-for=
"dict in get
Int
DictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)"
:key=
"dict.value"
:key=
"dict.value"
:label=
"dict.label"
:label=
"dict.label"
:value=
"dict.value"
:value=
"dict.value"
...
@@ -43,7 +43,7 @@
...
@@ -43,7 +43,7 @@
<el-form-item
label=
"客户等级"
prop=
"level"
>
<el-form-item
label=
"客户等级"
prop=
"level"
>
<el-select
v-model=
"formData.level"
placeholder=
"请选择客户等级"
>
<el-select
v-model=
"formData.level"
placeholder=
"请选择客户等级"
>
<el-option
<el-option
v-for=
"dict in get
Str
DictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
v-for=
"dict in get
Int
DictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)"
:key=
"dict.value"
:key=
"dict.value"
:label=
"dict.label"
:label=
"dict.label"
:value=
"dict.value"
:value=
"dict.value"
...
@@ -120,9 +120,9 @@
...
@@ -120,9 +120,9 @@
<el-form-item
label=
"下次联系时间"
prop=
"contactNextTime"
>
<el-form-item
label=
"下次联系时间"
prop=
"contactNextTime"
>
<el-date-picker
<el-date-picker
v-model=
"formData.contactNextTime"
v-model=
"formData.contactNextTime"
placeholder=
"选择下次联系时间"
type=
"date"
type=
"date"
value-format=
"x"
value-format=
"x"
placeholder=
"选择下次联系时间"
/>
/>
</el-form-item>
</el-form-item>
</el-col>
</el-col>
...
@@ -139,13 +139,13 @@
...
@@ -139,13 +139,13 @@
</el-col>
</el-col>
</el-form>
</el-form>
<template
#
footer
>
<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>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</
template
>
</Dialog>
</Dialog>
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
{
DICT_TYPE
,
get
Str
DictOptions
}
from
'@/utils/dict'
import
{
DICT_TYPE
,
get
Int
DictOptions
}
from
'@/utils/dict'
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'
...
...
src/views/crm/customer/detail/CustomerDetailsHeader.vue
View file @
631c105f
...
@@ -14,6 +14,7 @@
...
@@ -14,6 +14,7 @@
<el-button
v-hasPermi=
"['crm:customer:update']"
@
click=
"openForm(customer.id)"
>
<el-button
v-hasPermi=
"['crm:customer:update']"
@
click=
"openForm(customer.id)"
>
编辑
编辑
</el-button>
</el-button>
<el-button
@
click=
"transfer"
>
转移
</el-button>
<el-button>
更改成交状态
</el-button>
<el-button>
更改成交状态
</el-button>
</div>
</div>
</div>
</div>
...
@@ -26,22 +27,24 @@
...
@@ -26,22 +27,24 @@
<el-descriptions-item
label=
"成交状态"
>
<el-descriptions-item
label=
"成交状态"
>
{{
customer
.
dealStatus
?
'已成交'
:
'未成交'
}}
{{
customer
.
dealStatus
?
'已成交'
:
'未成交'
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"负责人"
>
{{
customer
.
ownerUserName
}}
</el-descriptions-item>
<el-descriptions-item
label=
"负责人"
>
{{
customer
.
ownerUserName
}}
</el-descriptions-item>
<!-- TODO wanwan 首要联系人? -->
<!-- TODO wanwan 首要联系人? -->
<el-descriptions-item
label=
"首要联系人"
/>
<el-descriptions-item
label=
"首要联系人"
/>
<!-- TODO wanwan 首要联系人电话? -->
<!-- TODO wanwan 首要联系人电话? -->
<el-descriptions-item
label=
"首要联系人电话"
>
{{
customer
.
mobile
}}
</el-descriptions-item>
<el-descriptions-item
label=
"首要联系人电话"
>
{{
customer
.
mobile
}}
</el-descriptions-item>
</el-descriptions>
</el-descriptions>
</ContentWrap>
</ContentWrap>
<!-- 表单弹窗:添加/修改 -->
<!-- 表单弹窗:添加/修改 -->
<CustomerForm
ref=
"formRef"
@
success=
"emit('refresh')"
/>
<CustomerForm
ref=
"formRef"
@
success=
"emit('refresh')"
/>
</
template
>
</
template
>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
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
CustomerForm
from
'../CustomerForm.vue'
import
CustomerForm
from
'../CustomerForm.vue'
defineOptions
({
name
:
'CustomerDetailsHeader'
})
const
{
customer
,
loading
}
=
defineProps
<
{
const
{
customer
,
loading
}
=
defineProps
<
{
customer
:
CustomerApi
.
CustomerVO
// 客户信息
customer
:
CustomerApi
.
CustomerVO
// 客户信息
loading
:
boolean
// 加载中
loading
:
boolean
// 加载中
...
...
src/views/crm/customer/detail/CustomerDetailsInfo.vue
View file @
631c105f
<
template
>
<
template
>
<ContentWrap>
<ContentWrap>
<el-collapse
class=
""
v-model=
"activeNames
"
>
<el-collapse
v-model=
"activeNames"
class=
"
"
>
<el-collapse-item
name=
"basicInfo"
>
<el-collapse-item
name=
"basicInfo"
>
<template
#
title
>
<template
#
title
>
<span
class=
"text-base font-bold"
>
基本信息
</span>
<span
class=
"text-base font-bold"
>
基本信息
</span>
...
@@ -20,11 +20,11 @@
...
@@ -20,11 +20,11 @@
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"手机"
>
{{ customer.mobile }}
</el-descriptions-item>
<el-descriptions-item
label=
"手机"
>
{{ customer.mobile }}
</el-descriptions-item>
<el-descriptions-item
label=
"电话"
>
{{ customer.telephone }}
</el-descriptions-item>
<el-descriptions-item
label=
"电话"
>
{{ customer.telephone }}
</el-descriptions-item>
<el-descriptions-item
label=
"邮箱"
>
{{ customer.email }}
</el-descriptions-item>
<el-descriptions-item
label=
"邮箱"
>
{{ customer.email }}
</el-descriptions-item>
<el-descriptions-item
label=
"QQ"
>
{{ customer.qq }}
</el-descriptions-item>
<el-descriptions-item
label=
"QQ"
>
{{ customer.qq }}
</el-descriptions-item>
<el-descriptions-item
label=
"微信"
>
{{ customer.wechat }}
</el-descriptions-item>
<el-descriptions-item
label=
"微信"
>
{{ customer.wechat }}
</el-descriptions-item>
<el-descriptions-item
label=
"网址"
>
{{ customer.website }}
</el-descriptions-item>
<el-descriptions-item
label=
"网址"
>
{{ customer.website }}
</el-descriptions-item>
<el-descriptions-item
label=
"所在地"
>
{{ customer.areaName }}
</el-descriptions-item>
<el-descriptions-item
label=
"所在地"
>
{{ customer.areaName }}
</el-descriptions-item>
<el-descriptions-item
label=
"详细地址"
<el-descriptions-item
label=
"详细地址"
>
{{ customer.detailAddress }}
>
{{ customer.detailAddress }}
</el-descriptions-item>
</el-descriptions-item>
...
@@ -38,8 +38,8 @@
...
@@ -38,8 +38,8 @@
</el-descriptions-item>
</el-descriptions-item>
</el-descriptions>
</el-descriptions>
<el-descriptions
:column=
"1"
>
<el-descriptions
:column=
"1"
>
<el-descriptions-item
label=
"客户描述"
>
{{ customer.description }}
</el-descriptions-item>
<el-descriptions-item
label=
"客户描述"
>
{{ customer.description }}
</el-descriptions-item>
<el-descriptions-item
label=
"备注"
>
{{ customer.remark }}
</el-descriptions-item>
<el-descriptions-item
label=
"备注"
>
{{ customer.remark }}
</el-descriptions-item>
</el-descriptions>
</el-descriptions>
</el-collapse-item>
</el-collapse-item>
<el-collapse-item
name=
"systemInfo"
>
<el-collapse-item
name=
"systemInfo"
>
...
@@ -47,8 +47,8 @@
...
@@ -47,8 +47,8 @@
<span
class=
"text-base font-bold"
>
系统信息
</span>
<span
class=
"text-base font-bold"
>
系统信息
</span>
</
template
>
</
template
>
<el-descriptions
:column=
"2"
>
<el-descriptions
:column=
"2"
>
<el-descriptions-item
label=
"负责人"
>
{{ customer.ownerUserName }}
</el-descriptions-item>
<el-descriptions-item
label=
"负责人"
>
{{ customer.ownerUserName }}
</el-descriptions-item>
<el-descriptions-item
label=
"创建人"
>
{{ customer.creatorName }}
</el-descriptions-item>
<el-descriptions-item
label=
"创建人"
>
{{ customer.creatorName }}
</el-descriptions-item>
<el-descriptions-item
label=
"创建时间"
>
<el-descriptions-item
label=
"创建时间"
>
{{ customer.createTime ? formatDate(customer.createTime) : '空' }}
{{ customer.createTime ? formatDate(customer.createTime) : '空' }}
</el-descriptions-item>
</el-descriptions-item>
...
@@ -60,15 +60,16 @@
...
@@ -60,15 +60,16 @@
</el-collapse>
</el-collapse>
</ContentWrap>
</ContentWrap>
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
formatDate
}
from
'@/utils/formatTime'
import
{
formatDate
}
from
'@/utils/formatTime'
defineOptions
({
name
:
'CustomerDetailsInfo'
})
const
{
customer
}
=
defineProps
<
{
const
{
customer
}
=
defineProps
<
{
customer
:
CustomerApi
.
CustomerVO
// 客户明细
customer
:
CustomerApi
.
CustomerVO
// 客户明细
}
>
()
}
>
()
const
activeNames
=
ref
([
'basicInfo'
,
'systemInfo'
])
// 展示的折叠面板
const
activeNames
=
ref
([
'basicInfo'
,
'systemInfo'
])
// 展示的折叠面板
</
script
>
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
<
style
lang=
"scss"
scoped
></
style
>
src/views/crm/customer/detail/index.vue
View file @
631c105f
...
@@ -5,7 +5,9 @@
...
@@ -5,7 +5,9 @@
<el-tab-pane
label=
"详细资料"
>
<el-tab-pane
label=
"详细资料"
>
<CustomerDetailsInfo
:customer=
"customer"
/>
<CustomerDetailsInfo
:customer=
"customer"
/>
</el-tab-pane>
</el-tab-pane>
<el-tab-pane
label=
"操作日志"
lazy
>
TODO 待开发
</el-tab-pane>
<el-tab-pane
label=
"操作日志"
>
<OperateLogV2
:log-list=
"logList"
/>
</el-tab-pane>
<el-tab-pane
label=
"联系人"
lazy
>
<el-tab-pane
label=
"联系人"
lazy
>
<ContactList
:biz-id=
"customer.id!"
:biz-type=
"BizTypeEnum.CRM_CUSTOMER"
/>
<ContactList
:biz-id=
"customer.id!"
:biz-type=
"BizTypeEnum.CRM_CUSTOMER"
/>
</el-tab-pane>
</el-tab-pane>
...
@@ -38,24 +40,39 @@ import ReceivableList from '@/views/crm/receivable/components/ReceivableList.vue
...
@@ -38,24 +40,39 @@ import ReceivableList from '@/views/crm/receivable/components/ReceivableList.vue
import
ReceivablePlanList
from
'@/views/crm/receivable/plan/components/ReceivablePlanList.vue'
// 回款计划列表
import
ReceivablePlanList
from
'@/views/crm/receivable/plan/components/ReceivablePlanList.vue'
// 回款计划列表
import
PermissionList
from
'@/views/crm/permission/components/PermissionList.vue'
// 团队成员列表(权限)
import
PermissionList
from
'@/views/crm/permission/components/PermissionList.vue'
// 团队成员列表(权限)
import
{
BizTypeEnum
}
from
'@/api/crm/permission'
import
{
BizTypeEnum
}
from
'@/api/crm/permission'
import
{
OperateLogV2VO
}
from
'@/api/system/operatelog'
defineOptions
({
name
:
'CrmCustomerDetail'
})
defineOptions
({
name
:
'CrmCustomerDetail'
})
const
route
=
useRoute
()
const
route
=
useRoute
()
const
id
=
Number
(
route
.
params
.
id
)
// 客户编号
const
id
=
Number
(
route
.
params
.
id
)
// 客户编号
const
loading
=
ref
(
true
)
// 加载中
const
loading
=
ref
(
true
)
// 加载中
/** 获取详情 */
/** 获取详情 */
const
customer
=
ref
<
CustomerApi
.
CustomerVO
>
({}
as
CustomerApi
.
CustomerVO
)
// 客户详情
const
customer
=
ref
<
CustomerApi
.
CustomerVO
>
({}
as
CustomerApi
.
CustomerVO
)
// 客户详情
const
getCustomer
=
async
(
id
:
number
)
=>
{
const
getCustomer
=
async
(
id
:
number
)
=>
{
loading
.
value
=
true
loading
.
value
=
true
try
{
try
{
customer
.
value
=
await
CustomerApi
.
getCustomer
(
id
)
customer
.
value
=
await
CustomerApi
.
getCustomer
(
id
)
await
getOperateLog
(
id
)
}
finally
{
}
finally
{
loading
.
value
=
false
loading
.
value
=
false
}
}
}
}
const
logList
=
ref
<
OperateLogV2VO
[]
>
([])
// 操作日志列表
/**
* 获取操作日志
*/
const
getOperateLog
=
async
(
customerId
:
number
)
=>
{
if
(
!
customerId
)
{
return
}
const
data
=
await
CustomerApi
.
getOperateLogPage
({
pageNo
:
1
,
pageSize
:
10
,
bizId
:
customerId
})
logList
.
value
=
data
.
list
}
/** 初始化 */
/** 初始化 */
const
{
delView
}
=
useTagsViewStore
()
// 视图操作
const
{
delView
}
=
useTagsViewStore
()
// 视图操作
const
{
currentRoute
}
=
useRouter
()
// 路由
const
{
currentRoute
}
=
useRouter
()
// 路由
...
...
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