fix: crm detail
parent
28807fa61b
commit
0597aa602a
|
@ -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"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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' },
|
||||||
},
|
},
|
||||||
|
|
|
@ -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),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue