CRM:完善商机和联系人之间的关联

(cherry picked from commit 8512fe6b43)
pull/420/head
YunaiV 2024-02-22 09:35:35 +08:00 committed by shizhong
parent 374f3e07d9
commit d57257e164
8 changed files with 86 additions and 37 deletions

View File

@ -47,6 +47,11 @@ export const getContactPageByCustomer = async (params: any) => {
return await request.get({ url: `/crm/contact/page-by-customer`, params })
}
// 查询 CRM 联系人列表,基于指定商机
export const getContactPageByBusiness = async (params: any) => {
return await request.get({ url: `/crm/contact/page-by-business`, params })
}
// 查询 CRM 联系人详情
export const getContact = async (id: number) => {
return await request.get({ url: `/crm/contact/get?id=` + id })

View File

@ -31,7 +31,12 @@
</el-col>
<el-col :span="8">
<el-form-item label="客户名称" prop="customerId">
<el-select v-model="formData.customerId" placeholder="请选择客户" class="w-1/1">
<el-select
:disabled="formData.customerDefault"
v-model="formData.customerId"
placeholder="请选择客户"
class="w-1/1"
>
<el-option
v-for="item in customerList"
:key="item.id"
@ -158,7 +163,9 @@ const formData = ref({
totalProductPrice: undefined,
totalPrice: undefined,
remark: undefined,
products: []
products: [],
contactId: undefined,
customerDefault: false
})
const formRules = reactive({
name: [{ required: true, message: '商机名称不能为空', trigger: 'blur' }],
@ -197,7 +204,7 @@ watch(
)
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
const open = async (type: string, id?: number, customerId?: number, contactId?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
@ -210,7 +217,17 @@ const open = async (type: string, id?: number) => {
} finally {
formLoading.value = false
}
} else {
if (customerId) {
formData.value.customerId = customerId
formData.value.customerDefault = true //
}
// contactId
if (contactId) {
formData.value.contactId = contactId
}
}
//
customerList.value = await CustomerApi.getCustomerSimpleList()
//
statusTypeList.value = await BusinessStatusApi.getBusinessStatusTypeSimpleList()
@ -264,7 +281,9 @@ const resetForm = () => {
totalProductPrice: undefined,
totalPrice: undefined,
remark: undefined,
products: []
products: [],
contactId: undefined,
customerDefault: false
}
formRef.value?.resetFields()
}

View File

@ -76,6 +76,7 @@ const props = defineProps<{
bizType: number //
bizId: number //
customerId?: number // customerId
contactId?: number //
}>()
const loading = ref(true) //
@ -125,7 +126,7 @@ const handleQuery = () => {
/** 添加操作 */
const formRef = ref()
const openForm = () => {
formRef.value.open('create')
formRef.value.open('create', null, props.customerId, props.contactId)
}
/** 打开联系人详情 */

View File

@ -15,6 +15,14 @@
<el-tab-pane label="详细资料">
<BusinessDetailsInfo :business="business" />
</el-tab-pane>
<el-tab-pane label="联系人" lazy>
<ContactList
:biz-id="business.id!"
:biz-type="BizTypeEnum.CRM_BUSINESS"
:business-id="business.id"
:customer-id="business.customerId"
/>
</el-tab-pane>
<el-tab-pane label="操作日志">
<OperateLogV2 :log-list="logList" />
</el-tab-pane>
@ -27,13 +35,6 @@
@quit-team="close"
/>
</el-tab-pane>
<el-tab-pane label="商机" lazy>
<BusinessList
:biz-id="business.id!"
:biz-type="BizTypeEnum.CRM_CONTACT"
:customer-id="business.customerId"
/>
</el-tab-pane>
</el-tabs>
</el-col>
<!-- 表单弹窗添加/修改 -->
@ -46,7 +47,6 @@ import * as ContactApi from '@/api/crm/contact'
import * as BusinessApi from '@/api/crm/business'
import BusinessDetailsHeader from './BusinessDetailsHeader.vue'
import BusinessDetailsInfo from './BusinessDetailsInfo.vue'
import BusinessList from '@/views/crm/business/components/BusinessList.vue' //
import PermissionList from '@/views/crm/permission/components/PermissionList.vue' //
import { BizTypeEnum } from '@/api/crm/permission'
import { OperateLogV2VO } from '@/api/system/operatelog'
@ -54,6 +54,7 @@ import { getOperateLogPage } from '@/api/crm/operateLog'
import ContactForm from '@/views/crm/contact/ContactForm.vue'
import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue'
import FollowUpList from '@/views/crm/followup/index.vue'
import ContactList from '@/views/crm/contact/components/ContactList.vue'
defineOptions({ name: 'CrmBusinessDetail' })

View File

@ -38,6 +38,11 @@
<!-- 列表 -->
<ContentWrap>
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="我负责的" name="1" />
<el-tab-pane label="我参与的" name="2" />
<el-tab-pane label="下属负责的" name="3" />
</el-tabs>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column align="center" label="商机名称" fixed="left" prop="name" width="160">
<template #default="scope">
@ -157,6 +162,7 @@ import download from '@/utils/download'
import * as BusinessApi from '@/api/crm/business'
import BusinessForm from './BusinessForm.vue'
import { erpPriceTableColumnFormatter } from '@/utils'
import { TabsPaneContext } from 'element-plus'
defineOptions({ name: 'CrmBusiness' })
@ -169,27 +175,12 @@ const list = ref([]) // 列表的数据
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: null,
statusTypeId: null,
statusId: null,
contactNextTime: [],
customerId: null,
dealTime: [],
price: null,
discountPercent: null,
productPrice: null,
remark: null,
ownerUserId: null,
createTime: [],
roUserIds: null,
rwUserIds: null,
endStatus: null,
endRemark: null,
contactLastTime: [],
followUpStatus: null
sceneType: '1', // activeName
name: null
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
const activeName = ref('1') // tab
/** 查询列表 */
const getList = async () => {
@ -215,6 +206,12 @@ const resetQuery = () => {
handleQuery()
}
/** tab 切换 */
const handleTabClick = (tab: TabsPaneContext) => {
queryParams.sceneType = tab.paneName
handleQuery()
}
/** 打开客户详情 */
const { currentRoute, push } = useRouter()
const openDetail = (id: number) => {

View File

@ -33,7 +33,12 @@
<el-row>
<el-col :span="12">
<el-form-item label="客户名称" prop="customerId">
<el-select v-model="formData.customerId" placeholder="请选择客户" class="w-1/1">
<el-select
:disabled="formData.customerDefault"
v-model="formData.customerId"
placeholder="请选择客户"
class="w-1/1"
>
<el-option
v-for="item in customerList"
:key="item.id"
@ -198,7 +203,9 @@ const formData = ref({
master: false,
post: undefined,
parentId: undefined,
remark: undefined
remark: undefined,
businessId: undefined,
customerDefault: false
})
const formRules = reactive({
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
@ -212,7 +219,7 @@ const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
const contactList = ref<ContactApi.ContactVO[]>([]) //
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
const open = async (type: string, id?: number, customerId?: number, businessId?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
@ -225,8 +232,19 @@ const open = async (type: string, id?: number) => {
} finally {
formLoading.value = false
}
} else {
if (customerId) {
formData.value.customerId = customerId
formData.value.customerDefault = true //
}
// businessId
if (businessId) {
formData.value.businessId = businessId
}
}
//
contactList.value = await ContactApi.getSimpleContactList()
//
customerList.value = await CustomerApi.getCustomerSimpleList()
//
areaList.value = await AreaApi.getAreaTree()
@ -284,7 +302,9 @@ const resetForm = () => {
master: false,
post: undefined,
parentId: undefined,
remark: undefined
remark: undefined,
businessId: undefined,
customerDefault: false
}
formRef.value?.resetFields()
}

View File

@ -25,7 +25,6 @@
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.master" />
</template>
</el-table-column>
<!-- TODO 芋艿操作设为首要联系人 -->
</el-table>
<!-- 分页 -->
<Pagination
@ -49,6 +48,8 @@ defineOptions({ name: 'CrmContactList' })
const props = defineProps<{
bizType: number //
bizId: number //
customerId: number //
businessId: number //
}>()
const loading = ref(true) //
@ -73,6 +74,10 @@ const getList = async () => {
queryParams.customerId = props.bizId
data = await ContactApi.getContactPageByCustomer(queryParams)
break
case BizTypeEnum.CRM_BUSINESS:
queryParams.businessId = props.bizId
data = await ContactApi.getContactPageByBusiness(queryParams)
break
default:
return
}
@ -92,7 +97,7 @@ const handleQuery = () => {
/** 添加操作 */
const formRef = ref()
const openForm = () => {
formRef.value.open('create')
formRef.value.open('create', undefined, props.customerId, props.businessId)
}
/** 打开联系人详情 */

View File

@ -32,6 +32,7 @@
:biz-id="contact.id!"
:biz-type="BizTypeEnum.CRM_CONTACT"
:customer-id="contact.customerId"
:contact-id="contact.id"
/>
</el-tab-pane>
</el-tabs>