✨ CRM:完善 CRM 跟进记录(商机的展示、添加)
parent
a9e4ef9b7b
commit
28eb23738c
|
@ -92,11 +92,6 @@ export const getBusinessPageByContact = async (params) => {
|
||||||
return await request.get({ url: `/crm/business/page-by-contact`, params })
|
return await request.get({ url: `/crm/business/page-by-contact`, params })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获得 CRM 商机列表
|
|
||||||
export const getBusinessListByIds = async (val: number[]) => {
|
|
||||||
return await request.get({ url: '/crm/business/list-by-ids', params: { ids: val.join(',') } })
|
|
||||||
}
|
|
||||||
|
|
||||||
// 商机转移
|
// 商机转移
|
||||||
export const transferBusiness = async (data: TransferReqVO) => {
|
export const transferBusiness = async (data: TransferReqVO) => {
|
||||||
return await request.put({ url: '/crm/business/transfer', data })
|
return await request.put({ url: '/crm/business/transfer', data })
|
||||||
|
|
|
@ -11,7 +11,17 @@ export interface FollowUpRecordVO {
|
||||||
fileUrls: string[] // 附件
|
fileUrls: string[] // 附件
|
||||||
nextTime: Date // 下次联系时间
|
nextTime: Date // 下次联系时间
|
||||||
businessIds: number[] // 关联的商机编号数组
|
businessIds: number[] // 关联的商机编号数组
|
||||||
|
businesses: {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
}[] // 关联的商机数组
|
||||||
contactIds: number[] // 关联的联系人编号数组
|
contactIds: number[] // 关联的联系人编号数组
|
||||||
|
contacts: {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
}[] // 关联的联系人数组
|
||||||
|
creator: string
|
||||||
|
creatorName?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跟进记录 API
|
// 跟进记录 API
|
||||||
|
@ -21,28 +31,13 @@ export const FollowUpRecordApi = {
|
||||||
return await request.get({ url: `/crm/follow-up-record/page`, params })
|
return await request.get({ url: `/crm/follow-up-record/page`, params })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 查询跟进记录详情
|
|
||||||
getFollowUpRecord: async (id: number) => {
|
|
||||||
return await request.get({ url: `/crm/follow-up-record/get?id=` + id })
|
|
||||||
},
|
|
||||||
|
|
||||||
// 新增跟进记录
|
// 新增跟进记录
|
||||||
createFollowUpRecord: async (data: FollowUpRecordVO) => {
|
createFollowUpRecord: async (data: FollowUpRecordVO) => {
|
||||||
return await request.post({ url: `/crm/follow-up-record/create`, data })
|
return await request.post({ url: `/crm/follow-up-record/create`, data })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 修改跟进记录
|
|
||||||
updateFollowUpRecord: async (data: FollowUpRecordVO) => {
|
|
||||||
return await request.put({ url: `/crm/follow-up-record/update`, data })
|
|
||||||
},
|
|
||||||
|
|
||||||
// 删除跟进记录
|
// 删除跟进记录
|
||||||
deleteFollowUpRecord: async (id: number) => {
|
deleteFollowUpRecord: async (id: number) => {
|
||||||
return await request.delete({ url: `/crm/follow-up-record/delete?id=` + id })
|
return await request.delete({ url: `/crm/follow-up-record/delete?id=` + id })
|
||||||
},
|
|
||||||
|
|
||||||
// 导出跟进记录 Excel
|
|
||||||
exportFollowUpRecord: async (params) => {
|
|
||||||
return await request.download({ url: `/crm/follow-up-record/export-excel`, params })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,8 @@
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="商机金额"
|
label="商机金额"
|
||||||
align="center"
|
align="center"
|
||||||
prop="price"
|
prop="totalPrice"
|
||||||
:formatter="erpPriceInputFormatter"
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="客户名称" align="center" prop="customerName" />
|
<el-table-column label="客户名称" align="center" prop="customerName" />
|
||||||
<el-table-column label="商机组" align="center" prop="statusTypeName" />
|
<el-table-column label="商机组" align="center" prop="statusTypeName" />
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
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 { erpPriceInputFormatter } from '@/utils'
|
import { erpPriceTableColumnFormatter } from '@/utils'
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
@ -99,6 +99,7 @@ const queryParams = reactive({
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async () => {
|
const open = async () => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
|
queryParams.customerId = props.customerId // 解决 props.customerId 没更新到 queryParams 上的问题
|
||||||
await getList()
|
await getList()
|
||||||
}
|
}
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
@ -144,7 +145,7 @@ const submitForm = async () => {
|
||||||
return message.error('未选择商机')
|
return message.error('未选择商机')
|
||||||
}
|
}
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
emit('success', businessIds)
|
emit('success', businessIds, businessRef.value.getSelectionRows())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 打开联系人详情 */
|
/** 打开联系人详情 */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<!-- 跟进记录的添加表单弹窗 -->
|
<!-- 跟进记录的添加表单弹窗 -->
|
||||||
<template>
|
<template>
|
||||||
<Dialog v-model="dialogVisible" :title="dialogTitle" width="50%">
|
<Dialog v-model="dialogVisible" title="添加跟进记录" width="50%">
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
v-loading="formLoading"
|
v-loading="formLoading"
|
||||||
|
@ -36,17 +36,17 @@
|
||||||
<el-input v-model="formData.content" :rows="3" type="textarea" />
|
<el-input v-model="formData.content" :rows="3" type="textarea" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="12">
|
||||||
<el-form-item label="图片" prop="content">
|
<el-form-item label="图片" prop="picUrls">
|
||||||
<UploadImgs v-model="formData.picUrls" class="min-w-80px" />
|
<UploadImgs v-model="formData.picUrls" class="min-w-80px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="12">
|
||||||
<el-form-item label="附件" prop="content">
|
<el-form-item label="附件" prop="fileUrls">
|
||||||
<UploadFile v-model="formData.fileUrls" class="min-w-80px" />
|
<UploadFile v-model="formData.fileUrls" class="min-w-80px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24" v-if="formData.bizType == BizTypeEnum.CRM_CUSTOMER">
|
||||||
<el-form-item label="关联联系人" prop="contactIds">
|
<el-form-item label="关联联系人" prop="contactIds">
|
||||||
<el-button @click="handleAddContact">
|
<el-button @click="handleAddContact">
|
||||||
<Icon class="mr-5px" icon="ep:plus" />
|
<Icon class="mr-5px" icon="ep:plus" />
|
||||||
|
@ -55,13 +55,13 @@
|
||||||
<contact-list v-model:contactIds="formData.contactIds" />
|
<contact-list v-model:contactIds="formData.contactIds" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24" v-if="formData.bizType == BizTypeEnum.CRM_CUSTOMER">
|
||||||
<el-form-item label="关联商机" prop="businessIds">
|
<el-form-item label="关联商机" prop="businessIds">
|
||||||
<el-button @click="handleAddBusiness">
|
<el-button @click="handleOpenBusiness">
|
||||||
<Icon class="mr-5px" icon="ep:plus" />
|
<Icon class="mr-5px" icon="ep:plus" />
|
||||||
添加商机
|
添加商机
|
||||||
</el-button>
|
</el-button>
|
||||||
<business-list v-model:businessIds="formData.businessIds" />
|
<FollowUpRecordBusinessForm :businesses="formData.businesses" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -71,13 +71,23 @@
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
|
<!-- 弹窗 -->
|
||||||
<ContactTableSelect ref="contactTableSelectRef" v-model="formData.contactIds" />
|
<ContactTableSelect ref="contactTableSelectRef" v-model="formData.contactIds" />
|
||||||
<BusinessTableSelect ref="businessTableSelectRef" v-model="formData.businessIds" />
|
<BusinessListModal
|
||||||
|
ref="businessTableSelectRef"
|
||||||
|
:customer-id="formData.bizId"
|
||||||
|
@success="handleAddBusiness"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { FollowUpRecordApi, FollowUpRecordVO } from '@/api/crm/followup'
|
import { FollowUpRecordApi, FollowUpRecordVO } from '@/api/crm/followup'
|
||||||
import { BusinessList, BusinessTableSelect, ContactList, ContactTableSelect } from './components'
|
import { ContactList, ContactTableSelect } from './components'
|
||||||
|
import { BizTypeEnum } from '@/api/crm/permission'
|
||||||
|
import FollowUpRecordBusinessForm from './components/FollowUpRecordBusinessForm.vue'
|
||||||
|
import BusinessListModal from '@/views/crm/business/components/BusinessListModal.vue'
|
||||||
|
import * as BusinessApi from '@/api/crm/business'
|
||||||
|
|
||||||
defineOptions({ name: 'FollowUpRecordForm' })
|
defineOptions({ name: 'FollowUpRecordForm' })
|
||||||
|
|
||||||
|
@ -87,8 +97,12 @@ const message = useMessage() // 消息弹窗
|
||||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
const dialogTitle = ref('') // 弹窗的标题
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formData = ref({
|
||||||
const formData = ref<FollowUpRecordVO>({} as FollowUpRecordVO)
|
bizType: undefined,
|
||||||
|
bizId: undefined,
|
||||||
|
businesses: [],
|
||||||
|
contacts: []
|
||||||
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
type: [{ required: true, message: '跟进类型不能为空', trigger: 'change' }],
|
type: [{ required: true, message: '跟进类型不能为空', trigger: 'change' }],
|
||||||
content: [{ required: true, message: '跟进内容不能为空', trigger: 'blur' }],
|
content: [{ required: true, message: '跟进内容不能为空', trigger: 'blur' }],
|
||||||
|
@ -98,22 +112,11 @@ const formRules = reactive({
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async (bizType: number, bizId: number, type: string, id?: number) => {
|
const open = async (bizType: number, bizId: number) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
dialogTitle.value = t('action.' + type)
|
|
||||||
formType.value = type
|
|
||||||
resetForm()
|
resetForm()
|
||||||
formData.value.bizType = bizType
|
formData.value.bizType = bizType
|
||||||
formData.value.bizId = bizId
|
formData.value.bizId = bizId
|
||||||
// 修改时,设置数据
|
|
||||||
if (id) {
|
|
||||||
formLoading.value = true
|
|
||||||
try {
|
|
||||||
formData.value = await FollowUpRecordApi.getFollowUpRecord(id)
|
|
||||||
} finally {
|
|
||||||
formLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
@ -126,13 +129,8 @@ const submitForm = async () => {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value as unknown as FollowUpRecordVO
|
const data = formData.value as unknown as FollowUpRecordVO
|
||||||
if (formType.value === 'create') {
|
await FollowUpRecordApi.createFollowUpRecord(data)
|
||||||
await FollowUpRecordApi.createFollowUpRecord(data)
|
message.success(t('common.createSuccess'))
|
||||||
message.success(t('common.createSuccess'))
|
|
||||||
} else {
|
|
||||||
await FollowUpRecordApi.updateFollowUpRecord(data)
|
|
||||||
message.success(t('common.updateSuccess'))
|
|
||||||
}
|
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
// 发送操作成功的事件
|
// 发送操作成功的事件
|
||||||
emit('success')
|
emit('success')
|
||||||
|
@ -148,14 +146,26 @@ const handleAddContact = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 关联商机 */
|
/** 关联商机 */
|
||||||
const businessTableSelectRef = ref<InstanceType<typeof BusinessTableSelect>>()
|
const businessTableSelectRef = ref<InstanceType<typeof BusinessListModal>>()
|
||||||
const handleAddBusiness = () => {
|
const handleOpenBusiness = () => {
|
||||||
businessTableSelectRef.value?.open()
|
businessTableSelectRef.value?.open()
|
||||||
}
|
}
|
||||||
|
const handleAddBusiness = (businessId: [], newBusinesses: BusinessApi.BusinessVO[]) => {
|
||||||
|
newBusinesses.forEach((business) => {
|
||||||
|
if (!formData.value.businesses.some((item) => item.id === business.id)) {
|
||||||
|
formData.value.businesses.push(business)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/** 重置表单 */
|
/** 重置表单 */
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
formData.value = {} as FollowUpRecordVO
|
formData.value = {
|
||||||
|
bizId: undefined,
|
||||||
|
bizType: undefined,
|
||||||
|
businesses: [],
|
||||||
|
contacts: []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-table :data="list" :show-overflow-tooltip="true" :stripe="true" height="200">
|
|
||||||
<el-table-column align="center" label="商机名称" prop="name" />
|
|
||||||
<el-table-column align="center" label="客户名称" prop="customerName" />
|
|
||||||
<el-table-column align="center" label="商机金额" prop="price" />
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="预计成交日期"
|
|
||||||
prop="dealTime"
|
|
||||||
width="120px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="商机状态类型" prop="statusTypeName" width="120" />
|
|
||||||
<el-table-column align="center" label="商机状态" prop="statusName" />
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="更新时间"
|
|
||||||
prop="updateTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="创建时间"
|
|
||||||
prop="createTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="负责人" prop="ownerUserName" width="120" />
|
|
||||||
<el-table-column align="center" label="创建人" prop="creatorName" width="120" />
|
|
||||||
<el-table-column align="center" label="备注" prop="remark" />
|
|
||||||
<el-table-column align="center" fixed="right" label="操作" width="130">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button link type="danger" @click="handleDelete(scope.row.id)"> 移除</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
|
||||||
import * as BusinessApi from '@/api/crm/business'
|
|
||||||
|
|
||||||
defineOptions({ name: 'BusinessList' })
|
|
||||||
const props = withDefaults(defineProps<{ businessIds: number[] }>(), {
|
|
||||||
businessIds: () => []
|
|
||||||
})
|
|
||||||
const list = ref<BusinessApi.BusinessVO[]>([] as BusinessApi.BusinessVO[])
|
|
||||||
watch(
|
|
||||||
() => props.businessIds,
|
|
||||||
(val) => {
|
|
||||||
if (!val || val.length === 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
list.value = BusinessApi.getBusinessListByIds(unref(val)) as unknown as BusinessApi.BusinessVO[]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const emits = defineEmits<{
|
|
||||||
(e: 'update:businessIds', businessIds: number[]): void
|
|
||||||
}>()
|
|
||||||
const handleDelete = (id: number) => {
|
|
||||||
const index = list.value.findIndex((item) => item.id === id)
|
|
||||||
if (index !== -1) {
|
|
||||||
list.value.splice(index, 1)
|
|
||||||
}
|
|
||||||
emits(
|
|
||||||
'update:businessIds',
|
|
||||||
list.value.map((item) => item.id)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,88 +0,0 @@
|
||||||
<!-- 商机的选择列表 TODO 芋艿:后面看看要不要搞到统一封装里 -->
|
|
||||||
<template>
|
|
||||||
<Dialog v-model="dialogVisible" :appendToBody="true" title="选择商机" width="700">
|
|
||||||
<el-table
|
|
||||||
ref="multipleTableRef"
|
|
||||||
v-loading="loading"
|
|
||||||
:data="list"
|
|
||||||
:show-overflow-tooltip="true"
|
|
||||||
:stripe="true"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" width="55" />
|
|
||||||
<el-table-column align="center" label="商机名称" prop="name" />
|
|
||||||
<el-table-column align="center" label="客户名称" prop="customerName" />
|
|
||||||
<el-table-column align="center" label="商机金额" prop="price" />
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="预计成交日期"
|
|
||||||
prop="dealTime"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="备注" prop="remark" />
|
|
||||||
</el-table>
|
|
||||||
<template #footer>
|
|
||||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
|
||||||
</template>
|
|
||||||
</Dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import * as BusinessApi from '@/api/crm/business'
|
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
|
||||||
import { ElTable } from 'element-plus'
|
|
||||||
|
|
||||||
defineOptions({ name: 'BusinessTableSelect' })
|
|
||||||
withDefaults(defineProps<{ modelValue: number[] }>(), { modelValue: () => [] })
|
|
||||||
|
|
||||||
const list = ref<BusinessApi.BusinessVO[]>([]) // 列表的数据
|
|
||||||
const loading = ref(false) // 列表的加载中
|
|
||||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
|
||||||
const formLoading = ref(false)
|
|
||||||
|
|
||||||
// 确认选择时的触发事件
|
|
||||||
const emits = defineEmits<{
|
|
||||||
(e: 'update:modelValue', v: number[]): void
|
|
||||||
}>()
|
|
||||||
const multipleTableRef = ref<InstanceType<typeof ElTable>>()
|
|
||||||
const multipleSelection = ref<BusinessApi.BusinessVO[]>([])
|
|
||||||
const handleSelectionChange = (val: BusinessApi.BusinessVO[]) => {
|
|
||||||
multipleSelection.value = val
|
|
||||||
}
|
|
||||||
/** 触发 */
|
|
||||||
const submitForm = () => {
|
|
||||||
formLoading.value = true
|
|
||||||
try {
|
|
||||||
emits(
|
|
||||||
'update:modelValue',
|
|
||||||
multipleSelection.value.map((item) => item.id)
|
|
||||||
)
|
|
||||||
} finally {
|
|
||||||
formLoading.value = false
|
|
||||||
// 关闭弹窗
|
|
||||||
dialogVisible.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getList = async () => {
|
|
||||||
loading.value = true
|
|
||||||
try {
|
|
||||||
list.value = await BusinessApi.getSimpleBusinessList()
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 打开弹窗 */
|
|
||||||
const open = async () => {
|
|
||||||
dialogVisible.value = true
|
|
||||||
await nextTick()
|
|
||||||
if (multipleSelection.value.length > 0) {
|
|
||||||
multipleTableRef.value!.clearSelection()
|
|
||||||
}
|
|
||||||
await getList()
|
|
||||||
}
|
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|
||||||
</script>
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<template>
|
||||||
|
<el-table :data="formData" :show-overflow-tooltip="true" :stripe="true" height="120">
|
||||||
|
<el-table-column label="商机名称" fixed="left" align="center" prop="name" />
|
||||||
|
<el-table-column
|
||||||
|
label="商机金额"
|
||||||
|
align="center"
|
||||||
|
prop="totalPrice"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
/>
|
||||||
|
<el-table-column label="客户名称" align="center" prop="customerName" />
|
||||||
|
<el-table-column label="商机组" align="center" prop="statusTypeName" />
|
||||||
|
<el-table-column label="商机阶段" align="center" prop="statusName" />
|
||||||
|
<el-table-column align="center" fixed="right" label="操作" width="80">
|
||||||
|
<template #default="{ $index }">
|
||||||
|
<el-button link type="danger" @click="handleDelete($index)"> 移除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { erpPriceTableColumnFormatter } from '@/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
businesses: undefined
|
||||||
|
}>()
|
||||||
|
const formData = ref([])
|
||||||
|
|
||||||
|
/** 初始化商机列表 */
|
||||||
|
watch(
|
||||||
|
() => props.businesses,
|
||||||
|
async (val) => {
|
||||||
|
formData.value = val
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = (index: number) => {
|
||||||
|
formData.value.splice(index, 1)
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,6 +1,4 @@
|
||||||
import BusinessList from './BusinessList.vue'
|
|
||||||
import BusinessTableSelect from './BusinessTableSelect.vue'
|
|
||||||
import ContactList from './ContactList.vue'
|
import ContactList from './ContactList.vue'
|
||||||
import ContactTableSelect from './ContactTableSelect.vue'
|
import ContactTableSelect from './ContactTableSelect.vue'
|
||||||
|
|
||||||
export { BusinessList, BusinessTableSelect, ContactList, ContactTableSelect }
|
export { ContactList, ContactTableSelect }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 操作栏 -->
|
<!-- 操作栏 -->
|
||||||
<el-row class="mb-10px" justify="end">
|
<el-row class="mb-10px" justify="end">
|
||||||
<el-button @click="openForm('create')">
|
<el-button @click="openForm">
|
||||||
<Icon class="mr-5px" icon="ep:edit" />
|
<Icon class="mr-5px" icon="ep:edit" />
|
||||||
写跟进
|
写跟进
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -10,8 +10,13 @@
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
||||||
<el-table-column align="center" label="编号" prop="id" />
|
<el-table-column
|
||||||
<!-- TODO @puhui999:展示不出来 -->
|
:formatter="dateFormatter"
|
||||||
|
align="center"
|
||||||
|
label="创建时间"
|
||||||
|
prop="createTime"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
<el-table-column align="center" label="跟进人" prop="creatorName" />
|
<el-table-column align="center" label="跟进人" prop="creatorName" />
|
||||||
<el-table-column align="center" label="跟进类型" prop="type">
|
<el-table-column align="center" label="跟进类型" prop="type">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
@ -26,27 +31,46 @@
|
||||||
prop="nextTime"
|
prop="nextTime"
|
||||||
width="180px"
|
width="180px"
|
||||||
/>
|
/>
|
||||||
<!-- TODO @puhui999:点击后,查看关联联系人 -->
|
|
||||||
<el-table-column align="center" label="关联联系人" prop="contactIds" />
|
|
||||||
<!-- TODO @puhui999:点击后,查看关联商机 -->
|
|
||||||
<el-table-column align="center" label="关联商机" prop="businessIds" />
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
align="center"
|
||||||
label="创建时间"
|
label="关联联系人"
|
||||||
prop="createTime"
|
prop="contactIds"
|
||||||
width="180px"
|
v-if="bizType === BizTypeEnum.CRM_CUSTOMER"
|
||||||
/>
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<el-link
|
||||||
|
v-for="contact in scope.row.contacts"
|
||||||
|
:key="`key-${contact.id}`"
|
||||||
|
:underline="false"
|
||||||
|
type="primary"
|
||||||
|
@click="openContactDetail(contact.id)"
|
||||||
|
class="ml-5px"
|
||||||
|
>
|
||||||
|
{{ contact.name }}
|
||||||
|
</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
align="center"
|
||||||
|
label="关联商机"
|
||||||
|
prop="businessIds"
|
||||||
|
v-if="bizType === BizTypeEnum.CRM_CUSTOMER"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<el-link
|
||||||
|
v-for="business in scope.row.businesses"
|
||||||
|
:key="`key-${business.id}`"
|
||||||
|
:underline="false"
|
||||||
|
type="primary"
|
||||||
|
@click="openBusinessDetail(business.id)"
|
||||||
|
class="ml-5px"
|
||||||
|
>
|
||||||
|
{{ business.name }}
|
||||||
|
</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column align="center" label="操作">
|
<el-table-column align="center" label="操作">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
|
||||||
v-hasPermi="['crm:follow-up-record:update']"
|
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click="openForm('update', scope.row.id)"
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['crm:follow-up-record:delete']"
|
v-hasPermi="['crm:follow-up-record:delete']"
|
||||||
link
|
link
|
||||||
|
@ -76,6 +100,7 @@ import { dateFormatter } from '@/utils/formatTime'
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
import { FollowUpRecordApi, FollowUpRecordVO } from '@/api/crm/followup'
|
import { FollowUpRecordApi, FollowUpRecordVO } from '@/api/crm/followup'
|
||||||
import FollowUpRecordForm from './FollowUpRecordForm.vue'
|
import FollowUpRecordForm from './FollowUpRecordForm.vue'
|
||||||
|
import { BizTypeEnum } from '@/api/crm/permission'
|
||||||
|
|
||||||
/** 跟进记录列表 */
|
/** 跟进记录列表 */
|
||||||
defineOptions({ name: 'FollowUpRecord' })
|
defineOptions({ name: 'FollowUpRecord' })
|
||||||
|
@ -110,8 +135,8 @@ const getList = async () => {
|
||||||
|
|
||||||
/** 添加/修改操作 */
|
/** 添加/修改操作 */
|
||||||
const formRef = ref<InstanceType<typeof FollowUpRecordForm>>()
|
const formRef = ref<InstanceType<typeof FollowUpRecordForm>>()
|
||||||
const openForm = (type: string, id?: number) => {
|
const openForm = () => {
|
||||||
formRef.value?.open(props.bizType, props.bizId, type, id)
|
formRef.value?.open(props.bizType, props.bizId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
|
@ -127,6 +152,17 @@ const handleDelete = async (id: number) => {
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 打开联系人详情 */
|
||||||
|
const { push } = useRouter()
|
||||||
|
const openContactDetail = (id: number) => {
|
||||||
|
push({ name: 'CrmContactDetail', params: { id } })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 打开商机详情 */
|
||||||
|
const openBusinessDetail = (id: number) => {
|
||||||
|
push({ name: 'CrmBusinessDetail', params: { id } })
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.bizId,
|
() => props.bizId,
|
||||||
() => {
|
() => {
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- TODO @puhui999:同时添加至,还没想好下次搞 -->
|
<!-- TODO @puhui999:同时添加至,还没想好下次搞 -->
|
||||||
<el-form-item v-if="formType === 'create'" label="同时添加至" prop="toBizType">
|
<el-form-item v-if="false && formType === 'create'" label="同时添加至" prop="toBizType">
|
||||||
<el-select v-model="formData.userId">
|
<el-select v-model="formData.userId">
|
||||||
<el-option :value="1" label="联系人" />
|
<el-option :value="1" label="联系人" />
|
||||||
<el-option :value="1" label="商机" />
|
<el-option :value="1" label="商机" />
|
||||||
|
|
Loading…
Reference in New Issue