From e81f00eb00efa513ccf236cfc6eca0ba50693a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E6=99=AF=E5=AD=A6?= <5412262+sun_jing_xue@user.noreply.gitee.com> Date: Mon, 11 Aug 2025 11:25:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=20=E6=89=80=E6=9C=89?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=93=81=E7=B1=BB=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SupplierSelector/SupplierSelector.tsx | 4 +- src/components/TreeCategorySelector/index.tsx | 75 +++++++++++-------- .../admission/SupplierCategoryEntry/index.tsx | 4 +- .../SupplierCategoryEntryReview/index.tsx | 4 +- .../components/CreateModal.tsx | 18 ++--- .../admission/admissionManagement/index.tsx | 4 +- .../backend/cooperateEnterprise/index.tsx | 4 +- .../mySupplierInquiry/index.tsx | 4 +- .../components/SupplierSelectModal.tsx | 4 +- .../components/SupplierSelectModal.tsx | 4 +- .../components/BasicInfoStep.tsx | 2 +- .../supplierAnnualTemplateManage.tsx | 4 +- .../supplierAnnualTemplateManageAdd.tsx | 2 +- .../components/BasicInfoStep.tsx | 2 +- .../supplierTemplateManage.tsx | 4 +- .../supplierTemplateManageAdd.tsx | 2 +- 16 files changed, 78 insertions(+), 63 deletions(-) diff --git a/src/components/SupplierSelector/SupplierSelector.tsx b/src/components/SupplierSelector/SupplierSelector.tsx index b55ab33..d00c354 100644 --- a/src/components/SupplierSelector/SupplierSelector.tsx +++ b/src/components/SupplierSelector/SupplierSelector.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'; import { Input, Select, Row, Col, Table, Button, Form, Tooltip, message } from 'antd'; import { RightOutlined, LeftOutlined } from '@ant-design/icons'; import { getSupplierPage } from '@/servers/api/supplier'; -import CategorySelector from '@/components/CategorySelector/CategorySelector'; +import CategorySelector from '@/components/TreeCategorySelector'; import './SupplierSelector.less'; import { useIntl } from 'umi'; import { useSupplierDetailModal } from '@/components/SupplierDetailModalContext/SupplierDetailModalContext'; @@ -304,7 +304,7 @@ const SupplierSelector: React.FC = ({ name="categoryId" label={intl.formatMessage({ id: 'supplierTaskManage.form.category' })} > - + diff --git a/src/components/TreeCategorySelector/index.tsx b/src/components/TreeCategorySelector/index.tsx index aa67249..3fa552c 100644 --- a/src/components/TreeCategorySelector/index.tsx +++ b/src/components/TreeCategorySelector/index.tsx @@ -6,8 +6,8 @@ import { categoryTree } from './services'; const { Search } = Input; interface Props { - value?: React.Key[]; - onChange?: (value: React.Key[]) => void; + value?: React.Key[] | React.Key; + onChange?: (value: React.Key[] | React.Key) => void; onChangeDetail?: (payload: { categoryIds: string[]; coscoAccessCategoryList: { @@ -110,7 +110,6 @@ const TreeCategorySelector: React.FC = ({ parentKeysMapRef.current = parentKeysMap; leafSetRef.current = leafSet; initialExpandedKeysRef.current = Array.from(new Set(collectExpand)); - console.log(tree, 'tree'); return tree; @@ -145,18 +144,36 @@ const TreeCategorySelector: React.FC = ({ return { tree, expandKeys: Array.from(expand) }; }; + // 1) 定义 eqArray(放在组件函数体内、useEffect 之上) +const eqArray = (a: React.Key[] = [], b: React.Key[] = []) => + a.length === b.length && a.every((x, i) => x === b[i]); + + // Props.value 是单个或数组:value?: React.Key[] | React.Key + // 2) 归一化成数组(一定放在 useEffect 之前,且只声明一次) +const valueArray = useMemo(() => { + if (Array.isArray(value)) return value; + return value == null ? [] : [value]; +}, [value]); + + // 输入框显示名称(缺的就是它) + const selectedNames = useMemo( + () => + valueArray + .map((k) => keyTitleMapRef.current[String(k)] || String(k)) + .filter(Boolean), + [valueArray, origin] + ); + // 拉数据 useEffect(() => { setLoading(true); - console.log(1); - categoryTree() .then((res: any) => { if (res?.code === 200) { const tree = buildTreeOnce(res.data || []); setOrigin(tree); setDisplayTree(tree); - // 初始展开 + // 初始展开 两级展开 setExpandedKeys(initialExpandedKeysRef.current); setAutoExpandParent(true); } @@ -164,18 +181,19 @@ const TreeCategorySelector: React.FC = ({ .finally(() => setLoading(false)); }, []); - // 打开时同步外部值 + 默认两级展开 useEffect(() => { if (!open) return; - if (multiple) setCheckedAllKeys(Array.isArray(value) ? value : []); - else setSelectedKey(value && value.length ? value[0] : null); - + if (multiple) { + if (!eqArray(checkedAllKeys, valueArray)) setCheckedAllKeys(valueArray); + } else { + const next = valueArray.length ? valueArray[0] : null; + console.log(valueArray,'valueArray',next, selectedKey); + if (selectedKey !== next) setSelectedKey(next); + } setSearch(''); setDisplayTree(origin); - setExpandedKeys(initialExpandedKeysRef.current); setAutoExpandParent(true); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [open, multiple]); + }, [open, multiple, valueArray, origin]); // 清理搜索定时器 useEffect(() => { @@ -190,8 +208,8 @@ const TreeCategorySelector: React.FC = ({ // 当 disabledCategories 改变时,更新树数据的 disabled 状态 useEffect(() => { if (!origin.length) return; - if(disabledCategories.length !== 0) { - const updateDisabled = (nodes: TreeNode[]): TreeNode[] => + if (disabledCategories.length !== 0) { + const updateDisabled = (nodes: TreeNode[]): TreeNode[] => nodes.map((n) => ({ ...n, disabled: disabledCategories.includes(n.key), @@ -210,19 +228,15 @@ const TreeCategorySelector: React.FC = ({ setExpandedKeys(expandKeys); } } - + }, [disabledCategories]); - // 输入框显示名称(缺的就是它) - const selectedNames = useMemo( - () => (value as React.Key[]) - .map((k) => keyTitleMapRef.current[String(k)] || String(k)) - .filter(Boolean), - [value] - ); + // Props.value 是单个或数组:value?: React.Key[] | React.Key + + // 2) 归一化成数组(一定放在 useEffect 之前,且只声明一次) // 搜索:逐字符匹配 + 只显示命中分支 - const onSearchChange = (val: string) => { + const onSearchChange = (val: string) => { const searchValue = val ?? ''; setSearch(searchValue); @@ -294,7 +308,7 @@ const TreeCategorySelector: React.FC = ({ }]; setSelectedKey(id); - onChange?.([id]); + onChange?.(id); onChangeDetail?.({ categoryIds: [id], coscoAccessCategoryList: list }); setOpen(false); @@ -330,7 +344,7 @@ const TreeCategorySelector: React.FC = ({ }; const handleClear = () => { - onChange?.([]); + onChange?.(multiple ? [] : ''); onChangeDetail?.({ categoryIds: [], coscoAccessCategoryList: [] }); }; @@ -358,7 +372,7 @@ const TreeCategorySelector: React.FC = ({ style={{ paddingRight: '30px', boxSizing: 'border-box' }} // suffix={} /> - {hover && (value?.length ?? 0) > 0 && ( + {hover && valueArray.length > 0 && ( { e.stopPropagation(); @@ -395,8 +409,8 @@ const TreeCategorySelector: React.FC = ({ setSearch(e.target.value)} // 只更新本地状态 - onSearch={(val) => onSearchChange(val)} // 回车/按钮点击才执行原逻辑 + onChange={(e) => setSearch(e.target.value)} // 只更新本地状态 + onSearch={(val) => onSearchChange(val)} // 回车/按钮点击才执行原逻辑 value={search} style={{ marginBottom: 8 }} /> @@ -424,7 +438,8 @@ const TreeCategorySelector: React.FC = ({ checkable={multiple} onCheck={multiple ? handleCheck : undefined} checkedKeys={multiple ? checkedAllKeys : undefined} - selectedKeys={multiple ? [] : (selectedKey ? [selectedKey] : [])} + selectedKeys={multiple ? [] : (valueArray.length ? [valueArray[0]] : [])} + // selectedKeys={multiple ? [] : (selectedKey ? [selectedKey] : [])} onSelect={multiple ? handleSelectExpand : handleSelect} /> diff --git a/src/pages/supplier/admission/SupplierCategoryEntry/index.tsx b/src/pages/supplier/admission/SupplierCategoryEntry/index.tsx index 6cd7936..e559e97 100644 --- a/src/pages/supplier/admission/SupplierCategoryEntry/index.tsx +++ b/src/pages/supplier/admission/SupplierCategoryEntry/index.tsx @@ -6,7 +6,7 @@ import type { ColumnsType, TablePaginationConfig } from 'antd/es/table'; import ViewModal from './components/ViewModal'; //发起准入 弹窗 import CreateModal from './components/CreateModal'; -import CategorySelector from '@/components/CategorySelector'; +import CategorySelector from '@/components/TreeCategorySelector'; import AdmissionTypeSelect from '@/components/CommonSelect/AdmissionTypeSelect'; import AccessDepartmentSelect from "@/components/AccessDepartmentSelect" //接口 @@ -147,7 +147,7 @@ const SupplierCategoryEntry: React.FC = () => { - + { @@ -242,7 +242,7 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi @@ -253,7 +253,7 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi 线上准入 @@ -267,7 +267,7 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi form.setFieldsValue({ categoryIds: ids })} @@ -282,7 +282,7 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi