fix: crm detail

pull/131/head
xingyu4j 2025-06-06 11:27:12 +08:00
parent 28807fa61b
commit 0597aa602a
7 changed files with 61 additions and 94 deletions

View File

@ -183,6 +183,7 @@ onMounted(() => {
</Tabs.TabPane> </Tabs.TabPane>
<Tabs.TabPane tab="产品" key="4" :force-render="true"> <Tabs.TabPane tab="产品" key="4" :force-render="true">
<ProductDetailsList <ProductDetailsList
:biz-id="businessId"
:biz-type="BizTypeEnum.CRM_BUSINESS" :biz-type="BizTypeEnum.CRM_BUSINESS"
:business="business" :business="business"
/> />

View File

@ -161,8 +161,8 @@ onMounted(() => {
</Tabs.TabPane> </Tabs.TabPane>
<Tabs.TabPane tab="产品" key="3" :force-render="true"> <Tabs.TabPane tab="产品" key="3" :force-render="true">
<ProductDetailsList <ProductDetailsList
:biz-id="contractId"
:biz-type="BizTypeEnum.CRM_CONTRACT" :biz-type="BizTypeEnum.CRM_CONTRACT"
:contract="contract"
/> />
</Tabs.TabPane> </Tabs.TabPane>
<Tabs.TabPane tab="回款" key="4" :force-render="true"> <Tabs.TabPane tab="回款" key="4" :force-render="true">

View File

@ -1,32 +1,49 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { CrmBusinessApi } from '#/api/crm/business';
import type { CrmContractApi } from '#/api/crm/contract';
import type { CrmProductApi } from '#/api/crm/product'; import type { CrmProductApi } from '#/api/crm/product';
import { ref } from 'vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getBusiness } from '#/api/crm/business';
import { getContract } from '#/api/crm/contract';
import { BizTypeEnum } from '#/api/crm/permission'; import { BizTypeEnum } from '#/api/crm/permission';
import { erpPriceInputFormatter } from '#/utils'; import { erpPriceInputFormatter } from '#/utils';
import { useDetailListColumns } from '../data'; import { useDetailListColumns } from '../data';
const props = defineProps<{ const props = defineProps<{
bizId: number;
bizType: BizTypeEnum; bizType: BizTypeEnum;
business?: CrmBusinessApi.Business; //
contract?: CrmContractApi.Contract; //
}>(); }>();
const discountPercent = ref(0);
const totalProductPrice = ref(0);
const [Grid] = useVbenVxeGrid({ const [Grid] = useVbenVxeGrid({
gridOptions: { gridOptions: {
columns: useDetailListColumns(props.bizType === BizTypeEnum.CRM_BUSINESS), columns: useDetailListColumns(props.bizType === BizTypeEnum.CRM_BUSINESS),
data:
props.bizType === BizTypeEnum.CRM_BUSINESS
? props.business?.products
: props.contract?.products,
height: 600, height: 600,
pagerConfig: { pagerConfig: {
enabled: false, enabled: false,
}, },
proxyConfig: {
ajax: {
query: async (_params) => {
const data =
props.bizType === BizTypeEnum.CRM_BUSINESS
? await getBusiness(props.bizId)
: await getContract(props.bizId);
discountPercent.value = data.discountPercent;
totalProductPrice.value = data.totalProductPrice;
return data.products;
},
},
},
toolbarConfig: {
refresh: { code: 'query' },
search: true,
},
keepSource: true, keepSource: true,
rowConfig: { rowConfig: {
keyField: 'id', keyField: 'id',
@ -38,21 +55,17 @@ const [Grid] = useVbenVxeGrid({
<template> <template>
<div> <div>
<Grid /> <Grid />
<div class="flex justify-end"> <div class="flex flex-col items-end justify-end">
<span class="font-bold text-red-500">
整单折扣{{
erpPriceInputFormatter(
business ? business.discountPercent : contract?.discountPercent,
)
}}%
</span>
<span class="ml-4 font-bold text-red-500"> <span class="ml-4 font-bold text-red-500">
产品总金额{{ {{ `产品总金额:${erpPriceInputFormatter(totalProductPrice)}` }}
erpPriceInputFormatter( </span>
business ? business.totalProductPrice : contract?.totalProductPrice, <span class="font-bold text-red-500">
) {{ `整单折扣:${erpPriceInputFormatter(discountPercent)}%` }}
</span>
<span class="font-bold text-red-500">
{{
`实际金额:${erpPriceInputFormatter(totalProductPrice * (1 - discountPercent / 100))}`
}} }}
</span> </span>
</div> </div>
</div> </div>

View File

@ -362,7 +362,7 @@ export function useDetailListColumns(): VxeTableGridOptions['columns'] {
}, },
{ {
title: '合同编号', title: '合同编号',
field: 'contract', field: 'contract.no',
minWidth: 150, minWidth: 150,
}, },
{ {
@ -396,12 +396,6 @@ export function useDetailListColumns(): VxeTableGridOptions['columns'] {
field: 'remark', field: 'remark',
minWidth: 150, minWidth: 150,
}, },
{
title: '合同金额(元)',
field: 'contract.totalPrice',
minWidth: 150,
formatter: 'formatNumber',
},
{ {
title: '回款状态', title: '回款状态',
field: 'auditStatus', field: 'auditStatus',

View File

@ -2,8 +2,6 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { CrmReceivableApi } from '#/api/crm/receivable'; import type { CrmReceivableApi } from '#/api/crm/receivable';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui'; import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
@ -28,15 +26,6 @@ const [FormModal, formModalApi] = useVbenModal({
destroyOnClose: true, destroyOnClose: true,
}); });
const checkedRows = ref<CrmReceivableApi.Receivable[]>([]);
function setCheckedRows({
records,
}: {
records: CrmReceivableApi.Receivable[];
}) {
checkedRows.value = records;
}
/** 刷新表格 */ /** 刷新表格 */
function onRefresh() { function onRefresh() {
gridApi.query(); gridApi.query();
@ -73,15 +62,14 @@ async function handleDelete(row: CrmReceivableApi.Receivable) {
const [Grid, gridApi] = useVbenVxeGrid({ const [Grid, gridApi] = useVbenVxeGrid({
gridOptions: { gridOptions: {
columns: useDetailListColumns(), columns: useDetailListColumns(),
height: 600, height: 500,
keepSource: true, keepSource: true,
proxyConfig: { proxyConfig: {
ajax: { ajax: {
query: async ({ page }, formValues) => { query: async ({ page }) => {
const queryParams: CrmReceivableApi.ReceivablePageParam = { const queryParams: CrmReceivableApi.ReceivablePageParam = {
page: page.currentPage, pageNo: page.currentPage,
pageSize: page.pageSize, pageSize: page.pageSize,
...formValues,
}; };
if (props.customerId && !props.contractId) { if (props.customerId && !props.contractId) {
queryParams.customerId = props.customerId; queryParams.customerId = props.customerId;
@ -102,10 +90,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
search: true, search: true,
}, },
} as VxeTableGridOptions<CrmReceivableApi.Receivable>, } as VxeTableGridOptions<CrmReceivableApi.Receivable>,
gridEvents: {
checkboxAll: setCheckedRows,
checkboxChange: setCheckedRows,
},
}); });
</script> </script>

View File

@ -310,12 +310,6 @@ export function useDetailBaseSchema(): DescriptionItemSchema[] {
/** 详情列表的字段 */ /** 详情列表的字段 */
export function useDetailListColumns(): VxeTableGridOptions['columns'] { export function useDetailListColumns(): VxeTableGridOptions['columns'] {
return [ return [
{
title: '回款编号',
field: 'no',
minWidth: 150,
fixed: 'left',
},
{ {
title: '客户名称', title: '客户名称',
field: 'customerName', field: 'customerName',
@ -323,29 +317,36 @@ export function useDetailListColumns(): VxeTableGridOptions['columns'] {
}, },
{ {
title: '合同编号', title: '合同编号',
field: 'contract', field: 'contractNo',
minWidth: 150, minWidth: 150,
}, },
{ {
title: '回款日期', title: '',
field: 'returnTime', field: 'period',
minWidth: 150, minWidth: 150,
formatter: 'formatDateTime',
}, },
{ {
title: '回款金额(元)', title: '计划回款(元)',
field: 'price', field: 'price',
minWidth: 150, minWidth: 150,
formatter: 'formatNumber', formatter: 'formatNumber',
}, },
{ {
title: '回款方式', title: '计划回款日期',
field: 'returnType', field: 'returnTime',
minWidth: 150, minWidth: 150,
cellRender: { formatter: 'formatDateTime',
name: 'CellDict', },
props: { type: DICT_TYPE.CRM_RECEIVABLE_RETURN_TYPE }, {
}, title: '提前几天提醒',
field: 'remindDays',
minWidth: 150,
},
{
title: '提醒日期',
field: 'remindTime',
minWidth: 150,
formatter: 'formatDateTime',
}, },
{ {
title: '负责人', title: '负责人',
@ -357,26 +358,10 @@ export function useDetailListColumns(): VxeTableGridOptions['columns'] {
field: 'remark', field: 'remark',
minWidth: 150, minWidth: 150,
}, },
{
title: '合同金额(元)',
field: 'contract.totalPrice',
minWidth: 150,
formatter: 'formatNumber',
},
{
title: '回款状态',
field: 'auditStatus',
minWidth: 100,
fixed: 'right',
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.CRM_AUDIT_STATUS },
},
},
{ {
title: '操作', title: '操作',
field: 'actions', field: 'actions',
width: 130, width: 240,
fixed: 'right', fixed: 'right',
slots: { default: 'actions' }, slots: { default: 'actions' },
}, },

View File

@ -3,8 +3,6 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { CrmReceivableApi } from '#/api/crm/receivable'; import type { CrmReceivableApi } from '#/api/crm/receivable';
import type { CrmReceivablePlanApi } from '#/api/crm/receivable/plan'; import type { CrmReceivablePlanApi } from '#/api/crm/receivable/plan';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui'; import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
@ -35,11 +33,6 @@ const [ReceivableFormModal, receivableFormModalApi] = useVbenModal({
destroyOnClose: true, destroyOnClose: true,
}); });
const checkedRows = ref<CrmReceivablePlanApi.Plan[]>([]);
function setCheckedRows({ records }: { records: CrmReceivablePlanApi.Plan[] }) {
checkedRows.value = records;
}
/** 刷新表格 */ /** 刷新表格 */
function onRefresh() { function onRefresh() {
gridApi.query(); gridApi.query();
@ -81,7 +74,7 @@ async function handleDelete(row: CrmReceivablePlanApi.Plan) {
const [Grid, gridApi] = useVbenVxeGrid({ const [Grid, gridApi] = useVbenVxeGrid({
gridOptions: { gridOptions: {
columns: useDetailListColumns(), columns: useDetailListColumns(),
height: 600, height: 400,
keepSource: true, keepSource: true,
proxyConfig: { proxyConfig: {
ajax: { ajax: {
@ -110,10 +103,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
search: true, search: true,
}, },
} as VxeTableGridOptions<CrmReceivablePlanApi.Plan>, } as VxeTableGridOptions<CrmReceivablePlanApi.Plan>,
gridEvents: {
checkboxAll: setCheckedRows,
checkboxChange: setCheckedRows,
},
}); });
</script> </script>
@ -143,6 +132,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
type: 'link', type: 'link',
icon: ACTION_ICON.ADD, icon: ACTION_ICON.ADD,
auth: ['crm:receivable-plan:create'], auth: ['crm:receivable-plan:create'],
disabled: !!row.receivableId,
onClick: handleCreateReceivable.bind(null, row), onClick: handleCreateReceivable.bind(null, row),
}, },
{ {