From 6103a8e5d2316af7fcf6b246e9e866e5216476f0 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期三, 18 三月 2026 11:11:34 +0800
Subject: [PATCH] #统一修改下拉框问题

---
 rsf-admin/src/page/components/DictSelect.jsx                  |   44 ++++----
 rsf-admin/src/page/components/TaskPathTemplateMergeSelect.jsx |   13 ++
 rsf-admin/src/page/components/BasStationSelect.jsx            |   57 +++--------
 rsf-admin/src/page/components/TreeSelectInput.jsx             |   73 +++++++-------
 rsf-admin/src/page/components/StatusSelectInput.jsx           |   11 ++
 rsf-admin/src/page/components/WarehouseSelect.jsx             |   67 ++++---------
 rsf-admin/src/page/components/DictionaryArraySelect.jsx       |   17 ++
 7 files changed, 128 insertions(+), 154 deletions(-)

diff --git a/rsf-admin/src/page/components/BasStationSelect.jsx b/rsf-admin/src/page/components/BasStationSelect.jsx
index 757044c..594a40b 100644
--- a/rsf-admin/src/page/components/BasStationSelect.jsx
+++ b/rsf-admin/src/page/components/BasStationSelect.jsx
@@ -1,30 +1,14 @@
 import { useState, useEffect } from 'react';
 import {
-    useTranslate, useNotify, required
+    useTranslate, useNotify, required, AutocompleteInput
 } from 'react-admin';
-import { useController } from 'react-hook-form';
 import request from '@/utils/request';
-import { Select, MenuItem, FormControl, InputLabel } from '@mui/material';
 
 const BasStationSelect = (props) => {
     const { dictTypeCode, label, name, validate, ...params } = props;
     const translate = useTranslate();
     const notify = useNotify();
     const [list, setList] = useState([]);
-
-    // 浣跨敤 useController 涓� react-hook-form 闆嗘垚
-    const { field, fieldState } = useController({
-        name: name,
-        rules: validate ? {
-            validate: (value) => {
-                for (const rule of validate) {
-                    const result = rule(value);
-                    if (result) return result;
-                }
-                return true;
-            }
-        } : undefined
-    });
 
     useEffect(() => {
         http();
@@ -44,32 +28,21 @@
         }
     };
 
-    const handleChange = (event) => {
-        const selectedValue = event.target.value;
-        field.onChange(selectedValue);
-    };
-
-    const validValue = list.some(item => item.id === field.value) ? field.value : '';
-
     return (
-        <FormControl required fullWidth error={!!fieldState.error}>
-            <InputLabel id={`${name}-label`}>{label}</InputLabel>
-            <Select
-                labelId={`${name}-label`}
-                value={validValue}
-                variant="filled"
-                onChange={handleChange}
-                size='small'
-            >
-                {list.map((item) => (
-                    <MenuItem
-                        key={item.id}
-                        value={item.id}>
-                        {item.name}
-                    </MenuItem>
-                ))}
-            </Select>
-        </FormControl>
+        <AutocompleteInput
+            source={name}
+            label={label}
+            choices={list}
+            validate={validate}
+            options={{
+                ListboxProps: {
+                    style: { maxHeight: '200px' }
+                },
+                ...(params.options || {})
+            }}
+            fullWidth
+            {...params}
+        />
     );
 };
 
diff --git a/rsf-admin/src/page/components/DictSelect.jsx b/rsf-admin/src/page/components/DictSelect.jsx
index df17b17..8f3531e 100644
--- a/rsf-admin/src/page/components/DictSelect.jsx
+++ b/rsf-admin/src/page/components/DictSelect.jsx
@@ -3,7 +3,7 @@
     useTranslate, useNotify, required
 } from 'react-admin';
 import request from '@/utils/request';
-import { Select, MenuItem, FormControl, InputLabel } from '@mui/material';
+import { Autocomplete, TextField, FormControl } from '@mui/material';
 
 const DictSelect = (props) => {
     const { dictTypeCode, label, group, value, onChange, ...params } = props;
@@ -29,33 +29,35 @@
         }
     };
 
