perf: optimize record summary

This commit is contained in:
sealday 2024-03-09 02:56:27 +08:00
parent 71c84a00de
commit fbe0c14920

View File

@ -1,45 +1,31 @@
import { onFieldInit, onFieldValueChange } from '@formily/core';
import { useForm, useFormEffects } from '@formily/react';
import { observer, useForm } from '@formily/react';
import { ConversionLogics, RecordCategory } from '../../utils/constants';
import { Descriptions, Tabs, type DescriptionsProps } from 'antd';
import { Descriptions, Tabs } from 'antd';
import {
CUSTOM_COMPONENT_TYPE_FORM_ITEM,
KEY_CUSTOM_COMPONENT_LABEL,
KEY_CUSTOM_COMPONENT_TYPE,
} from '@hera/plugin-core/client';
import React, { useEffect, useState } from 'react';
import { useRequest } from '@nocobase/client';
import React from 'react';
import _ from 'lodash';
import { formatCurrency, formatQuantity } from '../../utils/currencyUtils';
export const RecordSummary = (props) => {
const [products, setProducts] = useState([]);
const [leaseData, setLeaseData] = useState(null);
const [groupWeight, setGroupWeight] = useState([]);
const [recordWeight, setRecordWeight] = useState(0);
import { useCachedRequest, useLeaseItems } from '../hooks';
export const RecordSummary = observer((props) => {
const form = useForm();
const contractPlanId = form.values.contract_plan?.id;
const inContractPlanId = form.values.in_contract_plan?.id;
const outContractPlanId = form.values.out_contract_plan?.id;
const [contractPlanId, setContractPlanId] = useState(-1);
const [contractProducts, setContractProducts] = useState([]);
const [inContractProducts, setInContractProducts] = useState([]);
const [inContractPlanId, setInContractPlanId] = useState(-1);
const [outContractProducts, setOutContractProducts] = useState([]);
const [outContractPlanId, setOutContractPlanId] = useState(-1);
const contractPlans = useRequest<any>({
resource: 'contract_plans',
action: 'list',
params: {
appends: ['lease_items', 'lease_items.products'],
pageSize: 99999,
},
});
const reqWeightRules = useRequest<any>({
const leaseData = form.values.price_items;
const recordWeight = form.values.weight;
const reqWeightRules = useCachedRequest<any>({
resource: 'weight_rules',
action: 'list',
params: {
pageSize: 99999,
},
});
const reqProduct = useRequest<any>({
const reqProduct = useCachedRequest<any>({
resource: 'product',
action: 'list',
params: {
@ -47,468 +33,300 @@ export const RecordSummary = (props) => {
pageSize: 99999,
},
});
const { loading: loadingLeaseItems } = useRequest<any>(
{
resource: 'contract_plan_lease_items',
action: 'list',
params: {
appends: ['products'],
filter: {
contract_plan_id: contractPlanId,
},
pageSize: 9999,
},
},
{
refreshDeps: [contractPlanId],
onSuccess(data) {
if (data?.data?.length > 0) {
const result = data.data;
setContractProducts(result);
} else {
setContractProducts([]);
}
},
},
);
const { loading: loadingInLeaseItems } = useRequest<any>(
{
resource: 'contract_plan_lease_items',
action: 'list',
params: {
appends: ['products'],
filter: {
contract_plan_id: inContractPlanId,
},
pageSize: 9999,
},
},
{
refreshDeps: [inContractPlanId],
onSuccess(data) {
if (data?.data?.length > 0) {
const result = data.data;
setInContractProducts(result);
} else {
setInContractProducts([]);
}
},
},
);
const { loading: loadingOutLeaseItems } = useRequest<any>(
{
resource: 'contract_plan_lease_items',
action: 'list',
params: {
appends: ['products'],
filter: {
contract_plan_id: outContractPlanId,
},
pageSize: 9999,
},
},
{
refreshDeps: [outContractPlanId],
onSuccess(data) {
if (data?.data?.length > 0) {
const result = data.data;
setOutContractProducts(result);
} else {
setOutContractProducts([]);
}
},
},
);
const [value, setValue] = useState<DescriptionsProps['items']>([]);
const [inContractvalue, setInContractvalue] = useState<DescriptionsProps['items']>([]);
const [outContractvalue, setOutContractvalue] = useState<DescriptionsProps['items']>([]);
const [leasevalue, setLeasevalue] = useState<DescriptionsProps['items']>([]);
const form = useForm();
const calcLeaseSum = () => {
const allPrice = {
key: '1',
name: '总金额',
total: 0,
unit: '',
};
const weight = {
key: '2',
name: '理论重量',
total: 0,
unit: '吨',
};
const summaryProduct = {};
// 处理除实际重量的情况
const { data: leaseItems } = useLeaseItems(contractPlanId);
const { data: inLeaseItems } = useLeaseItems(inContractPlanId);
const { data: outLeaseItems } = useLeaseItems(outContractPlanId);
const allPrice = {
key: '1',
name: '总金额',
total: 0,
unit: '',
};
const weight = {
key: '2',
name: '理论重量',
total: 0,
unit: '吨',
};
const summaryProduct = {};
// 处理除实际重量的情况
form.values.items?.forEach((element) => {
// 1.获取产品的分类数据信息
const productCategory = reqProduct.data.data?.find(
(product) => product.category_id === element.product?.category_id,
)?.category;
if (productCategory) {
let summary, summaryUnit;
if (productCategory && productCategory.convertible) {
summary = (element.count || 0) * element.product?.ratio;
summaryUnit = productCategory.conversion_unit;
} else {
summary = element.count || 0;
summaryUnit = productCategory.unit;
}
weight.total += ((element.count || 0) * element.product?.weight) / 1000;
if (!element.product) return;
if (summaryProduct[element.product.category_id]) {
summaryProduct[element.product.category_id].total += summary;
} else {
summaryProduct[element.product.category_id] = {
name: productCategory.name,
total: summary,
unit: summaryUnit,
};
}
}
});
// 入库合同方案小结
const contractSummary = {};
// 出库合同方案小结
const outContractSummary = {};
// 报价方案小结
const leaseSummary = {};
// 计价数量的计算
const contractSummaryWeight = {
key: '0',
name: '理论重量',
total: 0,
unit: '吨',
};
if (
(form.values.category === RecordCategory.lease || form.values.category === RecordCategory.lease2lease) &&
(leaseItems || inLeaseItems)
) {
form.values.items?.forEach((element) => {
// 1.获取产品的分类数据信息
const productCategory = reqProduct.data.data?.find(
(product) => product.category_id === element.product?.category_id,
)?.category;
if (productCategory) {
let summary, summaryUnit;
if (productCategory && productCategory.convertible) {
summary = (element.count || 0) * element.product?.ratio;
summaryUnit = productCategory.conversion_unit;
} else {
summary = element.count || 0;
summaryUnit = productCategory.unit;
}
weight.total += ((element.count || 0) * element.product?.weight) / 1000;
if (!element.product) return;
if (summaryProduct[element.product.category_id]) {
summaryProduct[element.product.category_id].total += summary;
} else {
summaryProduct[element.product.category_id] = {
name: productCategory.name,
total: summary,
unit: summaryUnit,
};
}
}
});
// 入库合同方案小结
const contractSummary = {};
// 出库合同方案小结
const outContractSummary = {};
// 报价方案小结
const leaseSummary = {};
// 计价数量的计算
const contractSummaryWeight = {
key: '0',
name: '理论重量',
total: 0,
unit: '吨',
};
if (form.values.category === RecordCategory.lease || form.values.category === RecordCategory.lease2lease) {
form.values.items?.forEach((element) => {
const productCategory = reqProduct.data.data?.find(
(product) => product.category_id === element.product?.category_id,
)?.category;
// 合同方案
const in_contract = form.values.category === RecordCategory.lease ? contractProducts : inContractProducts;
const contractPlain = in_contract.find((item) =>
item.products.find(
(product) => product.id - 99999 === element.product?.category_id || product.id === element.product?.id,
),
);
// 计算合同方案的理论重量
const weightItem = calcTheoreticalWeight(element, reqWeightRules, contractPlain);
contractSummaryWeight.total += weightItem;
const res = subtotal(contractPlain, element, productCategory, reqWeightRules);
if (res) {
if (!contractSummary[element.product?.category_id]) {
contractSummary[element.product?.category_id] = {
name: productCategory?.name,
total: 0,
unit: res.unit,
};
}
// 合同方案
const in_contract = form.values.category === RecordCategory.lease ? leaseItems.data : inLeaseItems.data;
const contractPlain = in_contract.find((item) =>
item.products.find(
(product) => product.id - 99999 === element.product?.category_id || product.id === element.product?.id,
),
);
// 计算合同方案的理论重量
const weightItem = calcTheoreticalWeight(element, reqWeightRules, contractPlain);
contractSummaryWeight.total += weightItem;
const res = subtotal(contractPlain, element, productCategory, reqWeightRules);
if (res) {
if (!contractSummary[element.product?.category_id]) {
contractSummary[element.product?.category_id] = {
name: productCategory?.name,
total: (contractSummary[element.product?.category_id].total += res.count),
total: 0,
unit: res.unit,
};
}
});
}
const leaseSummaryWeight = {
key: '0',
name: '理论重量',
total: 0,
unit: '吨',
};
const leaseSummaryPrice = {
key: '99',
name: '总金额',
total: 0,
unit: '',
};
// 基本小结要带金额,报价小结也要带金额
if (form.values.category === RecordCategory.purchase || form.values.category === RecordCategory.purchase2lease) {
form.values.items?.forEach((element) => {
const productCategory = reqProduct.data.data?.find(
(product) => product.category_id === element.product?.category_id,
)?.category;
const rule = leaseData?.find(
(rule) =>
rule.product?.category_id === element.product?.category_id || rule.product?.id === element.product?.id,
);
if (rule) {
rule.conversion_logic_id = rule.conversion_logic.id;
const res = subtotal(rule, element, productCategory, reqWeightRules);
const price = calcLeasePriceSum(element, rule, productCategory, recordWeight);
leaseSummaryPrice.total += price;
// 计算合同方案的理论重量
const weightItem = calcTheoreticalWeight(element, reqWeightRules, rule);
leaseSummaryWeight.total += weightItem;
if (res) {
if (!leaseSummary[element.product?.category_id]) {
leaseSummary[element.product?.category_id] = {
name: productCategory?.name,
total: 0,
unit: res.unit,
};
}
contractSummary[element.product?.category_id] = {
name: productCategory?.name,
total: (contractSummary[element.product?.category_id].total += res.count),
unit: res.unit,
};
}
});
}
const leaseSummaryWeight = {
key: '0',
name: '理论重量',
total: 0,
unit: '吨',
};
const leaseSummaryPrice = {
key: '99',
name: '总金额',
total: 0,
unit: '',
};
// 基本小结要带金额,报价小结也要带金额
if (form.values.category === RecordCategory.purchase || form.values.category === RecordCategory.purchase2lease) {
form.values.items?.forEach((element) => {
const productCategory = reqProduct.data.data?.find(
(product) => product.category_id === element.product?.category_id,
)?.category;
const rule = leaseData?.find(
(rule) =>
rule.product?.category_id === element.product?.category_id || rule.product?.id === element.product?.id,
);
if (rule) {
rule.conversion_logic_id = rule.conversion_logic.id;
const res = subtotal(rule, element, productCategory, reqWeightRules);
const price = calcLeasePriceSum(element, rule, productCategory, recordWeight);
leaseSummaryPrice.total += price;
// 计算合同方案的理论重量
const weightItem = calcTheoreticalWeight(element, reqWeightRules, rule);
leaseSummaryWeight.total += weightItem;
if (res) {
if (!leaseSummary[element.product?.category_id]) {
leaseSummary[element.product?.category_id] = {
name: productCategory?.name,
total: (leaseSummary[element.product?.category_id].total += res.count),
unit: res.unit,
};
}
}
});
}
if (form.values.category === RecordCategory.purchase2lease) {
// 出现两次purchase2lease上面处理报价小结此处处理入库合同小结
form.values.items?.forEach((element) => {
const productCategory = reqProduct.data.data?.find(
(product) => product.category_id === element.product?.category_id,
)?.category;
const contractPlain = inContractProducts.find((item) =>
item.products.find(
(product) => product.id - 99999 === element.product?.category_id || product.id === element.product?.id,
),
);
const weightItem = calcTheoreticalWeight(element, reqWeightRules, contractPlain);
contractSummaryWeight.total += weightItem;
const res = subtotal(contractPlain, element, productCategory, reqWeightRules);
if (res) {
if (!contractSummary[element.product?.category_id]) {
contractSummary[element.product?.category_id] = {
name: productCategory?.name,
total: 0,
unit: res.unit,
};
}
leaseSummary[element.product?.category_id] = {
name: productCategory?.name,
total: (leaseSummary[element.product?.category_id].total += res.count),
unit: res.unit,
};
}
}
});
}
if (form.values.category === RecordCategory.purchase2lease && inLeaseItems) {
// 出现两次purchase2lease上面处理报价小结此处处理入库合同小结
form.values.items?.forEach((element) => {
const productCategory = reqProduct.data.data?.find(
(product) => product.category_id === element.product?.category_id,
)?.category;
const contractPlain = inLeaseItems.data.find((item) =>
item.products.find(
(product) => product.id - 99999 === element.product?.category_id || product.id === element.product?.id,
),
);
const weightItem = calcTheoreticalWeight(element, reqWeightRules, contractPlain);
contractSummaryWeight.total += weightItem;
const res = subtotal(contractPlain, element, productCategory, reqWeightRules);
if (res) {
if (!contractSummary[element.product?.category_id]) {
contractSummary[element.product?.category_id] = {
name: productCategory?.name,
total: (contractSummary[element.product?.category_id].total += res.count),
total: 0,
unit: res.unit,
};
}
});
}
const outContractSummaryWeight = {
key: '0',
name: '理论重量',
total: 0,
unit: '吨',
};
if (form.values.category === RecordCategory.lease2lease) {
// 此判断出现两次,上面处理入库小结,此处要处理出库小结
form.values.items?.forEach((element) => {
const productCategory = reqProduct.data.data?.find(
(product) => product.category_id === element.product?.category_id,
)?.category;
const contractPlain = outContractProducts.find((item) =>
item.products.find(
(product) => product.id - 99999 === element.product?.category_id || product.id === element.product?.id,
),
);
const weightItem = calcTheoreticalWeight(element, reqWeightRules, contractPlain);
outContractSummaryWeight.total += weightItem;
const res = subtotal(contractPlain, element, productCategory, reqWeightRules);
if (res) {
if (!outContractSummary[element.product?.category_id]) {
outContractSummary[element.product?.category_id] = {
name: productCategory?.name,
total: 0,
unit: res.unit,
};
}
contractSummary[element.product?.category_id] = {
name: productCategory?.name,
total: (contractSummary[element.product?.category_id].total += res.count),
unit: res.unit,
};
}
});
}
const outContractSummaryWeight = {
key: '0',
name: '理论重量',
total: 0,
unit: '吨',
};
if (form.values.category === RecordCategory.lease2lease && outLeaseItems) {
// 此判断出现两次,上面处理入库小结,此处要处理出库小结
form.values.items?.forEach((element) => {
const productCategory = reqProduct.data.data?.find(
(product) => product.category_id === element.product?.category_id,
)?.category;
const contractPlain = outLeaseItems.data.find((item) =>
item.products.find(
(product) => product.id - 99999 === element.product?.category_id || product.id === element.product?.id,
),
);
const weightItem = calcTheoreticalWeight(element, reqWeightRules, contractPlain);
outContractSummaryWeight.total += weightItem;
const res = subtotal(contractPlain, element, productCategory, reqWeightRules);
if (res) {
if (!outContractSummary[element.product?.category_id]) {
outContractSummary[element.product?.category_id] = {
name: productCategory?.name,
total: (outContractSummary[element.product?.category_id].total += res.count),
total: 0,
unit: res.unit,
};
}
});
}
// 常规小结
const items = [];
for (const key in summaryProduct) {
if (Object.prototype.hasOwnProperty.call(summaryProduct, key)) {
const element = summaryProduct[key];
items.push({ ...element, key: key });
}
}
const result =
form.values.category === RecordCategory.purchase || form.values.category === RecordCategory.purchase2lease
? [weight, ...items, allPrice]
: [weight, ...items];
const showItems = result
.map((item) => {
if (!item.total) return;
return {
label: item.name,
children: <p>{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}</p>,
outContractSummary[element.product?.category_id] = {
name: productCategory?.name,
total: (outContractSummary[element.product?.category_id].total += res.count),
unit: res.unit,
};
})
.filter(Boolean);
setValue(showItems);
// 合同小结/入库合同小结(租赁单,使用合同 租赁直发单,使用入库合同)
const inContract = [];
for (const key in contractSummary) {
if (Object.prototype.hasOwnProperty.call(contractSummary, key)) {
const element = contractSummary[key];
inContract.push({ ...element, key: key });
}
});
}
// 常规小结
const items = [];
for (const key in summaryProduct) {
if (Object.prototype.hasOwnProperty.call(summaryProduct, key)) {
const element = summaryProduct[key];
items.push({ ...element, key: key });
}
inContract.unshift(contractSummaryWeight);
const inContractItems = inContract
.map((item) => {
if (!item.total) return;
return {
label: item.name,
children: <p>{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}</p>,
};
})
.filter(Boolean);
setInContractvalue(inContractItems);
}
const result =
form.values.category === RecordCategory.purchase || form.values.category === RecordCategory.purchase2lease
? [weight, ...items, allPrice]
: [weight, ...items];
const value = result
.map((item) => {
if (!item.total) return;
return {
label: item.name,
children: <p>{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}</p>,
};
})
.filter(Boolean);
// 出库合同小结
const outContract = [];
for (const key in outContractSummary) {
if (Object.prototype.hasOwnProperty.call(outContractSummary, key)) {
const element = outContractSummary[key];
outContract.push({ ...element, key: key });
}
// 合同小结/入库合同小结(租赁单,使用合同 租赁直发单,使用入库合同)
const inContract = [];
for (const key in contractSummary) {
if (Object.prototype.hasOwnProperty.call(contractSummary, key)) {
const element = contractSummary[key];
inContract.push({ ...element, key: key });
}
outContract.unshift(outContractSummaryWeight);
const outContractItems = outContract
.map((item) => {
if (!item.total) return;
return {
label: item.name,
children: <p>{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}</p>,
};
})
.filter(Boolean);
setOutContractvalue(outContractItems);
}
inContract.unshift(contractSummaryWeight);
const inContractvalue = inContract
.map((item) => {
if (!item.total) return;
return {
label: item.name,
children: <p>{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}</p>,
};
})
.filter(Boolean);
// 报价小结
const lease = [];
for (const key in leaseSummary) {
if (Object.prototype.hasOwnProperty.call(leaseSummary, key)) {
const element = leaseSummary[key];
lease.push({ ...element, key: key });
}
// 出库合同小结
const outContract = [];
for (const key in outContractSummary) {
if (Object.prototype.hasOwnProperty.call(outContractSummary, key)) {
const element = outContractSummary[key];
outContract.push({ ...element, key: key });
}
lease.unshift(leaseSummaryWeight);
lease.push(leaseSummaryPrice);
const leaseItems = lease
.map((item) => {
if (!item.total) return;
return {
label: item.name,
children: <p>{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}</p>,
};
})
.filter(Boolean);
setLeasevalue(leaseItems);
};
useFormEffects(() => {
onFieldInit('items.*', () => {
setProducts(_.cloneDeep(form.values.items));
});
onFieldValueChange('items.*', () => {
setProducts(_.cloneDeep(form.values.items));
});
onFieldInit('price_items.*', () => {
setLeaseData(_.cloneDeep(form.values.price_items));
});
onFieldValueChange('price_items.*', () => {
setLeaseData(_.cloneDeep(form.values.price_items));
});
onFieldInit('group_weight_items.*', () => {
setGroupWeight(_.cloneDeep(form.values.group_weight_items));
});
onFieldValueChange('group_weight_items.*', () => {
setGroupWeight(_.cloneDeep(form.values.group_weight_items));
});
onFieldInit('weight', () => {
setRecordWeight(_.cloneDeep(form.values.weight));
});
onFieldValueChange('weight', () => {
setRecordWeight(_.cloneDeep(form.values.weight));
});
}
outContract.unshift(outContractSummaryWeight);
const outContractvalue = outContract
.map((item) => {
if (!item.total) return;
return {
label: item.name,
children: <p>{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}</p>,
};
})
.filter(Boolean);
onFieldInit('contract_plan', () => {
if (form.values.contract_plan) {
setContractPlanId(form.values.contract_plan.id);
} else {
setContractPlanId(-1);
}
});
onFieldValueChange('contract_plan', () => {
if (form.values.contract_plan) {
setContractPlanId(form.values.contract_plan.id);
} else {
setContractPlanId(-1);
}
});
onFieldInit('in_contract_plan', () => {
if (form.values.in_contract_plan) {
setInContractPlanId(form.values.in_contract_plan.id);
} else {
setInContractPlanId(-1);
}
});
onFieldValueChange('in_contract_plan', () => {
if (form.values.in_contract_plan) {
setInContractPlanId(form.values.in_contract_plan.id);
} else {
setInContractPlanId(-1);
}
});
onFieldInit('out_contract_plan', () => {
if (form.values.out_contract_plan) {
setOutContractPlanId(form.values.out_contract_plan.id);
} else {
setOutContractPlanId(-1);
}
});
onFieldValueChange('out_contract_plan', () => {
if (form.values.out_contract_plan) {
setOutContractPlanId(form.values.out_contract_plan.id);
} else {
setOutContractPlanId(-1);
}
});
});
useEffect(() => {
if (
!contractPlans.loading &&
!reqWeightRules.loading &&
!reqProduct.loading &&
!loadingLeaseItems &&
!loadingInLeaseItems &&
!loadingOutLeaseItems
) {
calcLeaseSum();
// 报价小结
const lease = [];
for (const key in leaseSummary) {
if (Object.prototype.hasOwnProperty.call(leaseSummary, key)) {
const element = leaseSummary[key];
lease.push({ ...element, key: key });
}
}, [
products,
leaseData,
groupWeight,
recordWeight,
contractPlans.loading,
reqWeightRules.loading,
reqProduct.loading,
loadingLeaseItems,
loadingInLeaseItems,
loadingOutLeaseItems,
]);
}
lease.unshift(leaseSummaryWeight);
lease.push(leaseSummaryPrice);
const leasevalue = lease
.map((item) => {
if (!item.total) return;
return {
label: item.name,
children: <p>{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}</p>,
};
})
.filter(Boolean);
const items = [
const resultItems = [
{ label: '基础', value: value },
{ label: '报价', value: leasevalue },
{ label: '出库合同', value: outContractvalue },
{ label: form.values.category === RecordCategory.lease ? '合同' : '入库合同', value: inContractvalue },
];
const trans: any[] = items
const trans: any[] = resultItems
.map((item, index) => {
if (item.value.length) {
const data = {
@ -534,7 +352,7 @@ export const RecordSummary = (props) => {
</div>
)
);
};
});
RecordSummary.displayName = 'RecordSummary';
RecordSummary[KEY_CUSTOM_COMPONENT_TYPE] = CUSTOM_COMPONENT_TYPE_FORM_ITEM;