UNPKG

sunmao-sdk

Version:

榫卯-开箱即用赋能-sdk

204 lines (188 loc) 6.09 kB
"use strict"; import React, { useState, useEffect, useRef } from "react"; import { Select, Spin } from "antd"; import { getFirstList, toStringArray } from "../../utils/commonUtils"; import { getDicTrue, getId, getName, getDisabled } from "../../utils/formUtils"; import { isEmpty, isInteger, debounce } from "lodash"; const { Option } = Select; /** * commonProps 独立配置 * showSearch : 是否可输入搜索,默认否 openSearch * requestFunc : 外部传进网络请求方法,只能接受返回数组[] ,切记 * url : 如需网络获取选择列表,需提供url * params : 网络请求参数 * * list : 默认选择列表 * key : 对象key对应字段,即返回的value * text : 对象name对应字段,即显示的name * showName : 对象name对应字段,即显示的name * specialReturn : 特殊返回函数,进行特殊处理,如不止需要返回选中 value时,可通过此方法返回,返回为数组或对象,结合antd的API,自行注意 * * * uiOptions 为antd中Select自带属性,参考antd中API * * bs:func 传值,不能被转json后 */ const displayName = "SelectCommon"; const SelectCommon = props => { const { onChange, name, value, schema: { commonProps = {} }, options: uiOptions, rootValue, ...otherProps } = props; const selectValue = toStringArray(value); const { openSearch = false, formToReq = false, // 开启搜索时,表单作为参数请求 strictSearch = true, // 严格搜索选项 inputToSelect = false, // 输入即选中 labelInValue, requestFunc, url, params, list, key = "key", text = "preName", disabledKey = "disabled", showName, defaultSelect, okPath, specialReturn } = commonProps; // 组件单独使用 与 榫卯平台配置 兼容处理 开放搜索 const showSearch = openSearch === true || getDicTrue(openSearch); // 开放搜索时,将表单数据带入请求 const formDataToReq = showSearch && (formToReq === true || getDicTrue(formToReq)); const [state, set] = useState([]); const [fetching, setFetch] = useState(false); const listString = useRef(null); useEffect(() => { if (list) setList(list); //需要网络请求 else if (url && requestFunc) { post(""); } }, []); useEffect(() => { const listToString = JSON.stringify(list); if (!isEmpty(list) && listString.current != listToString) { listString.current = listToString; setList(list); } }, [list]); const post = async data => { let reqParams; if (showSearch) { if (formDataToReq) { reqParams = { ...rootValue }; } //组装请求参数 reqParams = { ...reqParams, keyWord: data, searchKey: data, ...params }; // 支持按name搜索,不支持按key labelInValue && (reqParams[labelInValue] = data); } if (requestFunc) { setFetch(true); requestFunc(url, reqParams || params, okPath).then(req => { const list = getFirstList(req); if (!isEmpty(list)) { setList(list); } else if (data && (!strictSearch || params?.noStrictSearch)) { // 非严谨搜索则将输入当成选项 const item = { key: data, value: data }; item[key] = data; item[text] = data; setList([item]); if (inputToSelect) { // 输入即选中, 模拟选中操作 handleChange(data, { ...item, other: item, children: data }); } } setFetch(false); }); } else if (data && (!strictSearch || params?.noStrictSearch)) { // 非严谨搜索则将输入当成选项 const item = { key: data, value: data }; item[key] = data; item[text] = data; setList([item, ...list]); if (inputToSelect) { // 输入即选中, 模拟选中操作 handleChange(data, { ...item, other: item, children: data }); } } }; const setList = list => { // 只支持下拉单选 if (defaultSelect) { const value = { value: list.length ? getId(list[0], key) : null }; for (const item of list) { const keyValue = getId(item, key); if (keyValue === defaultSelect) { value.value = keyValue; value.other = item; break; } } // formRender 的 onChange 只支持单一调用,当多item同时调用,会覆盖之前操作 // 此为单一组件开放入口,不支持formRender onChange && onChange(name, value.value); specialReturn && specialReturn(value, true); } set(list); }; const handleChange = (value, other) => { let obj = null; if (labelInValue) { obj = { ...rootValue }; obj[labelInValue] = other?.children || null; // name优先级高于labelInValue obj[name] = value?.length ? value : null; } onChange && onChange(name, value?.length ? value : null, obj); //需特殊返回,则将选中对象返回,前置自行处理,可能返回空数组 if (specialReturn) { specialReturn(other); } try { showSearch && navigator.clipboard.writeText(other?.children); } catch {} }; return ( <Select style={{ width: "100%" }} value={ isInteger(selectValue) ? `${selectValue}` : selectValue ? selectValue : [] } allowClear filterOption={false} notFoundContent={fetching ? <Spin size="small" /> : null} onChange={handleChange} showSearch={showSearch} onSearch={showSearch ? debounce(post, 500) : null} placeholder={showSearch ? "请输入搜索" : "请选择"} {...uiOptions} > {!fetching && state?.map(i => ( <Option key={getId(i, key)} other={i} disabled={getDisabled(i, disabledKey)} > {showName ? showName(i) : getName(i, text) || getId(i, key)} </Option> ))} </Select> ); }; export default SelectCommon;