130 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			3.5 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";
 | 
						|
import ResetIcon from "../Icon/ResetIcon";
 | 
						|
import SearchIcon from "../Icon/SearchIcon";
 | 
						|
 | 
						|
/**
 | 
						|
 * 搜索表单组件
 | 
						|
 */
 | 
						|
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}
 | 
						|
          initialValues={values}
 | 
						|
        />
 | 
						|
        <Col span={showCollapseButton ? (collapse ? 6 : span) : span}>
 | 
						|
          <Form.Item label=" " labelCol={{ span: 2 }} colon={false} style={{ textAlign: "right" }}>
 | 
						|
            {showSearchButton && (
 | 
						|
              <Button type="primary" icon={<SearchIcon />} onClick={handleSubmit}>
 | 
						|
                {searchText}
 | 
						|
              </Button>
 | 
						|
            )}
 | 
						|
            {showResetButton && (
 | 
						|
              <Button style={{ marginLeft: 8 }} icon={<ResetIcon />} 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;
 |