127 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
| import { DownOutlined, UpOutlined } from "@ant-design/icons";
 | |
| import { Button, Col, Form, Row } from "antd";
 | |
| import { useEffect, useRef, useState } from "react";
 | |
| import FormItemsRenderer from "../FormBuilder/FormItemsRenderer";
 | |
| 
 | |
| /**
 | |
|  * 搜索表单组件
 | |
|  */
 | |
| const Search = (props) => {
 | |
|   const {
 | |
|     labelCol = { span: 6 },
 | |
|     options = [],
 | |
|     values,
 | |
|     onFinish,
 | |
|     onSubmit,
 | |
|     onReset,
 | |
|     searchText = "搜索",
 | |
|     resetText = "重置",
 | |
|     showSearchButton = true,
 | |
|     showResetButton = true,
 | |
|     extraButtons,
 | |
|     form,
 | |
|     ...restProps
 | |
|   } = props;
 | |
| 
 | |
|   const [collapse, setCollapse] = useState(true);
 | |
|   const [span, setSpan] = useState(6);
 | |
|   const [showCollapseButton, setShowCollapseButton] = useState(false);
 | |
|   const classNameRef = useRef(`search-${Date.now()}`);
 | |
| 
 | |
|   // 计算是否需要显示展开/收起按钮
 | |
|   useEffect(() => {
 | |
|     if (!options || options.length === 0)
 | |
|       return;
 | |
| 
 | |
|     const calculateLayout = () => {
 | |
|       const colEl = document.querySelectorAll(
 | |
|         `.${classNameRef.current}>.${window.process.env.app.antd["ant-prefix"]}-col`,
 | |
|       );
 | |
|       const colElLength = colEl.length;
 | |
|       const excludeLast = colElLength - (extraButtons ? 2 : 1);
 | |
| 
 | |
|       const spanMap = { 0: 24, 1: 18, 2: 12, 3: 6 };
 | |
|       setSpan(spanMap[excludeLast % 4] || 6);
 | |
| 
 | |
|       setShowCollapseButton(excludeLast > 3);
 | |
|     };
 | |
| 
 | |
|     // 延迟执行以确保 DOM 已渲染
 | |
|     setTimeout(calculateLayout, 0);
 | |
|   }, [options, extraButtons]);
 | |
| 
 | |
|   // 处理表单提交
 | |
|   const handleSubmit = () => {
 | |
|     const values = form.getFieldsValue();
 | |
|     onFinish?.(values, "submit");
 | |
|     onSubmit?.(values);
 | |
|   };
 | |
| 
 | |
|   // 处理重置
 | |
|   const handleReset = () => {
 | |
|     form.resetFields();
 | |
|     const values = form.getFieldsValue();
 | |
|     onFinish?.(values, "reset");
 | |
|     onReset?.(values);
 | |
|   };
 | |
| 
 | |
|   // 切换展开/收起
 | |
|   const toggleCollapse = () => {
 | |
|     setCollapse(!collapse);
 | |
|   };
 | |
| 
 | |
|   return (
 | |
|     <Form
 | |
|       form={form}
 | |
|       labelCol={labelCol}
 | |
|       initialValues={values}
 | |
|       {...restProps}
 | |
|     >
 | |
|       <Row className={classNameRef.current}>
 | |
|         <FormItemsRenderer
 | |
|           options={options}
 | |
|           labelCol={labelCol}
 | |
|           span={6}
 | |
|           collapse={collapse}
 | |
|           useAutoGenerateRequired={false}
 | |
|         />
 | |
|         <Col span={showCollapseButton ? (collapse ? 6 : span) : span}>
 | |
|           <Form.Item label=" " colon={false} style={{ textAlign: "right" }}>
 | |
|             {showSearchButton && (
 | |
|               <Button type="primary" onClick={handleSubmit}>
 | |
|                 {searchText}
 | |
|               </Button>
 | |
|             )}
 | |
|             {showResetButton && (
 | |
|               <Button style={{ marginLeft: 8 }} onClick={handleReset}>
 | |
|                 {resetText}
 | |
|               </Button>
 | |
|             )}
 | |
|             {showCollapseButton && (
 | |
|               <Button
 | |
|                 type="link"
 | |
|                 icon={collapse ? <DownOutlined /> : <UpOutlined />}
 | |
|                 onClick={toggleCollapse}
 | |
|                 style={{ marginLeft: 8 }}
 | |
|               >
 | |
|                 {collapse ? "展开" : "收起"}
 | |
|               </Button>
 | |
|             )}
 | |
|           </Form.Item>
 | |
|         </Col>
 | |
|         {extraButtons && (
 | |
|           <Col span={24}>
 | |
|             <Form.Item label=" " colon={false} labelCol={{ span: 0 }}>
 | |
|               {extraButtons}
 | |
|             </Form.Item>
 | |
|           </Col>
 | |
|         )}
 | |
|       </Row>
 | |
|     </Form>
 | |
|   );
 | |
| };
 | |
| 
 | |
| Search.displayName = "Search";
 | |
| 
 | |
| export default Search;
 |