From fbe0c149202c0efde8712ee1e417b6de943de308 Mon Sep 17 00:00:00 2001 From: sealday Date: Sat, 9 Mar 2024 02:56:27 +0800 Subject: [PATCH] perf: optimize record summary --- .../custom-components/RecordSummary.tsx | 716 +++++++----------- 1 file changed, 267 insertions(+), 449 deletions(-) diff --git a/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordSummary.tsx b/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordSummary.tsx index 8bede2327..fb21dae47 100644 --- a/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordSummary.tsx +++ b/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordSummary.tsx @@ -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({ - resource: 'contract_plans', - action: 'list', - params: { - appends: ['lease_items', 'lease_items.products'], - pageSize: 99999, - }, - }); - const reqWeightRules = useRequest({ + const leaseData = form.values.price_items; + const recordWeight = form.values.weight; + const reqWeightRules = useCachedRequest({ resource: 'weight_rules', action: 'list', params: { pageSize: 99999, }, }); - const reqProduct = useRequest({ + const reqProduct = useCachedRequest({ resource: 'product', action: 'list', params: { @@ -47,468 +33,300 @@ export const RecordSummary = (props) => { pageSize: 99999, }, }); - const { loading: loadingLeaseItems } = useRequest( - { - 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( - { - 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( - { - 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([]); - const [inContractvalue, setInContractvalue] = useState([]); - const [outContractvalue, setOutContractvalue] = useState([]); - const [leasevalue, setLeasevalue] = useState([]); - 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:

{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}

, + 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:

{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}

, - }; - }) - .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:

{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}

, + }; + }) + .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:

{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}

, - }; - }) - .filter(Boolean); - setOutContractvalue(outContractItems); + } + inContract.unshift(contractSummaryWeight); + const inContractvalue = inContract + .map((item) => { + if (!item.total) return; + return { + label: item.name, + children:

{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}

, + }; + }) + .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:

{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}

, - }; - }) - .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:

{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}

, + }; + }) + .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:

{item.unit ? formatQuantity(item.total, 2) + item.unit : formatCurrency(item.total, 2)}

, + }; + }) + .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) => { ) ); -}; +}); RecordSummary.displayName = 'RecordSummary'; RecordSummary[KEY_CUSTOM_COMPONENT_TYPE] = CUSTOM_COMPONENT_TYPE_FORM_ITEM;