Skip to content

Commit 7164ae5

Browse files
committed
✨ CRM:完善 CRM 跟进记录(联系人的展示、添加)
1 parent 28eb237 commit 7164ae5

File tree

10 files changed

+228
-210
lines changed

10 files changed

+228
-210
lines changed

src/api/crm/contact/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,6 @@ export const getSimpleContactList = async () => {
8282
return await request.get({ url: `/crm/contact/simple-all-list` })
8383
}
8484

85-
// 获得 CRM 联系人列表
86-
export const getContactListByIds = async (val: number[]) => {
87-
return await request.get({ url: '/crm/contact/list-by-ids', params: { ids: val.join(',') } })
88-
}
89-
9085
// 批量新增联系人商机关联
9186
export const createContactBusinessList = async (data: ContactBusinessReqVO) => {
9287
return await request.post({ url: `/crm/contact/create-business-list`, data })

src/views/crm/business/components/BusinessListModal.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ const submitForm = async () => {
148148
emit('success', businessIds, businessRef.value.getSelectionRows())
149149
}
150150
151-
/** 打开联系人详情 */
151+
/** 打开商机详情 */
152152
const { push } = useRouter()
153153
const openDetail = (id: number) => {
154154
push({ name: 'CrmBusinessDetail', params: { id } })

src/views/crm/contact/components/ContactList.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<el-table-column label="手机号" align="center" prop="mobile" />
2121
<el-table-column label="职位" align="center" prop="post" />
2222
<el-table-column label="直属上级" align="center" prop="parentName" />
23-
<el-table-column label="是否关键决策人" align="center" prop="master">
23+
<el-table-column label="是否关键决策人" align="center" prop="master" min-width="100">
2424
<template #default="scope">
2525
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.master" />
2626
</template>
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<template>
2+
<Dialog title="关联联系人" v-model="dialogVisible">
3+
<!-- 搜索工作栏 -->
4+
<ContentWrap>
5+
<el-form
6+
class="-mb-15px"
7+
:model="queryParams"
8+
ref="queryFormRef"
9+
:inline="true"
10+
label-width="90px"
11+
>
12+
<el-form-item label="联系人名称" prop="name">
13+
<el-input
14+
v-model="queryParams.name"
15+
placeholder="请输入联系人名称"
16+
clearable
17+
@keyup.enter="handleQuery"
18+
class="!w-240px"
19+
/>
20+
</el-form-item>
21+
<el-form-item>
22+
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
23+
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
24+
<el-button type="primary" @click="openForm()" v-hasPermi="['crm:business:create']">
25+
<Icon icon="ep:plus" class="mr-5px" /> 新增
26+
</el-button>
27+
</el-form-item>
28+
</el-form>
29+
</ContentWrap>
30+
31+
<!-- 列表 -->
32+
<ContentWrap class="mt-10px">
33+
<el-table
34+
v-loading="loading"
35+
ref="contactRef"
36+
:data="list"
37+
:stripe="true"
38+
:show-overflow-tooltip="true"
39+
>
40+
<el-table-column type="selection" width="55" />
41+
<el-table-column label="姓名" fixed="left" align="center" prop="name">
42+
<template #default="scope">
43+
<el-link type="primary" :underline="false" @click="openDetail(scope.row.id)">
44+
{{ scope.row.name }}
45+
</el-link>
46+
</template>
47+
</el-table-column>
48+
<el-table-column label="手机号" align="center" prop="mobile" />
49+
<el-table-column label="职位" align="center" prop="post" />
50+
<el-table-column label="直属上级" align="center" prop="parentName" />
51+
<el-table-column label="是否关键决策人" align="center" prop="master" min-width="100">
52+
<template #default="scope">
53+
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.master" />
54+
</template>
55+
</el-table-column>
56+
</el-table>
57+
<!-- 分页 -->
58+
<Pagination
59+
:total="total"
60+
v-model:page="queryParams.pageNo"
61+
v-model:limit="queryParams.pageSize"
62+
@pagination="getList"
63+
/>
64+
</ContentWrap>
65+
<template #footer>
66+
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
67+
<el-button @click="dialogVisible = false">取 消</el-button>
68+
</template>
69+
70+
<!-- 表单弹窗:添加 -->
71+
<ContactForm ref="formRef" @success="getList" />
72+
</Dialog>
73+
</template>
74+
<script setup lang="ts">
75+
import * as ContactApi from '@/api/crm/contact'
76+
import ContactForm from '../ContactForm.vue'
77+
import { erpPriceTableColumnFormatter } from '@/utils'
78+
import { DICT_TYPE } from '@/utils/dict'
79+
80+
const message = useMessage() // 消息弹窗
81+
const props = defineProps<{
82+
customerId: number
83+
}>()
84+
defineOptions({ name: 'ContactListModal' })
85+
86+
const dialogVisible = ref(false) // 弹窗的是否展示
87+
const loading = ref(true) // 列表的加载中
88+
const total = ref(0) // 列表的总页数
89+
const list = ref([]) // 列表的数据
90+
const queryFormRef = ref() // 搜索的表单
91+
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
92+
const queryParams = reactive({
93+
pageNo: 1,
94+
pageSize: 10,
95+
name: undefined,
96+
customerId: props.customerId
97+
})
98+
99+
/** 打开弹窗 */
100+
const open = async () => {
101+
dialogVisible.value = true
102+
queryParams.customerId = props.customerId // 解决 props.customerId 没更新到 queryParams 上的问题
103+
await getList()
104+
}
105+
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
106+
107+
/** 查询列表 */
108+
const getList = async () => {
109+
loading.value = true
110+
try {
111+
const data = await ContactApi.getContactPageByCustomer(queryParams)
112+
list.value = data.list
113+
total.value = data.total
114+
} finally {
115+
loading.value = false
116+
}
117+
}
118+
119+
/** 搜索按钮操作 */
120+
const handleQuery = () => {
121+
queryParams.pageNo = 1
122+
getList()
123+
}
124+
125+
/** 重置按钮操作 */
126+
const resetQuery = () => {
127+
queryFormRef.value.resetFields()
128+
handleQuery()
129+
}
130+
131+
/** 添加操作 */
132+
const formRef = ref()
133+
const openForm = () => {
134+
formRef.value.open('create')
135+
}
136+
137+
/** 关联联系人提交 */
138+
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
139+
const contactRef = ref()
140+
const submitForm = async () => {
141+
const contactIds = contactRef.value.getSelectionRows().map((row: ContactApi.ContactVO) => row.id)
142+
if (contactIds.length === 0) {
143+
return message.error('未选择联系人')
144+
}
145+
dialogVisible.value = false
146+
emit('success', contactIds, contactRef.value.getSelectionRows())
147+
}
148+
149+
/** 打开联系人详情 */
150+
const { push } = useRouter()
151+
const openDetail = (id: number) => {
152+
push({ name: 'CrmContactDetail', params: { id } })
153+
}
154+
</script>

src/views/crm/followup/FollowUpRecordForm.vue

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@
4848
</el-col>
4949
<el-col :span="24" v-if="formData.bizType == BizTypeEnum.CRM_CUSTOMER">
5050
<el-form-item label="关联联系人" prop="contactIds">
51-
<el-button @click="handleAddContact">
51+
<el-button @click="handleOpenContact">
5252
<Icon class="mr-5px" icon="ep:plus" />
5353
添加联系人
5454
</el-button>
55-
<contact-list v-model:contactIds="formData.contactIds" />
55+
<FollowUpRecordContactForm :contacts="formData.contacts" />
5656
</el-form-item>
5757
</el-col>
5858
<el-col :span="24" v-if="formData.bizType == BizTypeEnum.CRM_CUSTOMER">
@@ -73,7 +73,11 @@
7373
</Dialog>
7474

7575
<!-- 弹窗 -->
76-
<ContactTableSelect ref="contactTableSelectRef" v-model="formData.contactIds" />
76+
<ContactListModal
77+
ref="contactTableSelectRef"
78+
:customer-id="formData.bizId"
79+
@success="handleAddContact"
80+
/>
7781
<BusinessListModal
7882
ref="businessTableSelectRef"
7983
:customer-id="formData.bizId"
@@ -83,11 +87,13 @@
8387
<script lang="ts" setup>
8488
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
8589
import { FollowUpRecordApi, FollowUpRecordVO } from '@/api/crm/followup'
86-
import { ContactList, ContactTableSelect } from './components'
8790
import { BizTypeEnum } from '@/api/crm/permission'
8891
import FollowUpRecordBusinessForm from './components/FollowUpRecordBusinessForm.vue'
92+
import FollowUpRecordContactForm from './components/FollowUpRecordContactForm.vue'
8993
import BusinessListModal from '@/views/crm/business/components/BusinessListModal.vue'
9094
import * as BusinessApi from '@/api/crm/business'
95+
import ContactListModal from '@/views/crm/contact/components/ContactListModal.vue'
96+
import * as ContactApi from '@/api/crm/contact'
9197
9298
defineOptions({ name: 'FollowUpRecordForm' })
9399
@@ -128,7 +134,11 @@ const submitForm = async () => {
128134
// 提交请求
129135
formLoading.value = true
130136
try {
131-
const data = formData.value as unknown as FollowUpRecordVO
137+
const data = {
138+
...formData.value,
139+
contactIds: formData.value.contacts.map((item) => item.id),
140+
businessIds: formData.value.businesses.map((item) => item.id)
141+
} as unknown as FollowUpRecordVO
132142
await FollowUpRecordApi.createFollowUpRecord(data)
133143
message.success(t('common.createSuccess'))
134144
dialogVisible.value = false
@@ -140,10 +150,17 @@ const submitForm = async () => {
140150
}
141151
142152
/** 关联联系人 */
143-
const contactTableSelectRef = ref<InstanceType<typeof ContactTableSelect>>()
144-
const handleAddContact = () => {
153+
const contactTableSelectRef = ref<InstanceType<typeof ContactListModal>>()
154+
const handleOpenContact = () => {
145155
contactTableSelectRef.value?.open()
146156
}
157+
const handleAddContact = (contactId: [], newContacts: ContactApi.ContactVO[]) => {
158+
newContacts.forEach((contact) => {
159+
if (!formData.value.contacts.some((item) => item.id === contact.id)) {
160+
formData.value.contacts.push(contact)
161+
}
162+
})
163+
}
147164
148165
/** 关联商机 */
149166
const businessTableSelectRef = ref<InstanceType<typeof BusinessListModal>>()

src/views/crm/followup/components/ContactList.vue

Lines changed: 0 additions & 97 deletions
This file was deleted.

0 commit comments

Comments
 (0)