✨ CRM:完善商机和联系人之间的关联
This commit is contained in:
parent
01684aa6e8
commit
8512fe6b43
@ -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 })
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 打开联系人详情 */
|
/** 打开联系人详情 */
|
||||||
|
@ -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' })
|
||||||
|
|
||||||
|
@ -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) => {
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 打开联系人详情 */
|
/** 打开联系人详情 */
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user