diff --git a/packages/plugins/@hera/plugin-rental/package.json b/packages/plugins/@hera/plugin-rental/package.json index d4b5667d9..ac345f321 100644 --- a/packages/plugins/@hera/plugin-rental/package.json +++ b/packages/plugins/@hera/plugin-rental/package.json @@ -13,6 +13,7 @@ "antd": "5.*", "flatted": "^3.2.9", "qrcode": "^1.5.1", + "ahooks": "^3.7.2", "dayjs": "^1.11.8", "react-router-dom": "^6.11.2", "qrcode.react": "^3.1.0" diff --git a/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordItemCount.tsx b/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordItemCount.tsx index 6d62208df..8693bc983 100644 --- a/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordItemCount.tsx +++ b/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordItemCount.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import React from 'react'; import { CUSTOM_COMPONENT_TYPE_FIELD, KEY_CUSTOM_COMPONENT_LABEL, @@ -6,10 +6,9 @@ import { } from '@hera/plugin-core/client'; import { observer, useField, useForm } from '@formily/react'; import _ from 'lodash'; -import { useRequest } from '@nocobase/client'; import { formatQuantity } from '../../utils/currencyUtils'; import { Spin } from 'antd'; -import { stringify } from 'flatted'; +import { useCachedRequest } from '../hooks'; export const RecordItemCount = observer((props) => { const param = { @@ -19,8 +18,7 @@ export const RecordItemCount = observer((props) => { pageSize: 99999, }, }; - const cacheKey = stringify(param); - const { loading, data } = useRequest(param, { cacheKey }); + const { loading, data } = useCachedRequest(param); const form = useForm(); const field = useField(); diff --git a/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordItemValuationQuantity.tsx b/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordItemValuationQuantity.tsx index 26f575b80..dcd152f74 100644 --- a/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordItemValuationQuantity.tsx +++ b/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordItemValuationQuantity.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React from 'react'; import { CUSTOM_COMPONENT_TYPE_FIELD, KEY_CUSTOM_COMPONENT_LABEL, @@ -6,42 +6,12 @@ import { } from '@hera/plugin-core/client'; import { observer, useField, useForm } from '@formily/react'; import _ from 'lodash'; -import { useRequest } from '@nocobase/client'; import { ConversionLogics, RecordCategory } from '../../utils/constants'; import { formatQuantity } from '../../utils/currencyUtils'; -import { stringify } from 'flatted'; - -function useCachedRequest

(params: {}, options = {}) { - const cacheKey = stringify(params); - return useRequest

(params, { cacheKey, ...options }); -} - -const useLeaseItems = (planId) => { - const params = { - resource: 'contract_plan_lease_items', - action: 'list', - params: { - appends: ['products'], - filter: { - contract_plan_id: planId, - }, - pageSize: 99999, - }, - }; - const { data, loading, run } = useCachedRequest(params, { - manual: true, - }); - useEffect(() => { - if (planId) { - run(); - } - }, [planId]); - return { data, loading }; -}; +import { useCachedRequest, useLeaseItems } from '../hooks'; // 计价数量 export const RecordItemValuationQuantity = observer((props) => { - console.count('计价数量'); const form = useForm(); const field = useField(); const contractPlanId = form.getValuesIn('contract_plan')?.id; @@ -87,7 +57,7 @@ export const RecordItemValuationQuantity = observer((props) => { const count = subtotal(rule, item, productCategory, reqWeightRules); count && result.push({ label: '合同', value: count }); } - + // 采购 if (form.values.category === RecordCategory.purchase && priceItems) { const rule = priceItems?.find( (rule) => rule.product?.category_id === item.product?.category_id || rule.product?.id === item.product?.id, @@ -98,10 +68,11 @@ export const RecordItemValuationQuantity = observer((props) => { count && result.push({ label: '报价', value: count }); } } + // 暂存或结存 if (form.values.category === RecordCategory.inventory || form.values.category === RecordCategory.staging) { result.push([{ label: '', value: '-' }]); } - + // 采购直发 if (form.values.category === RecordCategory.purchase2lease && priceItems && inLeaseItems) { const rule = priceItems?.find( (rule) => rule.product?.category_id === item.product?.category_id || rule.product?.id === item.product?.id, @@ -119,7 +90,7 @@ export const RecordItemValuationQuantity = observer((props) => { const count = subtotal(leaseRule, item, productCategory, reqWeightRules); count && result.push({ label: '入库合同', value: count }); } - + // 租赁直发 if (form.values.category === RecordCategory.lease2lease && inLeaseItems && outLeaseItems) { const contractPlain_out = outLeaseItems.data.find((leaseItem) => leaseItem.products.find( diff --git a/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordProductScope.tsx b/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordProductScope.tsx index cd9520ec7..38067690f 100644 --- a/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordProductScope.tsx +++ b/packages/plugins/@hera/plugin-rental/src/client/custom-components/RecordProductScope.tsx @@ -1,222 +1,78 @@ import _ from 'lodash'; import { Spin } from 'antd'; -import React, { useEffect, useState } from 'react'; -import { onFieldValueChange, onFieldInit } from '@formily/core'; -import { useForm, useFormEffects } from '@formily/react'; -import { useRequest } from '@nocobase/client'; +import React from 'react'; +import { observer, useForm } from '@formily/react'; import { RecordCategory } from '../../utils/constants'; import { CUSTOM_COMPONENT_TYPE_ASSOCIATED_FIELD, KEY_CUSTOM_COMPONENT_LABEL, KEY_CUSTOM_COMPONENT_TYPE, } from '@hera/plugin-core/client'; +import { useCachedRequest, useLeaseItems } from '../hooks'; +import { useDeepCompareEffect } from 'ahooks'; -export const RecordProductScope = () => { +export const RecordProductScope = observer(() => { const form = useForm(); - const [priceProducts, setPriceProducts] = useState([]); - const [contractPlanId, setContractPlanId] = useState(-1); - const [contractProducts, setContractProducts] = useState([]); - const [inContractPlanId, setInContractPlanId] = useState(-1); - const [outContractPlanId, setOutContractPlanId] = useState(-1); - const [inContractProducts, setInContractProducts] = useState([]); - const [outContractProducts, setOutContractProducts] = useState([]); - const [required, setRequired] = useState({ price: false, contract: false, inContract: false, outContract: false }); - const { data, loading } = useRequest({ + const contractPlanId = form.getValuesIn('contract_plan')?.id; + const inContractPlanId = form.getValuesIn('in_contract_plan')?.id; + const outContractPlanId = form.getValuesIn('out_contract_plan')?.id; + + console.log('产品范围'); + let required = { price: false, contract: false, inContract: false, outContract: false }; + const { data, loading } = useCachedRequest({ resource: 'product_category', action: 'list', params: { - pageSize: 9999, + 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 items = data.data as { products: { category_id: string }[] }[]; - const result = items.reduce((acc, current) => { - acc.push(...current.products.map((item) => ({ id: item.category_id }))); - return acc; - }, []); - setContractProducts(result); - } else { - setContractProducts([]); - } - }, - }, - ); + const { data: leaseItems, loading: leaseItemsLoading } = useLeaseItems(contractPlanId); + const { data: inLeaseItems, loading: inLeaseItemsLoading } = useLeaseItems(inContractPlanId); + const { data: outLeaseItems, loading: outLeaseItemsLoading } = useLeaseItems(outContractPlanId); - // 租赁直发,入库合同方案产品 - 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 items = data.data as { products: { category_id: string }[] }[]; - const result = items.reduce((acc, current) => { - acc.push(...current.products.map((item) => ({ id: item.category_id }))); - return acc; - }, []); - 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 items = data.data as { products: { category_id: string }[] }[]; - const result = items.reduce((acc, current) => { - acc.push(...current.products.map((item) => ({ id: item.category_id }))); - return acc; - }, []); - setOutContractProducts(result); - } else { - setOutContractProducts([]); - } - }, - }, - ); + const contractProducts = + leaseItems?.data.reduce((acc, current) => { + acc.push(...current.products.map((item) => ({ id: item.category_id }))); + return acc; + }, []) ?? []; - useFormEffects(() => { - onFieldValueChange('price_items.*.product', () => { - setPriceProducts(_.get(form.values, 'price_items', []).map((item) => ({ id: item.product.category_id }))); - }); - }); - useFormEffects(() => { - 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); - } - }); + const inContractProducts = + inLeaseItems?.data.reduce((acc, current) => { + acc.push(...current.products.map((item) => ({ id: item.category_id }))); + return acc; + }, []) ?? []; - 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); - } - }); - }); - useFormEffects(() => { - onFieldInit('category', () => { - switch (form.values.category) { - case RecordCategory.lease: - setRequired({ price: false, contract: true, inContract: false, outContract: false }); - break; - case RecordCategory.purchase: - setRequired({ price: true, contract: false, inContract: false, outContract: false }); - break; - case RecordCategory.lease2lease: // 出库合同,入库合同的产品范围交集 - setRequired({ price: false, contract: false, inContract: true, outContract: true }); - break; - case RecordCategory.purchase2lease: // 报价,入库合同的产品范围交集 - setRequired({ price: true, contract: false, inContract: true, outContract: false }); - break; - case RecordCategory.inventory: - case RecordCategory.staging: - setRequired({ price: false, contract: false, inContract: false, outContract: false }); - break; - default: - break; - } - }); - onFieldValueChange('category', () => { - switch (form.values.category) { - case RecordCategory.lease: - setRequired({ price: false, contract: true, inContract: false, outContract: false }); - break; - case RecordCategory.purchase: - setRequired({ price: true, contract: false, inContract: false, outContract: false }); - break; - case RecordCategory.lease2lease: // 出库合同,入库合同的产品范围交集 - setRequired({ price: false, contract: false, inContract: true, outContract: true }); - break; - case RecordCategory.purchase2lease: // 报价,入库合同的产品范围交集 - setRequired({ price: true, contract: false, inContract: true, outContract: false }); - break; - case RecordCategory.inventory: - case RecordCategory.staging: - setRequired({ price: false, contract: false, inContract: false, outContract: false }); - break; - default: - break; - } - }); - }); - useEffect(() => { - if (loading || loadingLeaseItems || loadingInLeaseItems || loadingOutLeaseItems) { - return; - } - let result = data.data; + const outContractProducts = + outLeaseItems?.data.reduce((acc, current) => { + acc.push(...current.products.map((item) => ({ id: item.category_id }))); + return acc; + }, []) ?? []; + + const priceProducts = + form.values.price_items?.filter((item) => item.product).map((item) => ({ id: item.product.category_id })) ?? []; + + switch (form.values.category) { + case RecordCategory.lease: + required = { price: false, contract: true, inContract: false, outContract: false }; + break; + case RecordCategory.purchase: + required = { price: true, contract: false, inContract: false, outContract: false }; + break; + case RecordCategory.lease2lease: // 出库合同,入库合同的产品范围交集 + required = { price: false, contract: false, inContract: true, outContract: true }; + break; + case RecordCategory.purchase2lease: // 报价,入库合同的产品范围交集 + required = { price: true, contract: false, inContract: true, outContract: false }; + break; + case RecordCategory.inventory: + case RecordCategory.staging: + required = { price: false, contract: false, inContract: false, outContract: false }; + break; + default: + break; + } + useDeepCompareEffect(() => { + let result = data?.data ?? []; if (required.inContract && required.outContract) { // 租赁直发单 const intersection = _.intersectionBy(inContractProducts, outContractProducts, 'id'); @@ -230,25 +86,11 @@ export const RecordProductScope = () => { result = _.intersectionBy(result, contractProducts, 'id'); } form.setValues({ - // FIXME product_scope: result, }); - }, [ - required.price, - required.contract, - data?.data, - priceProducts, - contractProducts, - inContractProducts, - outContractProducts, - form, - loading, - loadingLeaseItems, - loadingInLeaseItems, - loadingOutLeaseItems, - ]); - return loading || loadingLeaseItems || loadingInLeaseItems || loadingOutLeaseItems ? : <>; -}; + }, [required, data, priceProducts, contractProducts, inContractProducts, outContractProducts, form]); + return loading || leaseItemsLoading || inLeaseItemsLoading || outLeaseItemsLoading ? : <>; +}); RecordProductScope.displayName = 'RecordProductScope'; RecordProductScope[KEY_CUSTOM_COMPONENT_TYPE] = CUSTOM_COMPONENT_TYPE_ASSOCIATED_FIELD; diff --git a/packages/plugins/@hera/plugin-rental/src/client/hooks/index.tsx b/packages/plugins/@hera/plugin-rental/src/client/hooks/index.tsx new file mode 100644 index 000000000..5238ba261 --- /dev/null +++ b/packages/plugins/@hera/plugin-rental/src/client/hooks/index.tsx @@ -0,0 +1,31 @@ +import { useRequest } from '@nocobase/client'; +import { stringify } from 'flatted'; +import { useEffect } from 'react'; + +export function useCachedRequest

(params: {}, options = {}) { + const cacheKey = stringify(params); + return useRequest

(params, { cacheKey, ...options }); +} + +export const useLeaseItems = (planId) => { + const params = { + resource: 'contract_plan_lease_items', + action: 'list', + params: { + appends: ['products'], + filter: { + contract_plan_id: planId, + }, + pageSize: 99999, + }, + }; + const { data, loading, run } = useCachedRequest(params, { + manual: true, + }); + useEffect(() => { + if (planId) { + run(); + } + }, [planId]); + return { data, loading }; +};