-    const handleChange = (event) => {
-        const selectedValue = event.target.value;
+    const validValueObj = list.find(item => item.value === value) || null;
+
+    const handleChange = (event, newValue) => {
         if (onChange) {
-            onChange(event);
+            onChange({ target: { value: newValue ? newValue.value : '' } });
         }
     };
 
-    const validValue = list.some(item => item.value === value) ? value : '';
-
     return (
-        <FormControl fullWidth>
-            <InputLabel id="demo-select-small-label">{label}</InputLabel>
-            <Select
-                labelId="demo-select-small-label"
-                value={validValue}
-                variant="filled"
+        <FormControl fullWidth size="small">
+            <Autocomplete
+                value={validValueObj}
                 onChange={handleChange}
-                size='small'
-            >
-                {list.map((item) => (
-                    <MenuItem key={item.value} value={item.value}>
-                        {item.label}
-                    </MenuItem>
-                ))}
-            </Select>
+                options={list}
+                getOptionLabel={(option) => option.label || ''}
+                isOptionEqualToValue={(option, val) => option.value === val.value}
+                size="small"
+                ListboxProps={{ style: { maxHeight: '200px' } }}
+                renderInput={(p) => (
+                    <TextField
+                        {...p}
+                        label={label}
+                        variant="filled"
+                    />
+                )}
+                {...params}
+            />
         </FormControl>
     );
 };
 
-export default DictSelect;    
\ No newline at end of file
+export default DictSelect;
\ No newline at end of file
diff --git a/rsf-admin/src/page/components/DictionaryArraySelect.jsx b/rsf-admin/src/page/components/DictionaryArraySelect.jsx
index f4f929c..f263326 100644
--- a/rsf-admin/src/page/components/DictionaryArraySelect.jsx
+++ b/rsf-admin/src/page/components/DictionaryArraySelect.jsx
@@ -4,7 +4,8 @@
     Button, useListContext, SelectInput,
     required, SelectArrayInput,
     useTranslate, useNotify,
-    SelectArrayInputClasses
+    SelectArrayInputClasses,
+    AutocompleteInput, AutocompleteArrayInput
 } from 'react-admin';
 import request from '@/utils/request';
 
@@ -12,7 +13,7 @@
     const { 
         dictTypeCode, 
         name, 
-        multiple = false, 
+        multiple = true, 
         perPage = 100,  // 榛樿姣忛〉鏄剧ず100鏉℃暟鎹�
         page = 1,       // 榛樿绗竴椤�
         ...parmas 
@@ -53,13 +54,21 @@
         }
     };
 
-    const InputComponent = multiple ? SelectArrayInput : SelectInput;
+    const InputComponent = multiple ? AutocompleteArrayInput : AutocompleteInput;
 
     return (
-        <SelectArrayInput
+        <InputComponent
             source={name}
             choices={list}
             isLoading={loading}
+            options={{
+                ListboxProps: {
+                    style: {
+                        maxHeight: '200px',
+                    }
+                },
+                ...(parmas.options || {})
+            }}
             {...parmas}
         />
     );
diff --git a/rsf-admin/src/page/components/StatusSelectInput.jsx b/rsf-admin/src/page/components/StatusSelectInput.jsx
index 11031ca..c1178e6 100644
--- a/rsf-admin/src/page/components/StatusSelectInput.jsx
+++ b/rsf-admin/src/page/components/StatusSelectInput.jsx
@@ -2,6 +2,7 @@
     SelectInput,
     required,
     useTranslate,
+    AutocompleteInput
 } from 'react-admin';
 
 const StatusSelectInput = (props) => {
@@ -9,7 +10,7 @@
     const translate = useTranslate();
 
     return (
-        <SelectInput
+        <AutocompleteInput
             label={translate('common.field.status')}
             source="status"
             validate={[require && required()]}
@@ -19,6 +20,14 @@
             ]}
             defaultValue={defaultValue}
             helperText={false}
