UNPKG

@innoways/utils

Version:

drip-form通用方法

617 lines (616 loc) 21.7 kB
/// <reference types="lodash" /> import _ from 'lodash'; /* * @Author: jiangxiaowei * @Date: 2020-05-30 15:05:13 * @Last Modified by: jiangxiaowei * @Last Modified time: 2022-07-22 13:46:08 */ import { CSSProperties, Dispatch } from "react"; declare const isEqual: (value: any, other: any) => boolean; declare const get: { <TObject extends object, TKey extends keyof TObject>(object: TObject, path: TKey | [TKey]): TObject[TKey]; <TObject_1 extends object, TKey_1 extends keyof TObject_1>(object: TObject_1 | null | undefined, path: TKey_1 | [TKey_1]): TObject_1[TKey_1] | undefined; <TObject_2 extends object, TKey_2 extends keyof TObject_2, TDefault>(object: TObject_2 | null | undefined, path: TKey_2 | [TKey_2], defaultValue: TDefault): TDefault | Exclude<TObject_2[TKey_2], undefined>; <TObject_3 extends object, TKey1 extends keyof TObject_3, TKey2 extends keyof TObject_3[TKey1]>(object: TObject_3, path: [TKey1, TKey2]): TObject_3[TKey1][TKey2]; <TObject_4 extends object, TKey1_1 extends keyof TObject_4, TKey2_1 extends keyof TObject_4[TKey1_1]>(object: TObject_4 | null | undefined, path: [TKey1_1, TKey2_1]): TObject_4[TKey1_1][TKey2_1] | undefined; <TObject_5 extends object, TKey1_2 extends keyof TObject_5, TKey2_2 extends keyof TObject_5[TKey1_2], TDefault_1>(object: TObject_5 | null | undefined, path: [TKey1_2, TKey2_2], defaultValue: TDefault_1): TDefault_1 | Exclude<TObject_5[TKey1_2][TKey2_2], undefined>; <TObject_6 extends object, TKey1_3 extends keyof TObject_6, TKey2_3 extends keyof TObject_6[TKey1_3], TKey3 extends keyof TObject_6[TKey1_3][TKey2_3]>(object: TObject_6, path: [TKey1_3, TKey2_3, TKey3]): TObject_6[TKey1_3][TKey2_3][TKey3]; <TObject_7 extends object, TKey1_4 extends keyof TObject_7, TKey2_4 extends keyof TObject_7[TKey1_4], TKey3_1 extends keyof TObject_7[TKey1_4][TKey2_4]>(object: TObject_7 | null | undefined, path: [TKey1_4, TKey2_4, TKey3_1]): TObject_7[TKey1_4][TKey2_4][TKey3_1] | undefined; <TObject_8 extends object, TKey1_5 extends keyof TObject_8, TKey2_5 extends keyof TObject_8[TKey1_5], TKey3_2 extends keyof TObject_8[TKey1_5][TKey2_5], TDefault_2>(object: TObject_8 | null | undefined, path: [TKey1_5, TKey2_5, TKey3_2], defaultValue: TDefault_2): TDefault_2 | Exclude<TObject_8[TKey1_5][TKey2_5][TKey3_2], undefined>; <TObject_9 extends object, TKey1_6 extends keyof TObject_9, TKey2_6 extends keyof TObject_9[TKey1_6], TKey3_3 extends keyof TObject_9[TKey1_6][TKey2_6], TKey4 extends keyof TObject_9[TKey1_6][TKey2_6][TKey3_3]>(object: TObject_9, path: [TKey1_6, TKey2_6, TKey3_3, TKey4]): TObject_9[TKey1_6][TKey2_6][TKey3_3][TKey4]; <TObject_10 extends object, TKey1_7 extends keyof TObject_10, TKey2_7 extends keyof TObject_10[TKey1_7], TKey3_4 extends keyof TObject_10[TKey1_7][TKey2_7], TKey4_1 extends keyof TObject_10[TKey1_7][TKey2_7][TKey3_4]>(object: TObject_10 | null | undefined, path: [TKey1_7, TKey2_7, TKey3_4, TKey4_1]): TObject_10[TKey1_7][TKey2_7][TKey3_4][TKey4_1] | undefined; <TObject_11 extends object, TKey1_8 extends keyof TObject_11, TKey2_8 extends keyof TObject_11[TKey1_8], TKey3_5 extends keyof TObject_11[TKey1_8][TKey2_8], TKey4_2 extends keyof TObject_11[TKey1_8][TKey2_8][TKey3_5], TDefault_3>(object: TObject_11 | null | undefined, path: [TKey1_8, TKey2_8, TKey3_5, TKey4_2], defaultValue: TDefault_3): TDefault_3 | Exclude<TObject_11[TKey1_8][TKey2_8][TKey3_5][TKey4_2], undefined>; <T>(object: _.NumericDictionary<T>, path: number): T; <T_1>(object: _.NumericDictionary<T_1> | null | undefined, path: number): T_1 | undefined; <T_2, TDefault_4>(object: _.NumericDictionary<T_2> | null | undefined, path: number, defaultValue: TDefault_4): T_2 | TDefault_4; <TDefault_5>(object: null | undefined, path: _.PropertyPath, defaultValue: TDefault_5): TDefault_5; (object: null | undefined, path: _.PropertyPath): undefined; (object: any, path: _.PropertyPath, defaultValue?: any): any; }; type Map = { [key: string]: any; }; type ClosestEdge = "left" | "top" | "bottom" | "right" | "over"; /** * 生成fieldkey的正则 * 根据a.0.b 返回/a.(\d+|$container).b/正则 * @param arr <Array> 需要生成正则的数组 * @returns 返回正则 */ declare const generateReg: (arr: Array<string>) => RegExp; /** * 用于删除、切换数组排序的arraykey * @param arr * @returns */ declare const generateArrayKeyReg: (arr: Array<string>) => RegExp; /** * 基本数据类型检测 * @param {unknown} checkVar 待检测的变量 * @returns {string} 基本数据类型:Object | Array | String | Number | Boolean | Null | Undefined */ declare function typeCheck(checkVar: any): string; /** * 判断变量是否为空 * @param checkVar */ declare function isEmpty(checkVar: any): boolean; /** * 设置data.a.b.c = value * 若data没有a.b 则依次赋值空对象,最后再将a.b.c设为value * @param {string} keys a.b.c * @param {object} data data.a.b.c * @param {unknown} value data.a.b.c = value * @param {object} typeMap 确定a.0.b.1中的0和1的父级应该是对象还是数组形式 * @param parentKey */ declare const setDeepProp: (keys: string[], data: Map, value: unknown, typeMap?: Map | undefined, parentKey?: string[] | undefined) => void; /** * 删除data.a.b.c * 若data没有a.b.c,则不进行任何操作 * @param {string} keys [a,b,c] * @param {object} data 需要删除的对象 */ declare const deleteDeepProp: (keys: string[], data: Map) => void; /** * 判断对象是否有某一属性,如没有,则根据valueType为其创建 * 并返回最后一个key的校验生成后的value * @param {Map} source 源对象 * @param {'array' | 'object'} valueType 创建的类型 * @param {array} keys 对象的key值,支持...以拓展深层对象的创建 */ declare const judgeAndRegister: (source: Map, valueType: "array" | "object", ...keys: any[]) => Map; /** * 允许循环引用的深拷贝 * @param target * @param map */ declare function deepClone(target: any, map?: WeakMap<object, any>): any; /** * 该方法用于快速向check的shcmea中注入vcontol。方便过滤已经设置的表单 * @param obj 待注入vontrol的uiSchema对象 */ declare function injectVcontrol(obj: Record<string, unknown>): void; /** * 解析url中?后的参数,返回参数Map * @param url */ declare function parseHrefParam(url: string | undefined): Map; declare function randomString(length: number): string; declare function number2Chinese(num: number): string; // TODO 更新Read more文档 declare function upgradeTips(oldApiName: string, newApiName: string): void; // 转换数组 declare function toArray(param: string | Array<string>): Array<string>; // 处理容器宽度 declare const handleMargin: (style: CSSProperties) => void; /** * 根据uiSchema,获取当前schem相对的主题和组件类型 * @param uiSchema * @returns */ declare const getThemeAndType: (uiSchema: { type: string; theme?: string; } & Map) => string; declare function isValidHttpUrl(string: string): boolean; declare function removeSpaceAndmakeStringCamelCase(string: string): string; /** * 将二进制流数据转成base64格式的数据 * * @param file */ declare function binaryData2Blob(file: File): Promise<string | ArrayBuffer | null>; /** * 将base64g格式的图片地址转成img图片对象 * * @param {string} imgBase64Url */ declare function getImgEl(imgBase64Url: string): Promise<HTMLImageElement>; // 尺寸限制 type ImgDimension = Partial<{ width: number; height: number; minWidth: number; minHeight: number; maxWidth: number; maxHeight: number; widthDivisor: number; heightDivisor: number; widthHeightEqual: boolean; }>; // 大小限制 type ImgSize = Partial<{ max: number; min: number; }>; declare function checkImg({ file, dimension, size, accept, errMsg }: { file: File; dimension?: ImgDimension; size?: ImgSize; accept?: string; errMsg?: Partial<{ dimension: string; size: string; type: string; }>; }): Promise<{ isOk: boolean; errors: Array<string>; }>; // nubmer 类型支持的操作符 type NumberOperator = ">=" | "<=" | "<" | ">" | "===" | "!=="; // string 类型支持的操作符 type StringOperator = "===" | "!==" | "includes" | "-includes"; // boolean 类型支持的操作符 type BooleanOperator = "true" | "false"; // object 类型支持的操作符 type ObjectOperator = "in" | "-in"; // array 类型支持的操作符 type ArrayOperator = "includes" | "-includes"; type Operator = NumberOperator | StringOperator | BooleanOperator | ObjectOperator | ArrayOperator | "change" | ""; // 条件逻辑配置字段 type Condintion = { /** * 格式:"fieldKey setType property" "fieldKey setType" * fieldkey: 需要获取的表单的fieldkey * setType: data|uiSchema|dataSchema * property: 可选 获取属性 */ fieldKey1: string; // 空字符用来初始化逻辑,新增条件时,value1未选择,操作符不应该展示 operator: Operator; // "fieldKey setType property" "fieldKey setType" fieldKey2?: string; value2?: unknown; logicOperator?: "&&" | "||"; }; type SetEffect = { type: "set" | "merge"; /** * 格式:"fieldKey setType property" "fieldKey setType" * fieldkey: 需要获取的表单的fieldkey * setType: data|uiSchema|dataSchema * property: 可选 获取属性 */ fieldKey: string; // 如果fieldkey 格式为fieldKey uiSchema vcontrol,则value为boolean类型 value: unknown; }; type SubAction = { type: "subAction"; actions: Array<Action>; }; type Effect = Array<SetEffect | SubAction>; // if else 逻辑 type ControlFlowAction = { type: "controlFlow"; condintion: Array<Condintion>; effect: Effect; }; // type Action = ControlFlowAction; type Flow = { // 版本号 一期默认为0.1.0 version: string; trigger: { event: "globalChange"; }; actions: Array<Action>; }; type Get = { (fieldKey?: string): { data: Map | undefined; dataSchema: DataSchema; uiSchema: UiSchema; }; (fieldKey: string, option: { isPrev: boolean; }): { data: Map | undefined; dataSchema: DataSchema | undefined; uiSchema: UiSchema | undefined; }; }; type GetKey = (fieldKey: string, type: "uiSchema" | "dataSchema" | "data" | "unitedSchema") => string; type GetTypeKey = (fieldKey: string) => string | never; type State = { typePath: Record<string, { type: string; unitedSchemaKey: string; fatherKey: string; }>; uiSchema: UiSchema; dataSchema: DataSchema; // 表单数据 formData: Record<string, any>; errors: Record<string, string>; // ajv校验错误信息 ajvErrors: Record<string, string>; // 用户自定义错误信息 customErrors: Record<string, string>; // 是否正在校验 checking: boolean; // 当前可见的表单 visibleFieldKey: Array<string>; // 当前正在变动的表单 changeKey: string; // 数组容器对应的react key映射 arrayKey: Record<string, Array<string>>; // 异步校验需要保留的错误key(用于防止异步校验的错误信息被ajv覆盖) ignoreErrKey: Array<string>; }; // 即将废弃,请改用 ResetAction type ReloadAction = { type: "reload"; } & Omit<State, "visibleFieldKey">; type ResetAction = { type: "reset"; action: { state: Omit<State, "visibleFieldKey">; }; }; // 即将废弃,请改用 SetValidate type SetDataSchemaAction = { type: "setDataSchema"; dataSchema?: DataSchema; isDelete?: boolean; } & Map; type SetValidate = { type: "setValidate"; action: { deleteKeys?: Array<string> | string; dataSchema?: DataSchema; set?: Map; }; }; // 即将废弃,请改用 SetUiAction type SetUiSchemaAction = { type: "setUiSchema"; uiSchema?: UiSchema; } & Map; // 即将废弃,请改用 SetUiAction type DeleteUiSchemaAction = { type: "deleteUiSchema"; key: string; }; type SetUiAction = { type: "setUi"; action: { deleteKeys?: Array<string> | string; uiSchema?: UiSchema; set?: Map; }; }; // 即将废弃,请改用 SetDataAction type SetFormDataAction = { type: "setFormData"; formData?: Map; } & Map; // 即将废弃 改用 SetDataAction type DeleteFormDataAction = { type: "deleteFormData"; key: string; }; type SetDataAction = { type: "setData"; action: { deleteKeys?: string | Array<string>; formData?: Map; set?: Map; }; }; type DeleteFieldAction = { type: "deleteField"; action: { fieldKey: string; get: Get; getKey: GetKey; getTypeKey: GetTypeKey; }; }; type AddFieldAction = { type: "addField"; action: { fieldKey: string; closestEdge: ClosestEdge; unitedSchema: UnitedSchema; overFieldKey: string; get: Get; getKey: GetKey; getTypeKey: GetTypeKey; shouldDelete: boolean; }; }; // 即将废弃 type SetErrType = { type: "setError"; action?: { ignore?: Array<string>; }; } & Record<string, string>; // 即将废弃 type SetErrsType = { type: "setError"; ignore?: Array<string>; errors?: Record<string, string>; }; // 即将废弃 请改用 SetErrAction type SetErrorAction = SetErrType | SetErrsType; // 即将废弃 请改用 SetErrAction type DeleteErrorAction = { type: "deleteError"; key: Array<string> | string; }; // 设置自定义错误信息 type SetErrAction = { type: "setErr"; action: { deleteKeys?: Array<string> | string; errors?: Record<string, string>; set?: Record<string, string>; }; }; // 设置ajv错误 type SetAjvErrorAction = { type: "setAjvErr"; action: { deleteKeys?: Array<string> | string; errors?: Record<string, string>; set?: Record<string, string>; }; }; // 即将废弃 type OldSetCheckingAction = { type: "setChecking"; checking: boolean; }; type NewSetCheckingAction = { type: "setChecking"; action: { checking: boolean; }; }; type SetCheckingAction = OldSetCheckingAction | NewSetCheckingAction; type SetVisibleKeyAction = { type: "setVisibleKey"; action: { deleteKeys?: Array<string> | string; fieldKey?: Array<string> | string; }; }; // 数组容器设置映射的组件唯一key(避免删除导致的组件渲染问题) type SetArrayKey = { type: "setArrayKey"; action: { // 数组父级fieldKey fieldKey: string; // 添加或删除的位置 (order为undefiedn,则全量设置当前fieldKey的key) order?: number; // 是否删除 默认添加 isDelete?: boolean; // 切换数组的顺序 move?: [ number, number ]; }; }; type Action$0 = ReloadAction | ResetAction | SetDataSchemaAction | SetValidate | SetUiSchemaAction | DeleteUiSchemaAction | SetUiAction | SetFormDataAction | DeleteFormDataAction | SetDataAction | DeleteFieldAction | AddFieldAction | SetErrorAction | SetErrAction | SetAjvErrorAction | DeleteErrorAction | SetCheckingAction | SetVisibleKeyAction | SetArrayKey; /** * 在联合Schema中,某个节点的类型 */ type FieldAtomType = { fieldKey?: string | number; } & Map; type ContainerStyle = Partial<{ // 表单宽度 width: number | string; // 容器margin-top marginTop: number | string; // 容器margin-right marginRight: number | string; // 容器margin-bottom marginBottom: number | string; // 容器margin-left marginLeft: number | string; // 容器margin margin: string; // 容器padding padding: string; paddingTop: number | string; paddingBottom: number | string; paddingRigth: number | string; paddingLeft: number | string; }> | null; type DescriptionItem = { type: "icon"; title: string; trigger?: "click" | "hover"; } | { type: "text"; title: string; } | null; type Description = DescriptionItem | Array<DescriptionItem>; type TitlePlacement = "left" | "right" | "bottom" | "top"; type Theme = "antd" | "babel-ui" | "drip-design" | string; type TitleUi = Partial<{ // 标题宽度 width: number | string; // 标题margin-top marginTop: number | string; // 标题margin-right marginRight: number | string; // 标题margin-bottom marginBottom: number | string; // 标题margin-left marginLeft: number | string; // 标题margin margin: string; // Title vertical alignment verticalAlign: "center" | "top" | "bottom"; // Title horizontal alignment textAlign: "left" | "right" | "center"; // 是否展示必填*号 requiredIcon: boolean; placement: TitlePlacement; color: string; fontSize: number | string; showColon?: boolean; }> | null; type Properties = { [propName: string]: { type: string; title?: TitleUi; showTitle?: boolean; containerStyle?: ContainerStyle; theme?: Theme; description?: Description; [propName: string]: unknown; }; }; /** * @param {string} fieldKey 必填 表单change触发,更改formData的key值 * @param {function} onChange 可选 表单触发change事件后的回调 * @param {object} options 可选 表单字段特殊处理配置。注意:options中只能有一个字段的值是true。否则不会对特殊数据进行格式化 * @param {func} dispatch 操作context */ type OnChange = (({ val, dispatch, fieldKey, getKey, prevFieldData, // 注意目前只有select表单支持这个字段(看后续是否有场景其它表单也需要) fieldData }: { val: any; dispatch: Dispatch<Action$0>; getKey: GetKey; fieldKey: string; prevFieldData: any; // 注意目前只有select表单支持这个字段(看后续是否有场景其它表单也需要) fieldData: any; }) => void) | string; /** * UiSchema的最小原子 */ type UiSchema = { formMode?: "edit" | "view" | "generator"; mode: "add" | "normal" | "collapse" | "tuple" | "fixed"; theme: Theme; type: string; containerStyle?: ContainerStyle; properties: Properties; order: Array<string | number>; title?: TitleUi; onChange?: OnChange; flow?: Flow; footer?: { url?: string; method?: "GET" | "POST"; token?: string; fetchData?: boolean; jsonkey?: string; apiJson?: string; [propName: string]: unknown; }; [propName: string]: unknown; }; /** * DataSchema的最小原子 */ type DataSchema = { type: string; validateTime: "submit" | "change"; showError: "change" | "submit" | "none"; requiredMode: "default" | "empty"; properties?: Map; items?: Array<Map> | Map; required?: Array<string | number>; errorMessage?: { required: Map; properties?: Map; items?: Map; [propName: string]: unknown; }; } & Map; /** * 联合Schema格式 */ type UnitedSchema = { theme?: "antd" | "babel-ui" | "drip-design" | string; themeColor?: string; validateTime?: "change" | "submit"; showError?: "change" | "submit" | "none"; requiredMode?: "default" | "empty"; title?: string; ui?: Map; schema?: Array<Map>; items?: Array<Map> | Map; } & Map; type TypePathItem = { type: string; fatherKey: string; title: string; unitedSchemaKey: string; }; type TypePath = Record<string, TypePathItem>; /** * 解析联合Schema * @param unitedSchema */ declare const parseUnitedSchema: (unitedSchema: UnitedSchema) => { uiSchema: UiSchema; dataSchema: DataSchema; typePath: TypePath; customProps: string[]; }; type Options = Partial<{ // 是否开启$fieldKey值转换为fieldKey(默认不开启,generator中viewport区域需要开启) $fieldKey: boolean; }>; /** * 融合dataSchema和uiSchema为联合Schema */ declare function combine(dataSchema: DataSchema, uiSchema: UiSchema, options?: Options): UnitedSchema; declare const parseFlow: (flow: Flow) => string; type FetchApi = (args: { params: Array<{ key: string; value: string; }>; url: string; method: "GET" | "POST"; }) => Promise<unknown>; type GetApi<R> = (args: { params: Map; url: string; }) => Promise<R>; type PostApi<R> = (args: { params: Map; url: string; }) => Promise<R>; declare const fetchFn: FetchApi; declare const fetchFnJsonKey: ({ config, dataHandler, dataSetter, doFinally }: { config: any; dataHandler?: Function | null | undefined; dataSetter?: Function | null | undefined; doFinally?: Function | null | undefined; }) => Promise<void>; export { isEqual, get, generateReg, generateArrayKeyReg, typeCheck, isEmpty, setDeepProp, deleteDeepProp, judgeAndRegister, deepClone, injectVcontrol, parseHrefParam, randomString, number2Chinese, upgradeTips, toArray, handleMargin, getThemeAndType, isValidHttpUrl, removeSpaceAndmakeStringCamelCase, Map, ClosestEdge, binaryData2Blob, getImgEl, ImgDimension, ImgSize, checkImg, parseUnitedSchema, combine, FieldAtomType, ContainerStyle, Description, TitlePlacement, Theme, TitleUi, OnChange, UiSchema, DataSchema, UnitedSchema, TypePathItem, TypePath, Get, GetKey, GetTypeKey, State, SetErrType, SetErrsType, Action$0 as Action, parseFlow, Operator, Condintion, SetEffect, ControlFlowAction, Flow, fetchFn, fetchFnJsonKey, FetchApi, GetApi, PostApi };