Skip to content

Commit 9cbb3aa

Browse files
author
puhui999
committed
crm-客户:完善转移和按钮权限
1 parent 5151824 commit 9cbb3aa

File tree

4 files changed

+284
-73
lines changed

4 files changed

+284
-73
lines changed

src/api/crm/customer/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,17 @@ export const getOperateLogPage = async (id: number) => {
7575

7676
// ======================= 业务操作 =======================
7777

78+
export interface TransferReqVO {
79+
id: number | undefined // 客户编号
80+
newOwnerUserId: number | undefined // 新负责人的用户编号
81+
oldOwnerPermissionLevel: number | undefined // 老负责人加入团队后的权限级别
82+
}
83+
84+
// 客户转移
85+
export const transfer = async (data: TransferReqVO) => {
86+
return await request.put({ url: '/crm/customer/transfer', data })
87+
}
88+
7889
// 锁定/解锁客户
7990
export const lockCustomer = async (id: number, lockStatus: boolean) => {
8091
return await request.put({ url: `/crm/customer/lock`, data: { id, lockStatus } })

src/views/crm/customer/detail/index.vue

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,38 @@
11
<template>
22
<CustomerDetailsHeader :customer="customer" :loading="loading">
3-
<!-- TODO puhui999: 按钮数据权限收尾统一完善,需要按权限分级和客户状态来动态显示匹配的按钮 -->
4-
<el-button v-hasPermi="['crm:customer:update']" type="primary" @click="openForm">
3+
<el-button
4+
v-if="permissionListRef?.validateWrite"
5+
v-hasPermi="['crm:customer:update']"
6+
type="primary"
7+
@click="openForm"
8+
>
59
编辑
610
</el-button>
7-
<!-- TODO @puhui999:转移的操作接入 -->
8-
<el-button type="primary" @click="transfer">转移</el-button>
9-
<!-- TODO @puhui999:修改成交状态的接入 -->
10-
<el-button>更改成交状态</el-button>
11-
<el-button v-if="customer.lockStatus" @click="handleUnlock">解锁</el-button>
12-
<el-button v-if="!customer.lockStatus" @click="handleLock">锁定</el-button>
11+
<el-button v-if="permissionListRef?.validateOwnerUser" type="primary" @click="transfer">
12+
转移
13+
</el-button>
14+
<el-button v-if="permissionListRef?.validateWrite">更改成交状态</el-button>
15+
<el-button
16+
v-if="customer.lockStatus && permissionListRef?.validateOwnerUser"
17+
@click="handleUnlock"
18+
>
19+
解锁
20+
</el-button>
21+
<el-button
22+
v-if="!customer.lockStatus && permissionListRef?.validateOwnerUser"
23+
@click="handleLock"
24+
>
25+
锁定
26+
</el-button>
1327
<el-button v-if="!customer.ownerUserId" type="primary" @click="handleReceive">
1428
领取客户
1529
</el-button>
16-
<el-button v-if="customer.ownerUserId" @click="handlePutPool">客户放入公海</el-button>
30+
<el-button
31+
v-if="customer.ownerUserId && permissionListRef?.validateOwnerUser"
32+
@click="handlePutPool"
33+
>
34+
客户放入公海
35+
</el-button>
1736
</CustomerDetailsHeader>
1837
<el-col>
1938
<el-tabs>
@@ -30,7 +49,12 @@
3049
<ContactList :biz-id="customer.id!" :biz-type="BizTypeEnum.CRM_CUSTOMER" />
3150
</el-tab-pane>
3251
<el-tab-pane label="团队成员">
33-
<PermissionList :biz-id="customer.id!" :biz-type="BizTypeEnum.CRM_CUSTOMER" />
52+
<PermissionList
53+
ref="permissionListRef"
54+
:biz-id="customer.id!"
55+
:biz-type="BizTypeEnum.CRM_CUSTOMER"
56+
:show-action="!permissionListRef?.isPool || false"
57+
/>
3458
</el-tab-pane>
3559
<el-tab-pane label="商机" lazy>
3660
<BusinessList :biz-id="customer.id!" :biz-type="BizTypeEnum.CRM_CUSTOMER" />
@@ -48,6 +72,7 @@
4872

4973
<!-- 表单弹窗:添加/修改 -->
5074
<CustomerForm ref="formRef" @success="getCustomer" />
75+
<CrmTransferForm ref="crmTransferFormRef" @success="close" />
5176
</template>
5277
<script lang="ts" setup>
5378
import { useTagsViewStore } from '@/store/modules/tagsView'
@@ -61,6 +86,7 @@ import BusinessList from '@/views/crm/business/components/BusinessList.vue' //
6186
import ReceivableList from '@/views/crm/receivable/components/ReceivableList.vue' // 回款列表
6287
import ReceivablePlanList from '@/views/crm/receivable/plan/components/ReceivablePlanList.vue' // 回款计划列表
6388
import PermissionList from '@/views/crm/permission/components/PermissionList.vue' // 团队成员列表(权限)
89+
import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue'
6490
import FollowUpList from '@/views/crm/followup/index.vue'
6591
import { BizTypeEnum } from '@/api/crm/permission'
6692
import type { OperateLogV2VO } from '@/api/system/operatelog'
@@ -73,6 +99,8 @@ const message = useMessage() // 消息弹窗
7399
const { delView } = useTagsViewStore() // 视图操作
74100
const { currentRoute } = useRouter() // 路由
75101
102+
const permissionListRef = ref<InstanceType<typeof PermissionList>>() // 团队成员列表 Ref
103+
76104
/** 获取详情 */
77105
const customer = ref<CustomerApi.CustomerVO>({} as CustomerApi.CustomerVO) // 客户详情
78106
const getCustomer = async () => {
@@ -92,7 +120,10 @@ const openForm = () => {
92120
}
93121
94122
/** 客户转移 */
95-
const transfer = () => {}
123+
const crmTransferFormRef = ref<InstanceType<typeof CrmTransferForm>>() // 客户转移表单 ref
124+
const transfer = () => {
125+
crmTransferFormRef.value?.open('客户转移', customerId.value, CustomerApi.transfer)
126+
}
96127
97128
/** 锁定客户 */
98129
const handleLock = async () => {

src/views/crm/permission/components/PermissionList.vue

Lines changed: 110 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,112 @@
11
<template>
22
<!-- 操作栏 -->
3-
<el-row justify="end">
4-
<el-button @click="openForm">
5-
<Icon class="mr-5px" icon="fluent:people-team-add-20-filled" />
6-
添加团队成员
3+
<el-row v-if="showAction" justify="end">
4+
<el-button v-if="validateOwnerUser" type="primary" @click="openForm">
5+
<Icon class="mr-5px" icon="ep:plus" />
6+
新增
77
</el-button>
8-
<el-button @click="handleUpdate">
8+
<el-button v-if="validateOwnerUser" @click="handleUpdate">
99
<Icon class="mr-5px" icon="ep:edit" />
1010
编辑
1111
</el-button>
12-
<el-button @click="handleDelete">
12+
<el-button v-if="validateOwnerUser" @click="handleDelete">
1313
<Icon class="mr-5px" icon="ep:delete" />
1414
移除
1515
</el-button>
16-
<el-button type="danger" @click="handleQuit"> 退出团队</el-button>
16+
<el-button v-if="!validateOwnerUser && list.length > 0" type="danger" @click="handleQuit">
17+
退出团队
18+
</el-button>
1719
</el-row>
18-
19-
<!-- 列表 -->
20-
<ContentWrap class="mt-10px">
21-
<el-table
22-
v-loading="loading"
23-
:data="list"
24-
:show-overflow-tooltip="true"
25-
:stripe="true"
26-
@selection-change="handleSelectionChange"
27-
>
28-
<!-- TODO @puhui999:负责人不允许选中 -->
29-
<el-table-column type="selection" width="55" />
30-
<el-table-column align="center" label="姓名" prop="nickname" />
31-
<el-table-column align="center" label="部门" prop="deptName" />
32-
<el-table-column align="center" label="岗位" prop="postNames" />
33-
<el-table-column align="center" label="权限" prop="level">
34-
<template #default="{ row }">
35-
<dict-tag :type="DICT_TYPE.CRM_PERMISSION_LEVEL" :value="row.level" />
36-
</template>
37-
</el-table-column>
38-
<el-table-column
39-
:formatter="dateFormatter"
40-
align="center"
41-
label="加入时间"
42-
prop="createTime"
43-
/>
44-
</el-table>
45-
</ContentWrap>
20+
<!-- 团队成员展示 -->
21+
<el-table
22+
ref="elTableRef"
23+
v-loading="loading"
24+
:data="list"
25+
:show-overflow-tooltip="true"
26+
:stripe="true"
27+
class="mt-20px"
28+
@selection-change="handleSelectionChange"
29+
>
30+
<el-table-column type="selection" width="55" />
31+
<el-table-column align="center" label="姓名" prop="nickname" />
32+
<el-table-column align="center" label="部门" prop="deptName" />
33+
<el-table-column align="center" label="岗位" prop="postNames" />
34+
<el-table-column align="center" label="权限级别" prop="level">
35+
<template #default="{ row }">
36+
<dict-tag :type="DICT_TYPE.CRM_PERMISSION_LEVEL" :value="row.level" />
37+
</template>
38+
</el-table-column>
39+
<el-table-column :formatter="dateFormatter" align="center" label="加入时间" prop="createTime" />
40+
</el-table>
4641

4742
<!-- 表单弹窗:添加/修改 -->
4843
<CrmPermissionForm ref="formRef" @success="getList" />
4944
</template>
5045
<script lang="ts" setup>
5146
import { dateFormatter } from '@/utils/formatTime'
52-
import { DICT_TYPE } from '@/utils/dict'
47+
import { ElTable } from 'element-plus'
5348
import * as PermissionApi from '@/api/crm/permission'
54-
import { PermissionLevelEnum } from '@/api/crm/permission'
5549
import { useUserStoreWithOut } from '@/store/modules/user'
5650
import CrmPermissionForm from './PermissionForm.vue'
51+
import { DICT_TYPE } from '@/utils/dict'
5752
5853
defineOptions({ name: 'CrmPermissionList' })
59-
const props = defineProps<{
60-
bizType: number // 业务类型
61-
bizId: number // 业务编号
62-
}>()
6354
6455
const message = useMessage() // 消息
56+
57+
const props = defineProps<{
58+
bizType: number // 模块类型
59+
bizId: number | undefined // 模块数据编号
60+
showAction: boolean //是否展示操作按钮
61+
}>()
6562
const loading = ref(true) // 列表的加载中
6663
const list = ref<PermissionApi.PermissionVO[]>([]) // 列表的数据
64+
const formData = ref({
65+
ownerUserId: 0
66+
})
67+
const userStore = useUserStoreWithOut() // 用户信息缓存
6768
6869
/** 查询列表 */
6970
const getList = async () => {
7071
loading.value = true
7172
try {
72-
list.value = await PermissionApi.getPermissionList({
73+
const data = await PermissionApi.getPermissionList({
7374
bizType: props.bizType,
7475
bizId: props.bizId
7576
})
77+
list.value = data
78+
const permission = list.value.find(
79+
(item) =>
80+
item.userId === userStore.getUser.id &&
81+
item.level === PermissionApi.PermissionLevelEnum.OWNER
82+
)
83+
if (permission) {
84+
formData.value.ownerUserId = userStore.getUser.id
85+
}
7686
} finally {
7787
loading.value = false
7888
}
7989
}
80-
81-
/** 选中团队成员 */
8290
const multipleSelection = ref<PermissionApi.PermissionVO[]>([]) // 选择的团队成员
91+
const elTableRef = ref<InstanceType<typeof ElTable>>()
8392
const handleSelectionChange = (val: PermissionApi.PermissionVO[]) => {
93+
if (val.findIndex((item) => item.level === PermissionApi.PermissionLevelEnum.OWNER) !== -1) {
94+
message.warning('不能选择负责人!')
95+
elTableRef.value?.clearSelection()
96+
return
97+
}
8498
multipleSelection.value = val
8599
}
86100
87-
/** 添加团队成员 */
88-
const formRef = ref<InstanceType<typeof CrmPermissionForm>>() // 权限表单 Ref
89-
const openForm = () => {
90-
formRef.value?.open('create', props.bizType, props.bizId)
91-
}
92-
93101
/** 编辑团队成员 */
102+
const formRef = ref<InstanceType<typeof CrmPermissionForm>>() // 权限表单 Ref
94103
const handleUpdate = () => {
95104
if (multipleSelection.value?.length === 0) {
96105
message.warning('请先选择团队成员后操作!')
97106
return
98107
}
99-
const ids = multipleSelection.value?.map((item) => item.id) as number[]
100-
formRef.value?.open('update', props.bizType, props.bizId, ids)
108+
const ids = multipleSelection.value?.map((item) => item.id) as unknown as number[]
109+
formRef.value?.open('update', props.bizType, props.bizId!, ids)
101110
}
102111
103112
/** 移除团队成员 */
@@ -106,36 +115,75 @@ const handleDelete = async () => {
106115
message.warning('请先选择团队成员后操作!')
107116
return
108117
}
109-
await message.delConfirm('是否删除选择的团队成员?')
118+
await message.delConfirm()
110119
const ids = multipleSelection.value?.map((item) => item.id)
111120
await PermissionApi.deletePermissionBatch({
112121
bizType: props.bizType,
113122
bizId: props.bizId,
114123
ids
115124
})
116-
message.success('删除成功')
117125
}
118126
127+
/** 添加团队成员 */
128+
const openForm = () => {
129+
formRef.value?.open('create', props.bizType, props.bizId!)
130+
}
131+
132+
// 校验负责人权限和编辑权限
133+
const validateOwnerUser = ref(false)
134+
const validateWrite = ref(false)
135+
const isPool = ref(false)
136+
watch(
137+
list,
138+
(newArr) => {
139+
isPool.value = false
140+
if (newArr?.length > 0) {
141+
isPool.value = !list.value.some(
142+
(item) => item.level === PermissionApi.PermissionLevelEnum.OWNER
143+
)
144+
validateOwnerUser.value = false
145+
validateWrite.value = false
146+
const userId = userStore.getUser?.id
147+
list.value
148+
.filter((item) => item.userId === userId)
149+
.forEach((item) => {
150+
if (item.level === PermissionApi.PermissionLevelEnum.OWNER) {
151+
validateOwnerUser.value = true
152+
validateWrite.value = true
153+
} else if (item.level === PermissionApi.PermissionLevelEnum.WRITE) {
154+
validateWrite.value = true
155+
}
156+
})
157+
} else {
158+
isPool.value = true
159+
}
160+
},
161+
{
162+
immediate: true
163+
}
164+
)
165+
166+
defineExpose({ openForm, validateOwnerUser, validateWrite, isPool })
119167
/** 退出团队 */
120-
const userStore = useUserStoreWithOut() // 用户信息缓存
121168
const handleQuit = async () => {
122169
const permission = list.value.find(
123-
(item) => item.userId === userStore.getUser.id && item.level === PermissionLevelEnum.OWNER
170+
(item) =>
171+
item.userId === userStore.getUser.id && item.level === PermissionApi.PermissionLevelEnum.OWNER
124172
)
125173
if (permission) {
126174
message.warning('负责人不能退出团队!')
127175
return
128176
}
129-
await message.confirm('确认退出团队吗?')
130177
const userPermission = list.value.find((item) => item.userId === userStore.getUser.id)
131-
await PermissionApi.deleteSelfPermission(userPermission?.id)
178+
if (userPermission) {
179+
await PermissionApi.deleteSelfPermission(userPermission.id!)
180+
}
132181
}
133182
134-
/** 监听打开的 bizId + bizType,从而加载最新的列表 */
135183
watch(
136-
() => [props.bizId, props.bizType],
137-
(val) => {
138-
if (!val[0]) {
184+
() => props.bizId,
185+
(bizId) => {
186+
if (!bizId) {
139187
return
140188
}
141189
getList()

0 commit comments

Comments
 (0)