+            options={{
+                ListboxProps: {
+                    style: {
+                        maxHeight: '200px',
+                    }
+                },
+                ...(rest.options || {})
+            }}
             {...rest}
         />
     )
diff --git a/rsf-admin/src/page/components/TaskPathTemplateMergeSelect.jsx b/rsf-admin/src/page/components/TaskPathTemplateMergeSelect.jsx
index c6609bc..00bdea6 100644
--- a/rsf-admin/src/page/components/TaskPathTemplateMergeSelect.jsx
+++ b/rsf-admin/src/page/components/TaskPathTemplateMergeSelect.jsx
@@ -4,7 +4,8 @@
     Button, useListContext, SelectInput,
     required, SelectArrayInput,
     useTranslate, useNotify,
-    SelectArrayInputClasses
+    SelectArrayInputClasses,
+    AutocompleteInput, AutocompleteArrayInput
 } from 'react-admin';
 import request from '@/utils/request';
 
@@ -48,13 +49,21 @@
         }
     };
 
-    const InputComponent = multiple ? SelectArrayInput : SelectInput;
+    const InputComponent = multiple ? AutocompleteArrayInput : AutocompleteInput;
 
     return (
         <InputComponent
             source={name}
             choices={list}
             isLoading={loading}
+            options={{
+                ListboxProps: {
+                    style: {
+                        maxHeight: '200px',
+                    }
+                },
+                ...(parmas.options || {})
+            }}
             {...parmas}
         />
     );
diff --git a/rsf-admin/src/page/components/TreeSelectInput.jsx b/rsf-admin/src/page/components/TreeSelectInput.jsx
index fb5de88..5e1bebb 100644
--- a/rsf-admin/src/page/components/TreeSelectInput.jsx
+++ b/rsf-admin/src/page/components/TreeSelectInput.jsx
@@ -1,6 +1,6 @@
 import React, { useState, useEffect } from 'react';
 import { useCreateContext, useTranslate, useRecordContext } from 'react-admin'
-import { MenuItem, Select, FormControl, InputLabel, Typography } from '@mui/material';
+import { Autocomplete, TextField, FormControl } from '@mui/material';
 import request from '@/utils/request';
 import * as Common from '@/utils/common';
 import { useFormContext } from 'react-hook-form';
@@ -22,7 +22,9 @@
                 condition: filter
             });
             if (res?.data?.code === 200) {
-                setTreeData(Common.flattenTree(res.data.data));
+                // Add a null option at the beginning
+                const flatTree = Common.flattenTree(res.data.data);
+                setTreeData([{ id: 0, name: ' ' }, ...flatTree]);
                 setProxyVal(val);
             } else {
                 notify(res.data.msg);
@@ -31,50 +33,45 @@
         http(resource);
     }, [filter, value]);
 
