SelectInput.jsx 8.55 KB
import React, { useState, useRef, useEffect, useCallback } from "react";
import { Input, Popup, Button, Toast, PickerView, SearchBar, Checkbox } from "antd-mobile";
import { DownOutline } from "antd-mobile-icons";
import commonConfig from "@/utils/config";
import * as commonServices from "@/services/services";
import * as commonFunc from "@/components/Common/commonFunc";
import * as commonUtils from "@/utils/utils";
import styles from "./selectInput.less";
import debounce from "lodash/debounce";

const SelectInput = props => {
  const [value, setValue] = useState(props.sValue || ""); // 如果存在 name 属性,将其值赋值给 value
  const [values, setValues] = useState("");
  const [searchValue, setSearchValue] = useState("");
  const [visible, setVisible] = useState(false);
  const { sId } = props.itemDetail || {};
  const { downIndex, tableName, viewRow, itemDetail, sModelsId, sValue, name, id, No, quotationData, showDropDown } = props || {};
  const { masterData } = props.state;
  const [bCanInput, setBCanInput] = useState(props.bCanInput);
  const { bReadonly } = itemDetail || {};
  const [propsType, setPropsType] = useState("");
  useEffect(() => {
    if (!itemDetail) return;
    const type = itemDetail.sName.charAt(0);
    setPropsType(type);
    const viewRowNew = itemDetail.sName ? viewRow?.[itemDetail.sName] : "";
    if (itemDetail.sDropDownType === "const") {
      return;
    }
    if (tableName.includes("slaveDown")) {
      if (!viewRow.sBackProcessData) return;
      // const data = viewRow.sBackProcessData[downIndex][itemDetail.sName];
      // setValue(data);
    } else if (tableName.includes("sBackendParams")) {
      const data = props.sBackProcessData.find(item => item[props.sParentFieldsName]).sBackendParams.find(item => item.sParam === itemDetail.sParam);
      if (data) {
        const values = data.label ? data.label : data.value;
        setValue(values || "");
      }
    } else {
      setValue(viewRowNew || ""); // 动态更新 value
    }
    // 处理默认数据
    console.log("🚀 ~ useEffect ~ itemDetail:", itemDetail)
    
  }, [itemDetail, itemDetail?.sName, viewRow]);
  const [columns, setColumns] = useState([]);
  const [coplyColumns, setCopyColumns] = useState(columns);
  const getSqlDropDownData = async (searchValue, sSqlCondition) => {
    const url = `${commonConfig.server_host}business/getSelectLimit/${sId}?sModelsId=${sModelsId}&sName=${""}`;
    const body = {
      sSqlCondition: sSqlCondition,
      sKeyUpFilterName: searchValue,
      pageNum: 1,
      pageSize: 20,
    };
    commonServices.postValueService(props.app.token, body, url).then(res => {
      if (res.data.code === 1 && res.data.dataset) {
        const list = res.data.dataset.rows?.map((item, i) => ({
          label: item.sCustomerName || item.sName || item.sProcessName || item.sColorName || item.sMaterialsName,
          value: item.sId || item.sSlaveId,
          ...item,
        }));
        setColumns(list);
        setCopyColumns(res.data.dataset.rows);
      }
    });
  };
  const handleConfirm = () => {
    if (!values[0]) {
      setVisible(false);
      return;
    }
    // 判断是否是
    const index = columns.findIndex(item => item.value === values[0]);
    const data = coplyColumns[index];
    data[itemDetail.sName] = data[itemDetail.sName] ? data[itemDetail.sName] : data.label || data.sName || data.sProcessName || data.sColorName;
    setValue(columns[index]?.label || "");
    props.onDataChange(tableName, itemDetail.sName, data, data.sId, coplyColumns);
    setVisible(false);
  };

  const handleCancel = () => {
    setVisible(false);
  };

  const searchData = async val => {
    if (val === "" || val === null || val === undefined) {
      setSearchValue("");
    } else {
      setSearchValue(val);
    }
    getSqlDropDownData(val);
  };
  // 处理选择器变化
  const debouncedChangeOption = useCallback(
    debounce(val => {
      setValues(val);
    }, 300), // 防抖时间设置为 300ms
    [columns]
  );

  const changeOption = val => {
    debouncedChangeOption(val);
  };
  useEffect(() => {
    if (!visible) return;
    let { sDropDownType, sVisColumnName } = itemDetail;
    if (sVisColumnName && sVisColumnName === "sProcessName") {
      if (sDropDownType === "sql") {
        if (itemDetail.sParamDropDown) {
          const { sParamDropDown = "", sName0, sName } = itemDetail;
          const dropDownData = sParamDropDown.split(",");
          if (dropDownData?.length) {
            const list = {
              dropDownData: dropDownData.map(item => ({
                sId: commonUtils.createSid(),
                value: commonUtils.createSid(),
                sParam: itemDetail.sParam,
                [sName]: item,
                sParamKey: sName0,
                sParamKeyNew: sName,
                label: item,
              })),
              totalPageCount: 1,
              currentPageNo: 1,
              conditonValues: {},
            };
            setColumns(list.dropDownData);
            setCopyColumns(list.dropDownData);
          }
        } else {
          const list = JSON.parse(itemDetail.sChineseDropDown).map(x => {
            return {
              label: x.sProcessName,
              value: x.sId,
              ...x,
            };
          });
          setColumns(list);
          setCopyColumns(list);
        }

        // getSqlDropDownData(searchValue);
      } else if ((sDropDownType = "const")) {
        if (!itemDetail.showDropDown) return;
        const list = Object.entries(JSON.parse(itemDetail.showDropDown)).map(([key, value]) => ({
          label: value,
          value: key,
        }));
        setColumns(list);
        setCopyColumns(list);
      }
    } else {
      if (sDropDownType === "sql") {
        const { sSqlCondition } = itemDetail;
        
        if (sSqlCondition) {
          const { viewRow } = props;
          const keys = sSqlCondition.split(",").map(sSqlCondition => sSqlCondition.split(".")[1]);

          // 构造 JSON 对象
          const result = keys.reduce((acc, key) => {
            acc[key] = viewRow[key];
            return acc;
          }, {});
          getSqlDropDownData(searchValue, result);
        } else {
          getSqlDropDownData(searchValue);
        }
      } else if ((sDropDownType = "const")) {
        if (!itemDetail.showDropDown) return;
        const list = Object.entries(JSON.parse(itemDetail.showDropDown)).map(([key, value]) => ({
          label: value,
          value: key,
        }));
        setColumns(list);
        setCopyColumns(list);
      }
    }
  }, [visible]);
  useCallback;
  useEffect(() => {
    if (!sValue) return;
    setValue(sValue);
  }, [sValue]);
  useCallback;

  const clickBtn = () => {
    setVisible(true);
  };
  return (
    <div>
      <div className={styles.inputBox}>
        {propsType === "b" ? (
          <Checkbox
            style={{ height: "3.125rem" }}
            onChange={val => {
              props.onDataChange(tableName, itemDetail.sName, { [itemDetail.sName]: val, label: val }, null, coplyColumns);
            }}
          />
        ) : (
          <div>
            {" "}
            <Input
              placeholder=""
              value={value}
              onChange={val => {
                setValue(val);
                props.onDataChange(tableName, itemDetail.sName, { [itemDetail.sName]: val }, null, coplyColumns);
              }}
              onClick={() => {
                if (!props.onCostomClick) return;
                props.onCostomClick(itemDetail);
              }}
              readOnly={bReadonly}
            />
            {itemDetail.sDropDownType === "sql" || itemDetail.sDropDownType === "const" ? (
              <div className={styles.icons} onClick={clickBtn}>
                <DownOutline />
              </div>
            ) : null}
          </div>
        )}
      </div>
      <Popup visible={visible} onMaskClick={() => setVisible(false)} onClose={() => setVisible(false)} bodyStyle={{ height: "50vh" }}>
        <div className={styles.popupHeader}>
          <Button onClick={handleCancel} color="primary" fill="none">
            取消
          </Button>
          <Button onClick={handleConfirm} color="primary" fill="none">
            确认
          </Button>
        </div>
        <div style={{ padding: "0 1.5rem", marginTop: "1rem" }}>
          <SearchBar placeholder="请输入内容" showCancelButton value={searchValue} onChange={val => searchData(val)} />
        </div>
        <PickerView columns={[columns]} value={values} onChange={changeOption} style={{ "--height": "200px", "--item-height": "2.8rem" }} />
      </Popup>
    </div>
  );
};

export default SelectInput;