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

This commit is contained in:
YunaiV 2024-02-22 09:35:35 +08:00
parent 01684aa6e8
commit 8512fe6b43
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 }) 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 联系人详情 // 查询 CRM 联系人详情
export const getContact = async (id: number) => { export const getContact = async (id: number) => {
return await request.get({ url: `/crm/contact/get?id=` + id }) return await request.get({ url: `/crm/contact/get?id=` + id })

View File

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

View File

@ -76,6 +76,7 @@ const props = defineProps<{
bizType: number // bizType: number //
bizId: number // bizId: number //
customerId?: number // customerId customerId?: number // customerId
contactId?: number //
}>() }>()
const loading = ref(true) // const loading = ref(true) //
@ -125,7 +126,7 @@ const handleQuery = () => {
/** 添加操作 */ /** 添加操作 */
const formRef = ref() const formRef = ref()
const openForm = () => { 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="详细资料"> <el-tab-pane label="详细资料">
<BusinessDetailsInfo :business="business" /> <BusinessDetailsInfo :business="business" />
</el-tab-pane> </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="操作日志"> <el-tab-pane label="操作日志">
<OperateLogV2 :log-list="logList" /> <OperateLogV2 :log-list="logList" />
</el-tab-pane> </el-tab-pane>
@ -27,13 +35,6 @@
@quit-team="close" @quit-team="close"
/> />
</el-tab-pane> </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-tabs>
</el-col> </el-col>
<!-- 表单弹窗添加/修改 --> <!-- 表单弹窗添加/修改 -->
@ -46,7 +47,6 @@ import * as ContactApi from '@/api/crm/contact'
import * as BusinessApi from '@/api/crm/business' import * as BusinessApi from '@/api/crm/business'
import BusinessDetailsHeader from './BusinessDetailsHeader.vue' import BusinessDetailsHeader from './BusinessDetailsHeader.vue'
import BusinessDetailsInfo from './BusinessDetailsInfo.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 PermissionList from '@/views/crm/permission/components/PermissionList.vue' //
import { BizTypeEnum } from '@/api/crm/permission' import { BizTypeEnum } from '@/api/crm/permission'
import { OperateLogV2VO } from '@/api/system/operatelog' 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 ContactForm from '@/views/crm/contact/ContactForm.vue'
import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue' import CrmTransferForm from '@/views/crm/permission/components/TransferForm.vue'
import FollowUpList from '@/views/crm/followup/index.vue' import FollowUpList from '@/views/crm/followup/index.vue'
import ContactList from '@/views/crm/contact/components/ContactList.vue'
defineOptions({ name: 'CrmBusinessDetail' }) defineOptions({ name: 'CrmBusinessDetail' })

View File

@ -38,6 +38,11 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <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 v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column align="center" label="商机名称" fixed="left" prop="name" width="160"> <el-table-column align="center" label="商机名称" fixed="left" prop="name" width="160">
<template #default="scope"> <template #default="scope">
@ -157,6 +162,7 @@ import download from '@/utils/download'
import * as BusinessApi from '@/api/crm/business' import * as BusinessApi from '@/api/crm/business'
import BusinessForm from './BusinessForm.vue' import BusinessForm from './BusinessForm.vue'
import { erpPriceTableColumnFormatter } from '@/utils' import { erpPriceTableColumnFormatter } from '@/utils'
import { TabsPaneContext } from 'element-plus'
defineOptions({ name: 'CrmBusiness' }) defineOptions({ name: 'CrmBusiness' })
@ -169,27 +175,12 @@ const list = ref([]) // 列表的数据
const queryParams = reactive({ const queryParams = reactive({
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
name: null, sceneType: '1', // activeName
statusTypeId: null, name: 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
}) })
const queryFormRef = ref() // const queryFormRef = ref() //
const exportLoading = ref(false) // const exportLoading = ref(false) //
const activeName = ref('1') // tab
/** 查询列表 */ /** 查询列表 */
const getList = async () => { const getList = async () => {
@ -215,6 +206,12 @@ const resetQuery = () => {
handleQuery() handleQuery()
} }
/** tab 切换 */
const handleTabClick = (tab: TabsPaneContext) => {
queryParams.sceneType = tab.paneName
handleQuery()
}
/** 打开客户详情 */ /** 打开客户详情 */
const { currentRoute, push } = useRouter() const { currentRoute, push } = useRouter()
const openDetail = (id: number) => { const openDetail = (id: number) => {

View File

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

View File

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