-    const handleChange = (event) => {
-        const val = event.target.value;
-        setProxyVal(val);
-        form?.setValue(source, val, {
+    const handleChange = (event, newValue) => {
+        const selectedVal = newValue ? newValue.id : 0;
+        setProxyVal(selectedVal);
+        form?.setValue(source, selectedVal, {
             shouldValidate: true,
             shouldDirty: true,
         });
-        onChange(event)
+        if (onChange) {
+            onChange({ target: { value: selectedVal } })
+        }
     };
 
+    const validValueObj = treeData.find(item => item.id === (proxyVal || 0)) || null;
+
     return (
-        <FormControl fullWidth required={required}>
-            <InputLabel>{translate(label)}</InputLabel>
-            <Select
-                value={proxyVal || ''}
+        <FormControl fullWidth required={required} size="small">
+            <Autocomplete
+                value={validValueObj}
                 onChange={handleChange}
-                label={label}
-                MenuProps={{
-                    PaperProps: {
-                        style: {
-                            maxHeight: 300,
-                        },
-                    },
-                }}
+                options={treeData}
+                getOptionLabel={(option) => isTranslate && option.type === 0 ? translate(option.name) : option.name}
+                isOptionEqualToValue={(option, val) => option.id === val.id}
+                size="small"
+                ListboxProps={{ style: { maxHeight: '300px' } }}
+                renderOption={(props, option) => (
+                    <li {...props} style={{ paddingLeft: (option.depth || 0) * 16 + 16 }}>
+                        {isTranslate && option.type === 0 ? translate(option.name) : option.name}
+                    </li>
+                )}
+                renderInput={(params) => (
+                    <TextField
+                        {...params}
+                        label={translate(label)}
+                        variant="filled"
+                        required={required}
+                    />
+                )}
                 {...rest}
-            >
-                <MenuItem value={0}>
-                    &nbsp;
-                </MenuItem>
-                {treeData.map((node) => {
-                    return (
-                        <MenuItem
-                            key={node.id}
-                            value={node.id}
-                            style={{ paddingLeft: node.depth * 16 + 16 }}
-                        >
-                            {isTranslate && node.type === 0
-                                ? translate(node.name)
-                                : node.name
-                            }
-                        </MenuItem>
-                    )
-                })}
-            </Select>
+            />
         </FormControl>
     );
 };
diff --git a/rsf-admin/src/page/components/WarehouseSelect.jsx b/rsf-admin/src/page/components/WarehouseSelect.jsx
index 355898c..b09fee1 100644
--- a/rsf-admin/src/page/components/WarehouseSelect.jsx
+++ b/rsf-admin/src/page/components/WarehouseSelect.jsx
@@ -1,30 +1,14 @@
 import { useState, useEffect } from 'react';
 import {
-    useTranslate, useNotify, required
+    useTranslate, useNotify, required, AutocompleteInput
 } from 'react-admin';
-import { useController } from 'react-hook-form';
 import request from '@/utils/request';
-import { Select, MenuItem, FormControl, InputLabel } from '@mui/material';
 
 const WarehouseSelect = (props) => {
     const { dictTypeCode, label, name, validate, onChange, ...params } = props;
     const translate = useTranslate();
     const notify = useNotify();
     const [list, setList] = useState([]);
-
-    // 浣跨敤 useController 涓� react-hook-form 闆嗘垚
-    const { field, fieldState } = useController({
-        name: name,
-        rules: validate ? {
-            validate: (value) => {
-                for (const rule of validate) {
-                    const result = rule(value);
-                    if (result) return result;
-                }
-                return true;
-            }
-        } : undefined
-    });
 
     useEffect(() => {
         http();
@@ -44,36 +28,27 @@
         }
     };
 
-    const handleChange = (event) => {
-        const selectedValue = event.target.value;
-        field.onChange(selectedValue);
-        if (onChange) {
-            onChange(event);
-        }
-    };
-
-    const validValue = list.some(item => item.id === field.value) ? field.value : '';
-
     return (
-        <FormControl required fullWidth error={!!fieldState.error}>
-            <InputLabel id={`${name}-label`}>{label}</InputLabel>
-            <Select
-                labelId={`${name}-label`}
-                value={validValue}
-                variant="filled"
-                onChange={handleChange}
-                size='small'
-            >
-                {list.map((item) => (
-                    <MenuItem
-                        key={item.id}
-                        value={item.id}>
-                        {item.name}
-                    </MenuItem>
-                ))}
-            </Select>
-        </FormControl>
+        <AutocompleteInput
+            source={name}
+            label={label}
+            choices={list}
+            validate={validate}
+            onChange={(val) => {
+                if (onChange) {
+                    onChange({ target: { value: val } });
+                }
+            }}
+            options={{
+                ListboxProps: {
+                    style: { maxHeight: '200px' }
+                },
+                ...(params.options || {})
+            }}
+            fullWidth
+            {...params}
+        />
     );
 };
 
-export default WarehouseSelect;    
\ No newline at end of file
+export default WarehouseSelect;
\ No newline at end of file

--
Gitblit v1.9.1