@innoways/utils
Version:
drip-form通用方法
648 lines (647 loc) • 22.5 kB
TypeScript
/// <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, breakPoint: number, screenSize: number) => 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 & Record<string, any>;
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;
formValueApiURLDomain?: 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";
headers?: Record<string, string>;
}) => Promise<unknown>;
type GetApi<R> = (args: {
params: Map;
url: string;
headers?: Record<string, string>;
}) => Promise<R>;
type PostApi<R> = (args: {
params: Map;
url: string;
headers?: Record<string, string>;
}) => Promise<R>;
type formValuePayloadType = {
form_id: string;
version_id: string;
extension: {
[key: string]: any;
};
form_data: {
[key: string]: any;
};
};
type getFormValueByType = {
id?: string;
form_id?: string;
extension?: {
[key: string]: any;
};
};
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>;
declare const fetchFormValue: (config: {
url: string;
token: string;
getFormValueBy: getFormValueByType;
}) => Promise<any>;
declare const addFormValue: (config: {
url: string;
token: string;
formValuePayload: formValuePayloadType;
}) => Promise<any>;
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, fetchFormValue, addFormValue, FetchApi, GetApi, PostApi, formValuePayloadType, getFormValueByType };