Skip to content

Commit 28eb237

Browse files
committed
✨ CRM:完善 CRM 跟进记录(商机的展示、添加)
1 parent a9e4ef9 commit 28eb237

File tree

10 files changed

+161
-243
lines changed

10 files changed

+161
-243
lines changed

src/api/crm/business/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,6 @@ export const getBusinessPageByContact = async (params) => {
9292
return await request.get({ url: `/crm/business/page-by-contact`, params })
9393
}
9494

95-
// 获得 CRM 商机列表
96-
export const getBusinessListByIds = async (val: number[]) => {
97-
return await request.get({ url: '/crm/business/list-by-ids', params: { ids: val.join(',') } })
98-
}
99-
10095
// 商机转移
10196
export const transferBusiness = async (data: TransferReqVO) => {
10297
return await request.put({ url: '/crm/business/transfer', data })

src/api/crm/followup/index.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,17 @@ export interface FollowUpRecordVO {
1111
fileUrls: string[] // 附件
1212
nextTime: Date // 下次联系时间
1313
businessIds: number[] // 关联的商机编号数组
14+
businesses: {
15+
id: number
16+
name: string
17+
}[] // 关联的商机数组
1418
contactIds: number[] // 关联的联系人编号数组
19+
contacts: {
20+
id: number
21+
name: string
22+
}[] // 关联的联系人数组
23+
creator: string
24+
creatorName?: string
1525
}
1626

1727
// 跟进记录 API
@@ -21,28 +31,13 @@ export const FollowUpRecordApi = {
2131
return await request.get({ url: `/crm/follow-up-record/page`, params })
2232
},
2333

24-
// 查询跟进记录详情
25-
getFollowUpRecord: async (id: number) => {
26-
return await request.get({ url: `/crm/follow-up-record/get?id=` + id })
27-
},
28-
2934
// 新增跟进记录
3035
createFollowUpRecord: async (data: FollowUpRecordVO) => {
3136
return await request.post({ url: `/crm/follow-up-record/create`, data })
3237
},
3338

34-
// 修改跟进记录
35-
updateFollowUpRecord: async (data: FollowUpRecordVO) => {
36-
return await request.put({ url: `/crm/follow-up-record/update`, data })
37-
},
38-
3939
// 删除跟进记录
4040
deleteFollowUpRecord: async (id: number) => {
4141
return await request.delete({ url: `/crm/follow-up-record/delete?id=` + id })
42-
},
43-
44-
// 导出跟进记录 Excel
45-
exportFollowUpRecord: async (params) => {
46-
return await request.download({ url: `/crm/follow-up-record/export-excel`, params })
4742
}
4843
}

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
<el-table-column
4949
label="商机金额"
5050
align="center"
51-
prop="price"
52-
:formatter="erpPriceInputFormatter"
51+
prop="totalPrice"
52+
:formatter="erpPriceTableColumnFormatter"
5353
/>
5454
<el-table-column label="客户名称" align="center" prop="customerName" />
5555
<el-table-column label="商机组" align="center" prop="statusTypeName" />
@@ -75,7 +75,7 @@
7575
<script setup lang="ts">
7676
import * as BusinessApi from '@/api/crm/business'
7777
import BusinessForm from '../BusinessForm.vue'
78-
import { erpPriceInputFormatter } from '@/utils'
78+
import { erpPriceTableColumnFormatter } from '@/utils'
7979
8080
const message = useMessage() // 消息弹窗
8181
const props = defineProps<{
@@ -99,6 +99,7 @@ const queryParams = reactive({
9999
/** 打开弹窗 */
100100
const open = async () => {
101101
dialogVisible.value = true
102+
queryParams.customerId = props.customerId // 解决 props.customerId 没更新到 queryParams 上的问题
102103
await getList()
103104
}
104105
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
@@ -144,7 +145,7 @@ const submitForm = async () => {
144145
return message.error('未选择商机')
145146
}
146147
dialogVisible.value = false
147-
emit('success', businessIds)
148+
emit('success', businessIds, businessRef.value.getSelectionRows())
148149
}
149150
150151
/** 打开联系人详情 */

src/views/crm/followup/FollowUpRecordForm.vue

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- 跟进记录的添加表单弹窗 -->
22
<template>
3-
<Dialog v-model="dialogVisible" :title="dialogTitle" width="50%">
3+
<Dialog v-model="dialogVisible" title="添加跟进记录" width="50%">
44
<el-form
55
ref="formRef"
66
v-loading="formLoading"
@@ -36,17 +36,17 @@
3636
<el-input v-model="formData.content" :rows="3" type="textarea" />
3737
</el-form-item>
3838
</el-col>
39-
<el-col :span="24">
40-
<el-form-item label="图片" prop="content">
39+
<el-col :span="12">
40+
<el-form-item label="图片" prop="picUrls">
4141
<UploadImgs v-model="formData.picUrls" class="min-w-80px" />
4242
</el-form-item>
4343
</el-col>
44-
<el-col :span="24">
45-
<el-form-item label="附件" prop="content">
44+
<el-col :span="12">
45+
<el-form-item label="附件" prop="fileUrls">
4646
<UploadFile v-model="formData.fileUrls" class="min-w-80px" />
4747
</el-form-item>
4848
</el-col>
49-
<el-col :span="24">
49+
<el-col :span="24" v-if="formData.bizType == BizTypeEnum.CRM_CUSTOMER">
5050
<el-form-item label="关联联系人" prop="contactIds">
5151
<el-button @click="handleAddContact">
5252
<Icon class="mr-5px" icon="ep:plus" />
@@ -55,13 +55,13 @@
5555
<contact-list v-model:contactIds="formData.contactIds" />
5656
</el-form-item>
5757
</el-col>
58-
<el-col :span="24">
58+
<el-col :span="24" v-if="formData.bizType == BizTypeEnum.CRM_CUSTOMER">
5959
<el-form-item label="关联商机" prop="businessIds">
60-
<el-button @click="handleAddBusiness">
60+
<el-button @click="handleOpenBusiness">
6161
<Icon class="mr-5px" icon="ep:plus" />
6262
添加商机
6363
</el-button>
64-
<business-list v-model:businessIds="formData.businessIds" />
64+
<FollowUpRecordBusinessForm :businesses="formData.businesses" />
6565
</el-form-item>
6666
</el-col>
6767
</el-row>
@@ -71,13 +71,23 @@
7171
<el-button @click="dialogVisible = false">取 消</el-button>
7272
</template>
7373
</Dialog>
74+
75+
<!-- 弹窗 -->
7476
<ContactTableSelect ref="contactTableSelectRef" v-model="formData.contactIds" />
75-
<BusinessTableSelect ref="businessTableSelectRef" v-model="formData.businessIds" />
77+
<BusinessListModal
78+
ref="businessTableSelectRef"
79+
:customer-id="formData.bizId"
80+
@success="handleAddBusiness"
81+
/>
7682
</template>
7783
<script lang="ts" setup>
7884
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
7985
import { FollowUpRecordApi, FollowUpRecordVO } from '@/api/crm/followup'
80-
import { BusinessList, BusinessTableSelect, ContactList, ContactTableSelect } from './components'
86+
import { ContactList, ContactTableSelect } from './components'
87+
import { BizTypeEnum } from '@/api/crm/permission'
88+
import FollowUpRecordBusinessForm from './components/FollowUpRecordBusinessForm.vue'
89+
import BusinessListModal from '@/views/crm/business/components/BusinessListModal.vue'
90+
import * as BusinessApi from '@/api/crm/business'
8191
8292
defineOptions({ name: 'FollowUpRecordForm' })
8393
@@ -87,8 +97,12 @@ const message = useMessage() // 消息弹窗
8797
const dialogVisible = ref(false) // 弹窗的是否展示
8898
const dialogTitle = ref('') // 弹窗的标题
8999
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
90-
const formType = ref('') // 表单的类型:create - 新增;update - 修改
91-
const formData = ref<FollowUpRecordVO>({} as FollowUpRecordVO)
100+
const formData = ref({
101+
bizType: undefined,
102+
bizId: undefined,
103+
businesses: [],
104+
contacts: []
105+
})
92106
const formRules = reactive({
93107
type: [{ required: true, message: '跟进类型不能为空', trigger: 'change' }],
94108
content: [{ required: true, message: '跟进内容不能为空', trigger: 'blur' }],
@@ -98,22 +112,11 @@ const formRules = reactive({
98112
const formRef = ref() // 表单 Ref
99113
100114
/** 打开弹窗 */
101-
const open = async (bizType: number, bizId: number, type: string, id?: number) => {
115+
const open = async (bizType: number, bizId: number) => {
102116
dialogVisible.value = true
103-
dialogTitle.value = t('action.' + type)
104-
formType.value = type
105117
resetForm()
106118
formData.value.bizType = bizType
107119
formData.value.bizId = bizId
108-
// 修改时,设置数据
109-
if (id) {
110-
formLoading.value = true
111-
try {
112-
formData.value = await FollowUpRecordApi.getFollowUpRecord(id)
113-
} finally {
114-
formLoading.value = false
115-
}
116-
}
117120
}
118121
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
119122
@@ -126,13 +129,8 @@ const submitForm = async () => {
126129
formLoading.value = true
127130
try {
128131
const data = formData.value as unknown as FollowUpRecordVO
129-
if (formType.value === 'create') {
130-
await FollowUpRecordApi.createFollowUpRecord(data)
131-
message.success(t('common.createSuccess'))
132-
} else {
133-
await FollowUpRecordApi.updateFollowUpRecord(data)
134-
message.success(t('common.updateSuccess'))
135-
}
132+
await FollowUpRecordApi.createFollowUpRecord(data)
133+
message.success(t('common.createSuccess'))
136134
dialogVisible.value = false
137135
// 发送操作成功的事件
138136
emit('success')
@@ -148,14 +146,26 @@ const handleAddContact = () => {
148146
}
149147
150148
/** 关联商机 */
151-
const businessTableSelectRef = ref<InstanceType<typeof BusinessTableSelect>>()
152-
const handleAddBusiness = () => {
149+
const businessTableSelectRef = ref<InstanceType<typeof BusinessListModal>>()
150+
const handleOpenBusiness = () => {
153151
businessTableSelectRef.value?.open()
154152
}
153+
const handleAddBusiness = (businessId: [], newBusinesses: BusinessApi.BusinessVO[]) => {
154+
newBusinesses.forEach((business) => {
155+
if (!formData.value.businesses.some((item) => item.id === business.id)) {
156+
formData.value.businesses.push(business)
157+
}
158+
})
159+
}
155160
156161
/** 重置表单 */
157162
const resetForm = () => {
158163
formRef.value?.resetFields()
159-
formData.value = {} as FollowUpRecordVO
164+
formData.value = {
165+
bizId: undefined,
166+
bizType: undefined,
167+
businesses: [],
168+
contacts: []
169+
}
160170
}
161171
</script>

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

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

0 commit comments

Comments
 (0)