feat:【antd】【crm】商机的整体代码结构优化
This commit is contained in:
@@ -1,25 +1,5 @@
|
|||||||
import { defineAsyncComponent } from 'vue';
|
import { defineAsyncComponent } from 'vue';
|
||||||
|
|
||||||
export const BusinessForm = defineAsyncComponent(
|
|
||||||
() => import('./modules/form.vue'),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const BusinessDetailsInfo = defineAsyncComponent(
|
|
||||||
() => import('./modules/detail-info.vue'),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const BusinessDetailsList = defineAsyncComponent(
|
export const BusinessDetailsList = defineAsyncComponent(
|
||||||
() => import('./modules/detail-list.vue'),
|
() => import('./modules/detail-list.vue'),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const BusinessDetails = defineAsyncComponent(
|
|
||||||
() => import('./modules/detail.vue'),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const BusinessDetailsListModal = defineAsyncComponent(
|
|
||||||
() => import('./modules/detail-list-modal.vue'),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const UpStatusForm = defineAsyncComponent(
|
|
||||||
() => import('./modules/up-status-form.vue'),
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { CrmBusinessApi } from '#/api/crm/business';
|
import type { CrmBusinessApi } from '#/api/crm/business';
|
||||||
|
|
||||||
|
import { ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
||||||
import { downloadFileFromBlobPart } from '@vben/utils';
|
import { downloadFileFromBlobPart } from '@vben/utils';
|
||||||
|
|
||||||
import { Button, message } from 'ant-design-vue';
|
import { Button, message, Tabs } from 'ant-design-vue';
|
||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import {
|
import {
|
||||||
@@ -21,6 +22,7 @@ import { useGridColumns, useGridFormSchema } from './data';
|
|||||||
import Form from './modules/form.vue';
|
import Form from './modules/form.vue';
|
||||||
|
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
|
const sceneType = ref('1');
|
||||||
|
|
||||||
const [FormModal, formModalApi] = useVbenModal({
|
const [FormModal, formModalApi] = useVbenModal({
|
||||||
connectedComponent: Form,
|
connectedComponent: Form,
|
||||||
@@ -28,13 +30,23 @@ const [FormModal, formModalApi] = useVbenModal({
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** 刷新表格 */
|
/** 刷新表格 */
|
||||||
function onRefresh() {
|
function handleRefresh() {
|
||||||
|
gridApi.query();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 处理场景类型的切换 */
|
||||||
|
function handleChangeSceneType(key: number | string) {
|
||||||
|
sceneType.value = key.toString();
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 导出表格 */
|
/** 导出表格 */
|
||||||
async function handleExport() {
|
async function handleExport() {
|
||||||
const data = await exportBusiness(await gridApi.formApi.getValues());
|
const formValues = await gridApi.formApi.getValues();
|
||||||
|
const data = await exportBusiness({
|
||||||
|
sceneType: sceneType.value,
|
||||||
|
...formValues,
|
||||||
|
});
|
||||||
downloadFileFromBlobPart({ fileName: '商机.xls', source: data });
|
downloadFileFromBlobPart({ fileName: '商机.xls', source: data });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +70,7 @@ async function handleDelete(row: CrmBusinessApi.Business) {
|
|||||||
try {
|
try {
|
||||||
await deleteBusiness(row.id as number);
|
await deleteBusiness(row.id as number);
|
||||||
message.success($t('ui.actionMessage.deleteSuccess', [row.name]));
|
message.success($t('ui.actionMessage.deleteSuccess', [row.name]));
|
||||||
onRefresh();
|
handleRefresh();
|
||||||
} catch {
|
} catch {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
}
|
}
|
||||||
@@ -88,6 +100,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
return await getBusinessPage({
|
return await getBusinessPage({
|
||||||
pageNo: page.currentPage,
|
pageNo: page.currentPage,
|
||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
|
sceneType: sceneType.value,
|
||||||
...formValues,
|
...formValues,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -95,6 +108,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
keyField: 'id',
|
keyField: 'id',
|
||||||
|
isHover: true,
|
||||||
},
|
},
|
||||||
toolbarConfig: {
|
toolbarConfig: {
|
||||||
refresh: true,
|
refresh: true,
|
||||||
@@ -117,8 +131,15 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<FormModal @success="onRefresh" />
|
<FormModal @success="handleRefresh" />
|
||||||
<Grid table-title="商机列表">
|
<Grid>
|
||||||
|
<template #top>
|
||||||
|
<Tabs class="-mt-11" @change="handleChangeSceneType">
|
||||||
|
<Tabs.TabPane tab="我负责的" key="1" />
|
||||||
|
<Tabs.TabPane tab="我参与的" key="2" />
|
||||||
|
<Tabs.TabPane tab="下属负责的" key="3" />
|
||||||
|
</Tabs>
|
||||||
|
</template>
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
@@ -176,3 +197,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
<style scoped>
|
||||||
|
:deep(.vxe-toolbar div) {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
|
||||||
import type { DescriptionItemSchema } from '#/components/description';
|
|
||||||
|
|
||||||
import { erpPriceInputFormatter, formatDateTime } from '@vben/utils';
|
|
||||||
|
|
||||||
/** 详情页的字段 */
|
|
||||||
export function useDetailSchema(): DescriptionItemSchema[] {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
field: 'customerName',
|
|
||||||
label: '客户名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'totalPrice',
|
|
||||||
label: '商机金额(元)',
|
|
||||||
content: (data) => erpPriceInputFormatter(data.totalPrice),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'statusTypeName',
|
|
||||||
label: '商机组',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'ownerUserName',
|
|
||||||
label: '负责人',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'createTime',
|
|
||||||
label: '创建时间',
|
|
||||||
content: (data) => formatDateTime(data?.createTime) as string,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 详情页的基础字段 */
|
|
||||||
export function useDetailBaseSchema(): DescriptionItemSchema[] {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
field: 'name',
|
|
||||||
label: '商机名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'customerName',
|
|
||||||
label: '客户名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'totalPrice',
|
|
||||||
label: '商机金额(元)',
|
|
||||||
content: (data) => erpPriceInputFormatter(data.totalPrice),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'dealTime',
|
|
||||||
label: '预计成交日期',
|
|
||||||
content: (data) => formatDateTime(data?.dealTime) as string,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'contactNextTime',
|
|
||||||
label: '下次联系时间',
|
|
||||||
content: (data) => formatDateTime(data?.contactNextTime) as string,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'statusTypeName',
|
|
||||||
label: '商机状态组',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'statusName',
|
|
||||||
label: '商机阶段',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'remark',
|
|
||||||
label: '备注',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 详情列表的字段 */
|
|
||||||
export function useDetailListColumns(): VxeTableGridOptions['columns'] {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
type: 'checkbox',
|
|
||||||
width: 50,
|
|
||||||
fixed: 'left',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'name',
|
|
||||||
title: '商机名称',
|
|
||||||
fixed: 'left',
|
|
||||||
slots: { default: 'name' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'customerName',
|
|
||||||
title: '客户名称',
|
|
||||||
fixed: 'left',
|
|
||||||
slots: { default: 'customerName' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'totalPrice',
|
|
||||||
title: '商机金额(元)',
|
|
||||||
formatter: 'formatAmount2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'dealTime',
|
|
||||||
title: '预计成交日期',
|
|
||||||
formatter: 'formatDate',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'ownerUserName',
|
|
||||||
title: '负责人',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'ownerUserDeptName',
|
|
||||||
title: '所属部门',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'statusTypeName',
|
|
||||||
title: '商机状态组',
|
|
||||||
fixed: 'right',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'statusName',
|
|
||||||
title: '商机阶段',
|
|
||||||
fixed: 'right',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import type { CrmBusinessApi } from '#/api/crm/business';
|
|
||||||
|
|
||||||
import { Divider } from 'ant-design-vue';
|
|
||||||
|
|
||||||
import { useDescription } from '#/components/description';
|
|
||||||
import { useFollowUpDetailSchema } from '#/views/crm/followup/data';
|
|
||||||
|
|
||||||
import { useDetailBaseSchema } from './detail-data';
|
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
business: CrmBusinessApi.Business; // 商机信息
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const [BaseDescriptions] = useDescription({
|
|
||||||
componentProps: {
|
|
||||||
title: '基本信息',
|
|
||||||
bordered: false,
|
|
||||||
column: 4,
|
|
||||||
class: 'mx-4',
|
|
||||||
},
|
|
||||||
schema: useDetailBaseSchema(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const [SystemDescriptions] = useDescription({
|
|
||||||
componentProps: {
|
|
||||||
title: '系统信息',
|
|
||||||
bordered: false,
|
|
||||||
column: 3,
|
|
||||||
class: 'mx-4',
|
|
||||||
},
|
|
||||||
schema: useFollowUpDetailSchema(),
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="p-4">
|
|
||||||
<BaseDescriptions :data="business" />
|
|
||||||
<Divider />
|
|
||||||
<SystemDescriptions :data="business" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -13,7 +13,7 @@ import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
|||||||
import { getBusinessPageByCustomer } from '#/api/crm/business';
|
import { getBusinessPageByCustomer } from '#/api/crm/business';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useDetailListColumns } from './detail-data';
|
import { useDetailListColumns } from '../detail/data';
|
||||||
import Form from './form.vue';
|
import Form from './form.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import {
|
|||||||
import { BizTypeEnum } from '#/api/crm/permission';
|
import { BizTypeEnum } from '#/api/crm/permission';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useDetailListColumns } from './detail-data';
|
import { useDetailListColumns } from '../detail/data';
|
||||||
import ListModal from './detail-list-modal.vue';
|
import ListModal from './detail-list-modal.vue';
|
||||||
import Form from './form.vue';
|
import Form from './form.vue';
|
||||||
|
|
||||||
|
|||||||
@@ -1,183 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import type { CrmBusinessApi } from '#/api/crm/business';
|
|
||||||
import type { SystemOperateLogApi } from '#/api/system/operate-log';
|
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
|
||||||
import { useTabs } from '@vben/hooks';
|
|
||||||
|
|
||||||
import { Button, Card, Tabs } from 'ant-design-vue';
|
|
||||||
|
|
||||||
import { getBusiness } from '#/api/crm/business';
|
|
||||||
import { getOperateLogPage } from '#/api/crm/operateLog';
|
|
||||||
import { BizTypeEnum } from '#/api/crm/permission';
|
|
||||||
import { useDescription } from '#/components/description';
|
|
||||||
import { AsyncOperateLog } from '#/components/operate-log';
|
|
||||||
import {
|
|
||||||
BusinessDetailsInfo,
|
|
||||||
BusinessForm,
|
|
||||||
UpStatusForm,
|
|
||||||
} from '#/views/crm/business';
|
|
||||||
import { ContactDetailsList } from '#/views/crm/contact/components';
|
|
||||||
import { ContractDetailsList } from '#/views/crm/contract';
|
|
||||||
import { FollowUp } from '#/views/crm/followup';
|
|
||||||
import { PermissionList, TransferForm } from '#/views/crm/permission';
|
|
||||||
import { ProductDetailsList } from '#/views/crm/product/components';
|
|
||||||
|
|
||||||
import { useDetailSchema } from './detail-data';
|
|
||||||
|
|
||||||
const loading = ref(false);
|
|
||||||
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
const tabs = useTabs();
|
|
||||||
|
|
||||||
const businessId = ref(0);
|
|
||||||
|
|
||||||
const business = ref<CrmBusinessApi.Business>({} as CrmBusinessApi.Business);
|
|
||||||
const businessLogList = ref<SystemOperateLogApi.OperateLog[]>([]);
|
|
||||||
const permissionListRef = ref<InstanceType<typeof PermissionList>>(); // 团队成员列表 Ref
|
|
||||||
|
|
||||||
const [Descriptions] = useDescription({
|
|
||||||
componentProps: {
|
|
||||||
bordered: false,
|
|
||||||
column: 4,
|
|
||||||
class: 'mx-4',
|
|
||||||
},
|
|
||||||
schema: useDetailSchema(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const [FormModal, formModalApi] = useVbenModal({
|
|
||||||
connectedComponent: BusinessForm,
|
|
||||||
destroyOnClose: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const [TransferModal, transferModalApi] = useVbenModal({
|
|
||||||
connectedComponent: TransferForm,
|
|
||||||
destroyOnClose: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const [UpStatusModal, upStatusModalApi] = useVbenModal({
|
|
||||||
connectedComponent: UpStatusForm,
|
|
||||||
destroyOnClose: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
/** 加载详情 */
|
|
||||||
async function loadBusinessDetail() {
|
|
||||||
loading.value = true;
|
|
||||||
const data = await getBusiness(businessId.value);
|
|
||||||
const logList = await getOperateLogPage({
|
|
||||||
bizType: BizTypeEnum.CRM_BUSINESS,
|
|
||||||
bizId: businessId.value,
|
|
||||||
});
|
|
||||||
businessLogList.value = logList.list;
|
|
||||||
business.value = data;
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 返回列表页 */
|
|
||||||
function handleBack() {
|
|
||||||
tabs.closeCurrentTab();
|
|
||||||
router.push('/crm/business');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 编辑 */
|
|
||||||
function handleEdit() {
|
|
||||||
formModalApi.setData({ id: businessId.value }).open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 转移线索 */
|
|
||||||
function handleTransfer() {
|
|
||||||
transferModalApi.setData({ bizType: BizTypeEnum.CRM_BUSINESS }).open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 更新商机状态操作 */
|
|
||||||
async function handleUpdateStatus() {
|
|
||||||
upStatusModalApi.setData(business.value).open();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载数据
|
|
||||||
onMounted(() => {
|
|
||||||
businessId.value = Number(route.params.id);
|
|
||||||
loadBusinessDetail();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<Page auto-content-height :title="business?.name" :loading="loading">
|
|
||||||
<FormModal @success="loadBusinessDetail" />
|
|
||||||
<TransferModal @success="loadBusinessDetail" />
|
|
||||||
<UpStatusModal @success="loadBusinessDetail" />
|
|
||||||
<template #extra>
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<Button
|
|
||||||
v-if="permissionListRef?.validateWrite"
|
|
||||||
type="primary"
|
|
||||||
@click="handleEdit"
|
|
||||||
>
|
|
||||||
{{ $t('ui.actionTitle.edit') }}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
v-if="permissionListRef?.validateWrite"
|
|
||||||
@click="handleUpdateStatus"
|
|
||||||
>
|
|
||||||
变更商机状态
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
v-if="permissionListRef?.validateOwnerUser"
|
|
||||||
@click="handleTransfer"
|
|
||||||
>
|
|
||||||
转移
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<Card class="min-h-[10%]">
|
|
||||||
<Descriptions :data="business" />
|
|
||||||
</Card>
|
|
||||||
<Card class="mt-4 min-h-[60%]">
|
|
||||||
<Tabs>
|
|
||||||
<Tabs.TabPane tab="详细资料" key="1" :force-render="true">
|
|
||||||
<BusinessDetailsInfo :business="business" />
|
|
||||||
</Tabs.TabPane>
|
|
||||||
<Tabs.TabPane tab="跟进记录" key="2" :force-render="true">
|
|
||||||
<FollowUp :biz-id="businessId" :biz-type="BizTypeEnum.CRM_BUSINESS" />
|
|
||||||
</Tabs.TabPane>
|
|
||||||
<Tabs.TabPane tab="联系人" key="3" :force-render="true">
|
|
||||||
<ContactDetailsList
|
|
||||||
:biz-id="businessId"
|
|
||||||
:biz-type="BizTypeEnum.CRM_BUSINESS"
|
|
||||||
:business-id="businessId"
|
|
||||||
:customer-id="business.customerId"
|
|
||||||
/>
|
|
||||||
</Tabs.TabPane>
|
|
||||||
<Tabs.TabPane tab="产品" key="4" :force-render="true">
|
|
||||||
<ProductDetailsList
|
|
||||||
:biz-id="businessId"
|
|
||||||
:biz-type="BizTypeEnum.CRM_BUSINESS"
|
|
||||||
:business="business"
|
|
||||||
/>
|
|
||||||
</Tabs.TabPane>
|
|
||||||
<Tabs.TabPane tab="合同" key="5" :force-render="true">
|
|
||||||
<ContractDetailsList
|
|
||||||
:biz-id="businessId"
|
|
||||||
:biz-type="BizTypeEnum.CRM_BUSINESS"
|
|
||||||
/>
|
|
||||||
</Tabs.TabPane>
|
|
||||||
<Tabs.TabPane tab="团队成员" key="6" :force-render="true">
|
|
||||||
<PermissionList
|
|
||||||
ref="permissionListRef"
|
|
||||||
:biz-id="businessId"
|
|
||||||
:biz-type="BizTypeEnum.CRM_BUSINESS"
|
|
||||||
:show-action="true"
|
|
||||||
@quit-team="handleBack"
|
|
||||||
/>
|
|
||||||
</Tabs.TabPane>
|
|
||||||
<Tabs.TabPane tab="操作日志" key="7" :force-render="true">
|
|
||||||
<AsyncOperateLog :log-list="businessLogList" />
|
|
||||||
</Tabs.TabPane>
|
|
||||||
</Tabs>
|
|
||||||
</Card>
|
|
||||||
</Page>
|
|
||||||
</template>
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import type { CrmBusinessApi } from '#/api/crm/business';
|
|
||||||
|
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
|
||||||
|
|
||||||
import { message } from 'ant-design-vue';
|
|
||||||
|
|
||||||
import { useVbenForm } from '#/adapter/form';
|
|
||||||
import { updateBusinessStatus } from '#/api/crm/business';
|
|
||||||
import {
|
|
||||||
DEFAULT_STATUSES,
|
|
||||||
getBusinessStatusSimpleList,
|
|
||||||
} from '#/api/crm/business/status';
|
|
||||||
import { $t } from '#/locales';
|
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
|
||||||
|
|
||||||
const formData = ref<CrmBusinessApi.Business>();
|
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
|
||||||
commonConfig: {
|
|
||||||
componentProps: {
|
|
||||||
class: 'w-full',
|
|
||||||
},
|
|
||||||
formItemClass: 'col-span-2',
|
|
||||||
labelWidth: 120,
|
|
||||||
},
|
|
||||||
layout: 'horizontal',
|
|
||||||
schema: [
|
|
||||||
{
|
|
||||||
fieldName: 'id',
|
|
||||||
component: 'Input',
|
|
||||||
dependencies: {
|
|
||||||
triggerFields: [''],
|
|
||||||
show: () => false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: 'statusId',
|
|
||||||
label: '商机状态',
|
|
||||||
component: 'Input',
|
|
||||||
dependencies: {
|
|
||||||
triggerFields: [''],
|
|
||||||
show: () => false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: 'endStatus',
|
|
||||||
label: '商机状态',
|
|
||||||
component: 'Input',
|
|
||||||
dependencies: {
|
|
||||||
triggerFields: [''],
|
|
||||||
show: () => false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: 'status',
|
|
||||||
label: '商机阶段',
|
|
||||||
component: 'Select',
|
|
||||||
dependencies: {
|
|
||||||
triggerFields: [''],
|
|
||||||
async componentProps() {
|
|
||||||
const statusList = await getBusinessStatusSimpleList(
|
|
||||||
formData.value?.statusTypeId ?? 0,
|
|
||||||
);
|
|
||||||
const statusOptions = statusList.map((item) => ({
|
|
||||||
label: `${item.name}(赢单率:${item.percent}%)`,
|
|
||||||
value: item.id,
|
|
||||||
}));
|
|
||||||
const options = DEFAULT_STATUSES.map((item) => ({
|
|
||||||
label: `${`${item.name}(赢单率:${item.percent}`}%)`,
|
|
||||||
value: item.endStatus,
|
|
||||||
}));
|
|
||||||
statusOptions.push(...options);
|
|
||||||
return {
|
|
||||||
options: statusOptions,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rules: 'required',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
showDefaultActions: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
|
||||||
async onConfirm() {
|
|
||||||
const { valid } = await formApi.validate();
|
|
||||||
if (!valid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
modalApi.lock();
|
|
||||||
// 提交表单
|
|
||||||
const data = (await formApi.getValues()) as CrmBusinessApi.Business;
|
|
||||||
try {
|
|
||||||
if (!data.status) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await updateBusinessStatus({
|
|
||||||
id: data.id,
|
|
||||||
statusId: data.status > 0 ? data.status : undefined,
|
|
||||||
endStatus: data.status < 0 ? -data.status : undefined,
|
|
||||||
});
|
|
||||||
// 关闭并提示
|
|
||||||
await modalApi.close();
|
|
||||||
emit('success');
|
|
||||||
message.success($t('ui.actionMessage.operationSuccess'));
|
|
||||||
} finally {
|
|
||||||
modalApi.unlock();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async onOpenChange(isOpen: boolean) {
|
|
||||||
if (!isOpen) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 加载数据
|
|
||||||
const data = modalApi.getData<CrmBusinessApi.Business>();
|
|
||||||
if (!data || !data.id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
data.status = data.endStatus === null ? data.statusId : -data.endStatus;
|
|
||||||
formData.value = data;
|
|
||||||
modalApi.lock();
|
|
||||||
try {
|
|
||||||
// 设置到 values
|
|
||||||
await formApi.setValues(formData.value);
|
|
||||||
} finally {
|
|
||||||
modalApi.unlock();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<Modal title="变更商机状态" class="w-2/5">
|
|
||||||
<Form class="mx-4" />
|
|
||||||
</Modal>
|
|
||||||
</template>
|
|
||||||
Reference in New Issue
Block a user