diff --git a/frontend/packages/lib-shared/api/requrls/customer/index.ts b/frontend/packages/lib-shared/api/requrls/customer/index.ts index 0739183f3..2812563fa 100644 --- a/frontend/packages/lib-shared/api/requrls/customer/index.ts +++ b/frontend/packages/lib-shared/api/requrls/customer/index.ts @@ -38,3 +38,4 @@ export const BatchAssignOpenSeaCustomerUrl = '/pool/customer/batch-assign'; // export const AssignOpenSeaCustomerUrl = '/pool/customer/assign'; // 分配公海客户 export const GetOpenSeaOptionsUrl = '/pool/customer/options'; // 获取公海选项 export const DeleteOpenSeaCustomerUrl = '/pool/customer/delete'; // 删除公海客户 +export const CancelCustomerFollowPlanUrl = '/customer/follow/plan/cancel'; // 取消客户跟进计划 diff --git a/frontend/packages/lib-shared/enums/formDesignEnum.ts b/frontend/packages/lib-shared/enums/formDesignEnum.ts index 0b99ed519..59ea74237 100644 --- a/frontend/packages/lib-shared/enums/formDesignEnum.ts +++ b/frontend/packages/lib-shared/enums/formDesignEnum.ts @@ -5,9 +5,9 @@ export enum FormDesignKeyEnum { CUSTOMER = 'customer', // 客户 CUSTOMER_OPEN_SEA = 'customerOpenSea', // 公海客户 CONTACT = 'contact', // 联系人 - FOLLOW_RECORD_CUSTOMER = 'recordCustomer', // 客户跟进记录 - FOLLOW_PLAN_CUSTOMER = 'planCustomer', // 客户跟进计划 - BUSINESS = 'business', // 商机 + FOLLOW_RECORD_CUSTOMER = 'record', // 客户跟进记录 + FOLLOW_PLAN_CUSTOMER = 'plan', // 客户跟进计划 + BUSINESS = 'opportunity', // 商机 FOLLOW_RECORD_BUSINESS = 'recordBusiness', // 商机跟进记录 FOLLOW_PLAN_BUSINESS = 'planBusiness', // 商机跟进计划 PRODUCT = 'product', // 产品 diff --git a/frontend/packages/lib-shared/enums/opportunityEnum.ts b/frontend/packages/lib-shared/enums/opportunityEnum.ts index bc6632ec8..e0a1f3553 100644 --- a/frontend/packages/lib-shared/enums/opportunityEnum.ts +++ b/frontend/packages/lib-shared/enums/opportunityEnum.ts @@ -25,3 +25,10 @@ export enum StageResultEnum { /** 失败 */ FAIL = 'FAIL', } + +export enum OpportunitySearchTypeEnum { + ALL = 'ALL', + SELF = 'SELF', + DEPARTMENT = 'DEPARTMENT', + DEAL = 'DEAL', +} diff --git a/frontend/packages/web/src/api/modules/customer/index.ts b/frontend/packages/web/src/api/modules/customer/index.ts index 75119436c..213b57152 100644 --- a/frontend/packages/web/src/api/modules/customer/index.ts +++ b/frontend/packages/web/src/api/modules/customer/index.ts @@ -10,6 +10,7 @@ import { BatchDeleteOpenSeaCustomerUrl, BatchPickOpenSeaCustomerUrl, BatchTransferCustomerUrl, + CancelCustomerFollowPlanUrl, DeleteCustomerContactUrl, DeleteCustomerOpenSeaUrl, DeleteCustomerUrl, @@ -154,6 +155,11 @@ export function getCustomerFollowPlanList(data: CustomerFollowPlanTableParams) { return CDR.post>({ url: GetCustomerFollowPlanListUrl, data }); } +// 取消客户跟进计划 +export function cancelCustomerFollowPlan(id: string) { + return CDR.get({ url: `${CancelCustomerFollowPlanUrl}/${id}` }); +} + // 获取客户跟进计划表单配置 export function getCustomerFollowPlanFormConfig() { return CDR.get({ url: GetCustomerFollowPlanFormConfigUrl }); diff --git a/frontend/packages/web/src/assets/style/naive-reset.less b/frontend/packages/web/src/assets/style/naive-reset.less index 125f8e14e..1d531ce13 100644 --- a/frontend/packages/web/src/assets/style/naive-reset.less +++ b/frontend/packages/web/src/assets/style/naive-reset.less @@ -355,6 +355,7 @@ .n-base-selection-popover { .n-base-selection-tags { padding: 4px; + height: 26px; } .n-base-selection-tag-wrapper { padding-bottom: 0; diff --git a/frontend/packages/web/src/components/business/crm-follow-detail/index.vue b/frontend/packages/web/src/components/business/crm-follow-detail/index.vue index 6eada2d84..c1c90808b 100644 --- a/frontend/packages/web/src/components/business/crm-follow-detail/index.vue +++ b/frontend/packages/web/src/components/business/crm-follow-detail/index.vue @@ -1,27 +1,26 @@ @@ -68,52 +73,50 @@ import dayjs from 'dayjs'; import { CustomerFollowPlanStatusEnum } from '@lib/shared/enums/customerEnum'; + import { FormDesignKeyEnum } from '@lib/shared/enums/formDesignEnum'; import type { FollowDetailItem } from '@lib/shared/models/customer'; import type { Description } from '@/components/pure/crm-detail-card/index.vue'; import CrmSearchInput from '@/components/pure/crm-search-input/index.vue'; import CrmTab from '@/components/pure/crm-tab/index.vue'; + import CrmFormCreateDrawer from '@/components/business/crm-form-create-drawer/index.vue'; import FollowRecord from './followRecord.vue'; import { useI18n } from '@/hooks/useI18n'; + import useFollowApi, { type followEnumType } from './useFollowApi'; + const { t } = useI18n(); export type ActiveType = 'followPlan' | 'followRecord'; interface FollowDetailProps { - type: string; // 跟进记录|跟进计划 - showSearchInput?: boolean; // 是否显示检索框 - showTitle?: boolean; // 是否显示标题 - noPadding?: boolean; // 无边距 + activeType: 'followRecord' | 'followPlan'; // 跟进记录|跟进计划 + followApiKey: followEnumType; // 跟进计划apiKey + virtualScrollHeight?: string; // 虚拟高度 wrapperClass?: string; - loading: boolean; + sourceId: string; // 资源id } - const props = withDefaults(defineProps(), { - showSearchInput: true, - noPadding: false, - }); + const props = defineProps(); - const emit = defineEmits<{ - (e: 'search'): void; - (e: 'handleEdit', item: FollowDetailItem): void; - (e: 'cancelPlan', item: FollowDetailItem): void; - (e: 'reachBottom'): void; - }>(); + const formDrawerVisible = ref(false); - const data = defineModel('data', { - required: true, - default: [], - }); - - const activeStatus = defineModel('activeStatus', { - default: '', - }); - - const innerKeyword = defineModel('keyword', { - default: '', + const { + data, + loading, + handleReachBottom, + searchData, + activeStatus, + loadFollowList, + handleCancelPlan, + followKeyword, + followFormKeyMap, + } = useFollowApi({ + type: toRef(props, 'activeType'), + followApiKey: props.followApiKey, + sourceId: toRef(props, 'sourceId'), }); // 跟进计划状态 @@ -182,26 +185,19 @@ })) || []) as Description[]; } - // 取消计划 - function cancelPlan(item: FollowDetailItem) { - emit('cancelPlan', item); - } + // 编辑记录或计划 + const realFormKey = ref(FormDesignKeyEnum.FOLLOW_RECORD_CUSTOMER); + const realFollowSourceId = ref(''); - // 编辑记录 function handleEdit(item: FollowDetailItem) { - emit('handleEdit', item); + realFormKey.value = followFormKeyMap[props.followApiKey as keyof typeof followFormKeyMap][props.activeType]; + realFollowSourceId.value = item.id; + formDrawerVisible.value = true; } - const followKeyword = ref(''); - - watch( - () => innerKeyword.value, - (val) => { - if (val && !props.showSearchInput) { - followKeyword.value = val; - } - } - ); + onBeforeMount(() => { + loadFollowList(); + }); +