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
5f26c4af
authored
Nov 30, 2023
by
YunaiV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
crm:完善数据权限的界面
parent
7de0e93d
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
247 additions
and
228 deletions
+247
-228
src/api/crm/contact/index.ts
+2
-3
src/api/crm/permission/index.ts
+23
-7
src/utils/dict.ts
+2
-2
src/views/crm/components/index.ts
+0
-16
src/views/crm/contact/ContactForm.vue
+1
-1
src/views/crm/contact/components/ContactList.vue
+3
-2
src/views/crm/contact/detail/index.vue
+2
-2
src/views/crm/contact/index.vue
+115
-35
src/views/crm/customer/detail/CustomerBasicInfo.vue
+0
-18
src/views/crm/customer/detail/CustomerDetailsHeader.vue
+17
-35
src/views/crm/customer/detail/CustomerDetailsInfo.vue
+15
-38
src/views/crm/customer/detail/index.vue
+15
-22
src/views/crm/customer/index.vue
+11
-14
src/views/crm/permission/components/PermissionForm.vue
+5
-4
src/views/crm/permission/components/PermissionList.vue
+36
-29
No files found.
src/api/crm/contact/index.ts
View file @
5f26c4af
...
...
@@ -61,8 +61,7 @@ export const exportContact = async (params) => {
return
await
request
.
download
({
url
:
`/crm/contact/export-excel`
,
params
})
}
export
const
simpleAllList
=
async
()
=>
{
// 获得 CRM 联系人列表(精简)
export
const
getSimpleContactList
=
async
()
=>
{
return
await
request
.
get
({
url
:
`/crm/contact/simple-all-list`
})
}
//
src/api/crm/permission/index.ts
View file @
5f26c4af
...
...
@@ -12,6 +12,11 @@ export interface PermissionVO {
createTime
?:
Date
}
/**
* CRM 业务类型枚举
*
* @author HUIHUI
*/
export
enum
BizTypeEnum
{
CRM_LEADS
=
1
,
// 线索
CRM_CUSTOMER
=
2
,
// 客户
...
...
@@ -20,36 +25,47 @@ export enum BizTypeEnum {
CRM_CONTRACT
=
6
// 合同
}
// 查询团队成员列表
/**
* CRM 数据权限级别枚举
*/
export
enum
PermissionLevelEnum
{
OWNER
=
1
,
// 负责人
READ
=
2
,
// 只读
WRITE
=
3
// 读写
}
// 获得数据权限列表(查询团队成员列表)
export
const
getPermissionList
=
async
(
params
)
=>
{
return
await
request
.
get
({
url
:
`/crm/permission/list`
,
params
})
}
//
新增团队成员
//
创建数据权限(新增团队成员)
export
const
createPermission
=
async
(
data
:
PermissionVO
)
=>
{
return
await
request
.
post
({
url
:
`/crm/permission/create`
,
data
})
}
//
修改团队成员权限级别
//
编辑数据权限(修改团队成员权限级别)
export
const
updatePermission
=
async
(
data
)
=>
{
return
await
request
.
put
({
url
:
`/crm/permission/update`
,
data
})
}
// 删除
团队成员
export
const
deletePermission
=
async
(
params
)
=>
{
// 删除
数据权限(删除团队成员)
export
const
deletePermission
Batch
=
async
(
params
)
=>
{
return
await
request
.
delete
({
url
:
'/crm/permission/delete'
,
params
})
}
//
退出团队
export
const
quitTeam
=
async
(
id
)
=>
{
//
删除自己的数据权限(退出团队)
export
const
deleteSelfPermission
=
async
(
id
)
=>
{
return
await
request
.
delete
({
url
:
'/crm/permission/quit-team?id='
+
id
})
}
// TODO @puhui999:调整下位置
// 领取公海数据
export
const
receive
=
async
(
data
:
{
bizType
:
number
;
bizId
:
number
})
=>
{
return
await
request
.
put
({
url
:
`/crm/permission/receive`
,
data
})
}
// TODO @puhui999:调整下位置
// 数据放入公海
export
const
putPool
=
async
(
data
:
{
bizType
:
number
;
bizId
:
number
})
=>
{
return
await
request
.
put
({
url
:
`/crm/permission/put-pool`
,
data
})
...
...
src/utils/dict.ts
View file @
5f26c4af
...
...
@@ -198,6 +198,6 @@ export enum DICT_TYPE {
CRM_PRODUCT_STATUS
=
'crm_product_status'
,
// ========== CRM - 数据权限模块 ==========
CRM_BIZ_TYPE
=
'crm_biz_type'
,
//
数据模块
类型
CRM_PERMISSION_LEVEL
=
'crm_permission_level'
//
用户数据权限类型
CRM_BIZ_TYPE
=
'crm_biz_type'
,
//
CRM 业务
类型
CRM_PERMISSION_LEVEL
=
'crm_permission_level'
//
CRM 数据权限的级别
}
src/views/crm/components/index.ts
deleted
100644 → 0
View file @
7de0e93d
import
CrmPermissionList
from
'./CrmPermissionList.vue'
// TODO @puhui999:迁移到 api/permission/index.ts 里;我已经迁移了一部分哈
enum
CrmBizTypeEnum
{
CRM_LEADS
=
1
,
// 线索
CRM_CUSTOMER
=
2
,
// 客户
CRM_CONTACTS
=
3
,
// 联系人
CRM_BUSINESS
=
5
,
// 商机
CRM_CONTRACT
=
6
// 合同
}
enum
CrmPermissionLevelEnum
{
OWNER
=
1
// 负责人
}
export
{
CrmPermissionList
,
CrmBizTypeEnum
,
CrmPermissionLevelEnum
}
src/views/crm/contact/ContactForm.vue
View file @
5f26c4af
...
...
@@ -235,7 +235,7 @@ const open = async (type: string, id?: number) => {
dialogTitle
.
value
=
t
(
'action.'
+
type
)
formType
.
value
=
type
resetForm
()
allContactList
.
value
=
await
ContactApi
.
simpleAll
List
()
allContactList
.
value
=
await
ContactApi
.
getSimpleContact
List
()
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
customerList
.
value
=
await
CustomerApi
.
queryAllList
()
areaList
.
value
=
await
AreaApi
.
getAreaTree
()
...
...
src/views/crm/contact/components/ContactList.vue
View file @
5f26c4af
<
template
>
<!-- 操作栏 -->
<el-row
justify=
"end"
>
<el-button
class=
"mb-10px"
>
<el-button>
<Icon
class=
"mr-5px"
icon=
"system-uicons:contacts"
/>
创建联系人
</el-button>
</el-row>
<!-- 列表 -->
<ContentWrap>
<ContentWrap
class=
"mt-10px"
>
<el-table
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
>
<el-table-column
label=
"姓名"
fixed=
"left"
align=
"center"
prop=
"name"
>
<template
#
default=
"scope"
>
...
...
@@ -136,6 +136,7 @@ const openDetail = (id: number) => {
push
({
name
:
'CrmContactDetail'
,
params
:
{
id
}
})
}
/** 监听打开的 bizId + bizType,从而加载最新的列表 */
watch
(
()
=>
[
props
.
bizId
,
props
.
bizType
],
()
=>
{
...
...
src/views/crm/contact/detail/index.vue
View file @
5f26c4af
...
...
@@ -90,10 +90,10 @@ import ContactBasicInfo from '@/views/crm/contact/detail/ContactBasicInfo.vue'
import
ContactDetails
from
'@/views/crm/contact/detail/ContactDetails.vue'
import
ContactForm
from
'@/views/crm/contact/ContactForm.vue'
import
{
formatDate
}
from
'@/utils/formatTime'
import
*
as
CustomerApi
from
'@/api/crm/customer'
// TODO 芋艿:后面在 review 么?
defineOptions
({
name
:
'ContactDetail'
})
defineOptions
({
name
:
'CrmContactDetail'
})
const
{
delView
}
=
useTagsViewStore
()
// 视图操作
const
route
=
useRoute
()
const
{
currentRoute
}
=
useRouter
()
// 路由
...
...
src/views/crm/contact/index.vue
View file @
5f26c4af
<
template
>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"68px"
>
<el-form
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"客户"
prop=
"customerId"
>
<el-select
v-model=
"queryParams.customerId"
placeholder=
"请选择客户"
value-key=
"id"
lable-key=
"name"
@
keyup
.
enter=
"handleQuery"
clearable
>
<el-option
v-for=
"item in customerList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
v-model=
"queryParams.customerId"
placeholder=
"请选择客户"
value-key=
"id"
lable-key=
"name"
@
keyup
.
enter=
"handleQuery"
clearable
>
<el-option
v-for=
"item in customerList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"姓名"
prop=
"name"
>
<el-input
v-model=
"queryParams.name"
placeholder=
"请输入姓名"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
<el-input
v-model=
"queryParams.name"
placeholder=
"请输入姓名"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"手机号"
prop=
"mobile"
>
<el-input
v-model=
"queryParams.mobile"
placeholder=
"请输入手机号"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
v-model=
"queryParams.mobile"
placeholder=
"请输入手机号"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"座机"
prop=
"telephone"
>
<el-input
v-model=
"queryParams.telephone"
placeholder=
"请输入电话"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
v-model=
"queryParams.telephone"
placeholder=
"请输入电话"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"QQ"
prop=
"qq"
>
<el-input
v-model=
"queryParams.qq"
placeholder=
"请输入QQ"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
<el-input
v-model=
"queryParams.qq"
placeholder=
"请输入QQ"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"微信"
prop=
"wechat"
>
<el-input
v-model=
"queryParams.wechat"
placeholder=
"请输入微信"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
v-model=
"queryParams.wechat"
placeholder=
"请输入微信"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"电子邮箱"
prop=
"email"
>
<el-input
v-model=
"queryParams.email"
placeholder=
"请输入电子邮箱"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
v-model=
"queryParams.email"
placeholder=
"请输入电子邮箱"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</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
@
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>
<el-button
type=
"success"
plain
@
click=
"handleExport"
:loading=
"exportLoading"
v-hasPermi=
"['crm:contact:export']"
>
type=
"success"
plain
@
click=
"handleExport"
:loading=
"exportLoading"
v-hasPermi=
"['crm:contact:export']"
>
<Icon
icon=
"ep:download"
class=
"mr-5px"
/>
导出
</el-button>
</el-form-item>
...
...
@@ -60,9 +104,9 @@ type="success" plain @click="handleExport" :loading="exportLoading"
<el-table
v-loading=
"loading"
:data=
"list"
:stripe=
"true"
:show-overflow-tooltip=
"true"
>
<el-table-column
label=
"姓名"
fixed=
"left"
align=
"center"
prop=
"name"
>
<template
#
default=
"scope"
>
<el-link
type=
"primary"
:underline=
"false"
@
click=
"openDetail(scope.row.id)"
>
{{
scope
.
row
.
name
}}
</el-link>
<el-link
type=
"primary"
:underline=
"false"
@
click=
"openDetail(scope.row.id)"
>
{{
scope
.
row
.
name
}}
</el-link>
</
template
>
</el-table-column>
<el-table-column
label=
"客户"
fixed=
"left"
align=
"center"
prop=
"customerName"
/>
...
...
@@ -84,17 +128,41 @@ type="success" plain @click="handleExport" :loading="exportLoading"
<el-table-column
label=
"微信"
align=
"center"
prop=
"wechat"
/>
<el-table-column
label=
"邮箱"
align=
"center"
prop=
"email"
/>
<el-table-column
label=
"地址"
align=
"center"
prop=
"address"
/>
<el-table-column
label=
"下次联系时间"
align=
"center"
prop=
"nextTime"
width=
"180px"
:formatter=
"dateFormatter"
/>
<el-table-column
label=
"下次联系时间"
align=
"center"
prop=
"nextTime"
width=
"180px"
:formatter=
"dateFormatter"
/>
<el-table-column
label=
"备注"
align=
"center"
prop=
"remark"
/>
<el-table-column
label=
"最后跟进时间"
align=
"center"
prop=
"lastTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"最后跟进时间"
align=
"center"
prop=
"lastTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"负责人"
align=
"center"
prop=
"ownerUserId"
>
<
template
#
default=
"scope"
>
{{
scope
.
row
.
ownerUserName
}}
</
template
>
</el-table-column>
<!-- <el-table-column label="所属部门" align="center" prop="ownerUserId" /> -->
<el-table-column
label=
"更新时间"
align=
"center"
prop=
"updateTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"创建时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"更新时间"
align=
"center"
prop=
"updateTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"创建时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<!-- <el-table-column
label="创建人"
align="center"
...
...
@@ -108,10 +176,20 @@ type="success" plain @click="handleExport" :loading="exportLoading"
</el-table-column> -->
<el-table-column
label=
"操作"
align=
"center"
fixed=
"right"
width=
"200"
>
<
template
#
default=
"scope"
>
<el-button
plain
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['crm:contact:update']"
>
<el-button
plain
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['crm:contact:update']"
>
编辑
</el-button>
<el-button
plain
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['crm:contact:delete']"
>
<el-button
plain
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['crm:contact:delete']"
>
删除
</el-button>
</
template
>
...
...
@@ -119,8 +197,11 @@ type="success" plain @click="handleExport" :loading="exportLoading"
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
</ContentWrap>
<!-- 表单弹窗:添加/修改 -->
...
...
@@ -208,7 +289,7 @@ const handleDelete = async (id: number) => {
message
.
success
(
t
(
'common.delSuccess'
))
// 刷新列表
await
getList
()
}
catch
{
}
}
catch
{}
}
/** 导出按钮操作 */
...
...
@@ -232,7 +313,6 @@ const openDetail = (id: number) => {
push
({
name
:
'CrmContactDetail'
,
params
:
{
id
}
})
}
/** 初始化 **/
onMounted
(
async
()
=>
{
await
getList
()
...
...
src/views/crm/customer/detail/CustomerBasicInfo.vue
deleted
100644 → 0
View file @
7de0e93d
<
template
>
<el-col>
<el-row>
<span
class=
"text-xl font-bold"
>
{{
customer
.
name
}}
</span>
</el-row>
</el-col>
<el-col
class=
"mt-10px"
>
<!-- TODO 标签 -->
<!--
<Icon
icon=
"ant-design:tag-filled"
/>
-->
</el-col>
</
template
>
<
script
setup
lang=
"ts"
>
import
*
as
CustomerApi
from
'@/api/crm/customer'
const
{
customer
}
=
defineProps
<
{
customer
:
CustomerApi
.
CustomerVO
}
>
()
</
script
>
src/views/crm/customer/detail/CustomerDetailsHeader.vue
View file @
5f26c4af
...
...
@@ -3,7 +3,11 @@
<div
class=
"flex items-start justify-between"
>
<div>
<!-- 左上:客户基本信息 -->
<CustomerBasicInfo
:customer=
"customer"
/>
<el-col>
<el-row>
<span
class=
"text-xl font-bold"
>
{{
customer
.
name
}}
</span>
</el-row>
</el-col>
</div>
<div>
<!-- 右上:按钮 -->
...
...
@@ -15,29 +19,13 @@
</div>
<!-- TODO 芋艿: -->
<el-row
class=
"mt-10px"
>
<el-button>
<Icon
class=
"mr-5px"
icon=
"ph:calendar-fill"
/>
创建任务
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"carbon:email"
/>
发送邮件
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"ep:opportunity"
/>
创建商机
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"clarity:contract-line"
/>
创建合同
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"icon-park:income-one"
/>
创建回款
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"ph:calendar-fill"
/>
创建任务
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"carbon:email"
/>
发送邮件
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"ep:opportunity"
/>
创建商机
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"clarity:contract-line"
/>
创建合同
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"icon-park:income-one"
/>
创建回款
</el-button>
<el-button>
<Icon
class=
"mr-5px"
icon=
"fluent:people-team-add-20-filled"
/>
添加团队成员
<Icon
class=
"mr-5px"
icon=
"fluent:people-team-add-20-filled"
/>
添加团队成员
</el-button>
</el-row>
</div>
...
...
@@ -49,15 +37,11 @@
<el-descriptions-item
label=
"成交状态"
>
{{
customer
.
dealStatus
?
'已成交'
:
'未成交'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"负责人"
>
{{
customer
.
ownerUserName
}}
</el-descriptions-item>
<el-descriptions-item
label=
"负责人"
>
{{
customer
.
ownerUserName
}}
</el-descriptions-item>
<!-- TODO wanwan 首要联系人? -->
<el-descriptions-item
label=
"首要联系人"
/>
<!-- TODO wanwan 首要联系人电话? -->
<el-descriptions-item
label=
"首要联系人电话"
>
{{
customer
.
mobile
}}
</el-descriptions-item>
<el-descriptions-item
label=
"首要联系人电话"
>
{{
customer
.
mobile
}}
</el-descriptions-item>
</el-descriptions>
</ContentWrap>
...
...
@@ -65,15 +49,13 @@
<CustomerForm
ref=
"formRef"
@
success=
"emit('refresh')"
/>
</
template
>
<
script
setup
lang=
"ts"
>
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
{
DICT_TYPE
}
from
'@/utils/dict'
// TODO @wanwan:是不是把 CustomerBasicInfo 也放进来。
import
CustomerBasicInfo
from
'@/views/crm/customer/detail/CustomerBasicInfo.vue'
import
CustomerForm
from
'@/views/crm/customer/CustomerForm.vue'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
CustomerForm
from
'../CustomerForm.vue'
const
{
customer
,
loading
}
=
defineProps
<
{
customer
:
CustomerApi
.
CustomerVO
loading
:
boolean
customer
:
CustomerApi
.
CustomerVO
// 客户信息
loading
:
boolean
// 加载中
}
>
()
/** 修改操作 */
...
...
src/views/crm/customer/detail/CustomerDetails.vue
→
src/views/crm/customer/detail/CustomerDetails
Info
.vue
View file @
5f26c4af
...
...
@@ -18,29 +18,15 @@
<el-descriptions-item
label=
"客户等级"
>
<dict-tag
:type=
"DICT_TYPE.CRM_CUSTOMER_LEVEL"
:value=
"customer.level"
/>
</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.email }}
</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.website }}
</el-descriptions-item>
<el-descriptions-item
label=
"所在地"
>
{{ customer.areaName }}
</el-descriptions-item>
<el-descriptions-item
label=
"详细地址"
>
{{ customer.detailAddress }}
<el-descriptions-item
label=
"手机"
>
{{ customer.mobile }}
</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=
"QQ"
>
{{ customer.qq }}
</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.areaName }}
</el-descriptions-item>
<el-descriptions-item
label=
"详细地址"
>
{{ customer.detailAddress }}
</el-descriptions-item>
<el-descriptions-item
label=
"下次联系时间"
>
{{
...
...
@@ -52,12 +38,8 @@
</el-descriptions-item>
</el-descriptions>
<el-descriptions
:column=
"1"
>
<el-descriptions-item
label=
"客户描述"
>
{{ customer.description }}
</el-descriptions-item>
<el-descriptions-item
label=
"备注"
>
{{ customer.remark }}
</el-descriptions-item>
<el-descriptions-item
label=
"客户描述"
>
{{ customer.description }}
</el-descriptions-item>
<el-descriptions-item
label=
"备注"
>
{{ customer.remark }}
</el-descriptions-item>
</el-descriptions>
</el-collapse-item>
<el-collapse-item
name=
"systemInfo"
>
...
...
@@ -65,12 +47,8 @@
<span
class=
"text-base font-bold"
>
系统信息
</span>
</
template
>
<el-descriptions
:column=
"2"
>
<el-descriptions-item
label=
"负责人"
>
{{ customer.ownerUserName }}
</el-descriptions-item>
<el-descriptions-item
label=
"创建人"
>
{{ customer.creatorName }}
</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.createTime ? formatDate(customer.createTime) : '空' }}
</el-descriptions-item>
...
...
@@ -88,10 +66,9 @@ import { DICT_TYPE } from '@/utils/dict'
import
{
formatDate
}
from
'@/utils/formatTime'
const
{
customer
}
=
defineProps
<
{
customer
:
CustomerApi
.
CustomerVO
customer
:
CustomerApi
.
CustomerVO
// 客户明细
}
>
()
// 展示的折叠面板
const
activeNames
=
ref
([
'basicInfo'
,
'systemInfo'
])
const
activeNames
=
ref
([
'basicInfo'
,
'systemInfo'
])
// 展示的折叠面板
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
src/views/crm/customer/detail/index.vue
View file @
5f26c4af
<
template
>
<CustomerDetailsHeader
:customer=
"customer"
:loading=
"loading"
@
refresh=
"getCustomer
Data
(id)"
/>
<CustomerDetailsHeader
:customer=
"customer"
:loading=
"loading"
@
refresh=
"getCustomer(id)"
/>
<el-col>
<el-tabs>
<el-tab-pane
label=
"详细资料"
>
<CustomerDetails
:customer=
"customer"
/>
<CustomerDetails
Info
:customer=
"customer"
/>
</el-tab-pane>
<el-tab-pane
label=
"操作日志"
lazy
>
TODO 待开发
</el-tab-pane>
<el-tab-pane
label=
"联系人"
lazy
>
<ContactList
:biz-id=
"customer.id!"
:biz-type=
"BizTypeEnum.CRM_CUSTOMER"
/>
</el-tab-pane>
<el-tab-pane
label=
"团队成员"
lazy
>
<
Crm
PermissionList
:biz-id=
"customer.id!"
:biz-type=
"BizTypeEnum.CRM_CUSTOMER"
/>
<PermissionList
:biz-id=
"customer.id!"
:biz-type=
"BizTypeEnum.CRM_CUSTOMER"
/>
</el-tab-pane>
<el-tab-pane
label=
"商机"
lazy
>
商机
</el-tab-pane>
<el-tab-pane
label=
"合同"
lazy
>
TODO 待开发
</el-tab-pane>
...
...
@@ -20,31 +20,24 @@
</el-tabs>
</el-col>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
import
*
as
CustomerApi
from
'@/api/crm/customer'
import
CustomerDetails
from
'@/views/crm/customer/detail/CustomerDetails.vue'
import
{
CrmPermissionList
}
from
'@/views/crm/components'
import
ContactList
from
'@/views/crm/contact/components/ContactList.vue'
import
CustomerDetailsHeader
from
'./CustomerDetailsHeader.vue'
import
CustomerDetails
Info
from
'./CustomerDetailsInfo.vue'
// 客户明细 - 详细信息
import
CustomerDetailsHeader
from
'./CustomerDetailsHeader.vue'
// 客户明细 - 头部
import
ContactList
from
'@/views/crm/contact/components/ContactList.vue'
// 联系人列表
import
PermissionList
from
'@/views/crm/permission/components/PermissionList.vue'
// 权限列表
import
{
BizTypeEnum
}
from
'@/api/crm/permission'
defineOptions
({
name
:
'CustomerDetail'
})
defineOptions
({
name
:
'C
rmC
ustomerDetail'
})
const
{
delView
}
=
useTagsViewStore
()
// 视图操作
const
route
=
useRoute
()
const
{
currentRoute
}
=
useRouter
()
// 路由
const
id
=
Number
(
route
.
params
.
id
)
const
id
=
Number
(
route
.
params
.
id
)
// 客户编号
const
loading
=
ref
(
true
)
// 加载中
/**
* 获取详情
*
* @param id 客户编号
*/
/** 获取详情 */
const
customer
=
ref
<
CustomerApi
.
CustomerVO
>
({}
as
CustomerApi
.
CustomerVO
)
// 客户详情
const
getCustomer
Data
=
async
(
id
:
number
)
=>
{
const
getCustomer
=
async
(
id
:
number
)
=>
{
loading
.
value
=
true
try
{
customer
.
value
=
await
CustomerApi
.
getCustomer
(
id
)
...
...
@@ -53,15 +46,15 @@ const getCustomerData = async (id: number) => {
}
}
/**
* 初始化
*/
/**
初始化 */
const
{
delView
}
=
useTagsViewStore
()
// 视图操作
const
{
currentRoute
}
=
useRouter
()
// 路由
onMounted
(()
=>
{
if
(
!
id
)
{
ElMessage
.
warning
(
'参数错误,客户不能为空!'
)
delView
(
unref
(
currentRoute
))
return
}
getCustomer
Data
(
id
)
getCustomer
(
id
)
})
</
script
>
src/views/crm/customer/index.vue
View file @
5f26c4af
...
...
@@ -72,17 +72,10 @@
</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"
>
<Icon
class=
"mr-5px"
icon=
"ep:refresh"
/>
重置
</el-button>
<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:customer:create']"
type=
"primary"
@
click=
"openForm('create')"
>
<Icon
class=
"mr-5px"
icon=
"ep:plus"
/>
新增
<Icon
class=
"mr-5px"
icon=
"ep:plus"
/>
新增
</el-button>
<el-button
v-hasPermi=
"['crm:customer:export']"
...
...
@@ -91,8 +84,7 @@
type=
"success"
@
click=
"handleExport"
>
<Icon
class=
"mr-5px"
icon=
"ep:download"
/>
导出
<Icon
class=
"mr-5px"
icon=
"ep:download"
/>
导出
</el-button>
</el-form-item>
</el-form>
...
...
@@ -102,7 +94,13 @@
<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"
/>
<el-table-column
align=
"center"
label=
"客户名称"
prop=
"name"
width=
"160"
>
<template
#
default=
"scope"
>
<el-link
type=
"primary"
:underline=
"false"
@
click=
"openDetail(scope.row.id)"
>
{{
scope
.
row
.
name
}}
</el-link>
</
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"
/>
...
...
@@ -157,7 +155,6 @@
<!-- TODO @wanwan 距进入公海天数 -->
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
min-width=
"150"
>
<
template
#
default=
"scope"
>
<el-button
link
type=
"primary"
@
click=
"openDetail(scope.row.id)"
>
详情
</el-button>
<el-button
v-hasPermi=
"['crm:customer:update']"
link
...
...
src/views/crm/
components/Crm
PermissionForm.vue
→
src/views/crm/
permission/components/
PermissionForm.vue
View file @
5f26c4af
...
...
@@ -23,12 +23,13 @@
v-for=
"dict in getIntDictOptions(DICT_TYPE.CRM_PERMISSION_LEVEL)"
:key=
"dict.value"
>
<el-radio
v-if=
"dict.value !=
Crm
PermissionLevelEnum.OWNER"
:label=
"dict.value"
>
<el-radio
v-if=
"dict.value != PermissionLevelEnum.OWNER"
:label=
"dict.value"
>
{{
dict
.
label
}}
</el-radio>
</
template
>
</el-radio-group>
</el-form-item>
<!-- TODO @puhui999:同时添加至 -->
</el-form>
<
template
#
footer
>
<el-button
:disabled=
"formLoading"
type=
"primary"
@
click=
"submitForm"
>
确 定
</el-button>
...
...
@@ -39,8 +40,8 @@
<
script
lang=
"ts"
setup
>
import
*
as
UserApi
from
'@/api/system/user'
import
*
as
PermissionApi
from
'@/api/crm/permission'
import
{
PermissionLevelEnum
}
from
'@/api/crm/permission'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
CrmPermissionLevelEnum
}
from
'@/views/crm/components/index'
defineOptions
({
name
:
'CrmPermissionForm'
})
...
...
@@ -54,8 +55,8 @@ const formType = ref('') // 表单的类型:create - 新增;update - 修改
const
userOptions
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
const
formData
=
ref
<
PermissionApi
.
PermissionVO
&
{
ids
?:
number
[]
}
>
({
userId
:
undefined
,
// 用户编号
bizType
:
undefined
,
// C
rm
类型
bizId
:
undefined
,
// C
rm
类型数据编号
bizType
:
undefined
,
// C
RM
类型
bizId
:
undefined
,
// C
RM
类型数据编号
level
:
undefined
// 权限级别
})
const
formRules
=
reactive
({
...
...
src/views/crm/
components/Crm
PermissionList.vue
→
src/views/crm/
permission/components/
PermissionList.vue
View file @
5f26c4af
<
template
>
<!-- 操作栏 -->
<el-row
justify=
"end"
>
<el-button
type=
"primary"
@
click=
"openForm"
>
<Icon
class=
"mr-5px"
icon=
"ep:plus"
/>
新增
<el-button
@
click=
"openForm"
>
<Icon
class=
"mr-5px"
icon=
"fluent:people-team-add-20-filled"
/>
添加团队成员
</el-button>
<el-button
@
click=
"handleUpdate"
>
<Icon
class=
"mr-5px"
icon=
"ep:edit"
/>
...
...
@@ -16,47 +15,51 @@
<el-button
type=
"danger"
@
click=
"handleQuit"
>
退出团队
</el-button>
</el-row>
<!-- 团队成员展示 -->
<!-- 列表 -->
<ContentWrap
class=
"mt-10px"
>
<el-table
v-loading=
"loading"
:data=
"list"
:show-overflow-tooltip=
"true"
:stripe=
"true"
class=
"mt-20px"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
/>
<el-table-column
align=
"center"
label=
"姓名"
prop=
"nickname"
/>
<el-table-column
align=
"center"
label=
"部门"
prop=
"deptName"
/>
<el-table-column
align=
"center"
label=
"岗位"
prop=
"postNames"
/>
<el-table-column
align=
"center"
label=
"权限级别
"
prop=
"level"
>
<el-table-column
align=
"center"
label=
"权限
"
prop=
"level"
>
<template
#
default=
"
{ row }">
<dict-tag
:type=
"DICT_TYPE.CRM_PERMISSION_LEVEL"
:value=
"row.level"
/>
</
template
>
</el-table-column>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"加入时间"
prop=
"createTime"
/>
<el-table-column
:formatter=
"dateFormatter"
align=
"center"
label=
"加入时间"
prop=
"createTime"
/>
</el-table>
</ContentWrap>
<!-- 表单弹窗:添加/修改 -->
<CrmPermissionForm
ref=
"formRef"
@
success=
"getList"
/>
</template>
<
script
lang=
"ts"
setup
>
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
{
ElTable
}
from
'element-plus
'
import
{
DICT_TYPE
}
from
'@/utils/dict
'
import
*
as
PermissionApi
from
'@/api/crm/permission'
import
{
PermissionLevelEnum
}
from
'@/api/crm/permission'
import
{
useUserStoreWithOut
}
from
'@/store/modules/user'
import
CrmPermissionForm
from
'./CrmPermissionForm.vue'
import
{
CrmPermissionLevelEnum
}
from
'./index'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
CrmPermissionForm
from
'./PermissionForm.vue'
defineOptions
({
name
:
'CrmPermissionList'
})
const
message
=
useMessage
()
// 消息
const
props
=
defineProps
<
{
bizType
:
number
//
模块
类型
bizId
:
number
//
模块数据
编号
bizType
:
number
//
业务
类型
bizId
:
number
//
业务
编号
}
>
()
const
message
=
useMessage
()
// 消息
const
loading
=
ref
(
true
)
// 列表的加载中
const
list
=
ref
<
PermissionApi
.
PermissionVO
[]
>
([])
// 列表的数据
...
...
@@ -64,28 +67,34 @@ const list = ref<PermissionApi.PermissionVO[]>([]) // 列表的数据
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
await
PermissionApi
.
getPermissionList
({
list
.
value
=
await
PermissionApi
.
getPermissionList
({
bizType
:
props
.
bizType
,
bizId
:
props
.
bizId
})
list
.
value
=
data
}
finally
{
loading
.
value
=
false
}
}
/** 选中团队成员 */
const
multipleSelection
=
ref
<
PermissionApi
.
PermissionVO
[]
>
([])
// 选择的团队成员
const
handleSelectionChange
=
(
val
:
PermissionApi
.
PermissionVO
[])
=>
{
multipleSelection
.
value
=
val
}
/**
编辑
团队成员 */
/**
添加
团队成员 */
const
formRef
=
ref
<
InstanceType
<
typeof
CrmPermissionForm
>>
()
// 权限表单 Ref
const
openForm
=
()
=>
{
formRef
.
value
?.
open
(
'create'
,
props
.
bizType
,
props
.
bizId
)
}
/** 编辑团队成员 */
const
handleUpdate
=
()
=>
{
if
(
multipleSelection
.
value
?.
length
===
0
)
{
message
.
warning
(
'请先选择团队成员后操作!'
)
return
}
const
ids
=
multipleSelection
.
value
?.
map
((
item
)
=>
item
.
id
)
const
ids
=
multipleSelection
.
value
?.
map
((
item
)
=>
item
.
id
)
as
number
[]
formRef
.
value
?.
open
(
'update'
,
props
.
bizType
,
props
.
bizId
,
ids
)
}
...
...
@@ -95,36 +104,34 @@ const handleDelete = async () => {
message
.
warning
(
'请先选择团队成员后操作!'
)
return
}
// TODO @puhui999:应该有个提示哈
await
message
.
delConfirm
()
const
ids
=
multipleSelection
.
value
?.
map
((
item
)
=>
item
.
id
)
await
PermissionApi
.
deletePermission
({
await
PermissionApi
.
deletePermission
Batch
({
bizType
:
props
.
bizType
,
bizId
:
props
.
bizId
,
ids
})
}
/** 添加团队成员 */
const
openForm
=
()
=>
{
formRef
.
value
?.
open
(
'create'
,
props
.
bizType
,
props
.
bizId
)
}
/** 退出团队 */
const
userStore
=
useUserStoreWithOut
()
// 用户信息缓存
const
handleQuit
=
async
()
=>
{
const
permission
=
list
.
value
.
find
(
(
item
)
=>
item
.
userId
===
userStore
.
getUser
.
id
&&
item
.
level
===
Crm
PermissionLevelEnum
.
OWNER
(
item
)
=>
item
.
userId
===
userStore
.
getUser
.
id
&&
item
.
level
===
PermissionLevelEnum
.
OWNER
)
if
(
permission
)
{
message
.
warning
(
'负责人不能退出团队!'
)
return
}
// TODO @puhui999:应该有个提示哈
const
userPermission
=
list
.
value
.
find
((
item
)
=>
item
.
userId
===
userStore
.
getUser
.
id
)
await
PermissionApi
.
quitTeam
(
userPermission
?.
id
)
await
PermissionApi
.
deleteSelfPermission
(
userPermission
?.
id
)
}
/** 监听打开的 bizId + bizType,从而加载最新的列表 */
watch
(
()
=>
props
.
bizId
,
()
=>
[
props
.
bizId
,
props
.
bizType
]
,
()
=>
{
getList
()
},
...
...
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