linkmore-design
Version:
🌈 🚀lm组件库。🚀
636 lines (621 loc) • 21.1 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _ahooks = require("ahooks");
var _intersectionBy = _interopRequireDefault(require("lodash/intersectionBy"));
var _omit = _interopRequireDefault(require("lodash/omit"));
var _pick = _interopRequireDefault(require("lodash/pick"));
var _uniqBy = _interopRequireDefault(require("lodash/uniqBy"));
var _react = _interopRequireWildcard(require("react"));
var _button = _interopRequireDefault(require("../../../button"));
var _form = _interopRequireDefault(require("../../../form"));
var _iconFont = _interopRequireDefault(require("../../../icon-font"));
var _select = _interopRequireDefault(require("../../../select"));
var _constants = require("../../constants");
var _controls = _interopRequireDefault(require("../../controls"));
var _utils = require("../../utils");
var _DynamicComponent = _interopRequireDefault(require("./DynamicComponent"));
/** 头部区域 */
const ComplexHeader = ({
locale
}) => {
return /*#__PURE__*/_react.default.createElement("div", {
className: "complex_header"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "header_title"
}, locale.complex), /*#__PURE__*/_react.default.createElement("div", {
className: "header_condition_group"
}, /*#__PURE__*/_react.default.createElement("span", null, locale.accordWith), /*#__PURE__*/_react.default.createElement("div", {
className: "condition_select"
}, /*#__PURE__*/_react.default.createElement(_form.default.Item, {
name: [_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.RELATION],
noStyle: true
}, /*#__PURE__*/_react.default.createElement(_select.default, {
options: [{
label: locale.and,
value: 'and'
}, {
label: locale.or,
value: 'or'
}]
}))), /*#__PURE__*/_react.default.createElement("span", null, locale.condition)));
};
/** 手动调用获取
* 'contains'/'in'仅存在其一, key用于唯一值
* 结果取交集, 以组件类型获取的操作符为主
*/
const getOperatorOption = ({
type,
fieldType,
locale
}) => {
// 根据组件类型获取操作符
const actionByType = typeParam => {
if (['input'].includes(typeParam)) {
return [{
label: locale.equal,
value: 'equal'
}, {
label: locale.notEqual,
value: 'not_equal'
}, {
label: locale.startsWith,
value: 'starts_with'
}, {
label: locale.endsWith,
value: 'ends_with'
}, {
key: 'in',
label: locale.contains,
value: 'contains'
}, {
key: 'not_in',
label: locale.notContains,
value: 'not_contains'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
if (['select', 'checkbox', 'cascader'].includes(typeParam)) {
return [{
label: locale.equal,
value: 'equal'
}, {
label: locale.notEqual,
value: 'not_equal'
}, {
label: locale.contains,
value: 'in'
}, {
label: locale.notContains,
value: 'not_in'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
if (['date', 'datetime', 'range', 'dateRange'].includes(typeParam)) {
return [{
label: locale.equal,
value: 'equal'
}, {
label: locale.notEqual,
value: 'not_equal'
}, {
label: locale.lessThan,
value: 'less_than_or_equal'
}, {
label: locale.greaterThan,
value: 'greater_than_or_equal'
}, {
label: locale.between,
value: 'between'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
if (['number', 'numberRange'].includes(typeParam)) {
return [{
label: '=',
value: 'equal'
}, {
label: '≠',
value: 'not_equal'
}, {
label: '>',
value: 'greater_than'
}, {
label: '≧',
value: 'greater_than_or_equal'
}, {
label: '<',
value: 'less_than'
}, {
label: '≦',
value: 'less_than_or_equal'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
return [];
};
// 根据字段类型获取操作符
const actionByFieldType = param => {
if (['string'].includes(param)) {
return [{
label: locale.equal,
value: 'equal'
}, {
label: locale.notEqual,
value: 'not_equal'
}, {
label: locale.startsWith,
value: 'starts_with'
}, {
label: locale.endsWith,
value: 'ends_with'
}, {
key: 'in',
label: locale.contains,
value: 'contains'
}, {
key: 'not_in',
label: locale.notContains,
value: 'not_contains'
}, {
label: locale.between,
value: 'between'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
if (['integer', 'double'].includes(param)) {
return [{
label: '=',
value: 'equal'
}, {
label: '≠',
value: 'not_equal'
}, {
label: '>',
value: 'greater_than'
}, {
label: '≧',
value: 'greater_than_or_equal'
}, {
label: '<',
value: 'less_than'
}, {
label: '≦',
value: 'less_than_or_equal'
}, {
label: locale.contains,
value: 'in'
}, {
label: locale.notContains,
value: 'not_in'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
if (['guid'].includes(param)) {
return [{
label: locale.equal,
value: 'equal'
}, {
label: locale.notEqual,
value: 'not_equal'
}, {
label: locale.contains,
value: 'in'
}, {
label: locale.notContains,
value: 'not_in'
}, {
label: locale.between,
value: 'between'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
if (['date', 'datetime'].includes(param)) {
return [{
label: locale.equal,
value: 'equal'
}, {
label: locale.notEqual,
value: 'not_equal'
}, {
label: locale.lessThan,
value: 'less_than_or_equal'
}, {
label: locale.greaterThan,
value: 'greater_than_or_equal'
}, {
label: locale.between,
value: 'between'
}, {
label: locale.contains,
value: 'in'
}, {
label: locale.notContains,
value: 'not_in'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
if (['boolean'].includes(param)) {
return [{
label: locale.equal,
value: 'equal'
}, {
label: locale.notEqual,
value: 'not_equal'
}, {
label: locale.contains,
value: 'in'
}, {
label: locale.notContains,
value: 'not_in'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
if (['json'].includes(param)) {
return [{
label: locale.equal,
value: 'equal'
}, {
label: locale.notEqual,
value: 'not_equal'
}, {
label: locale.contains,
value: 'in'
}, {
label: locale.notContains,
value: 'not_in'
}, {
label: locale.empty,
value: 'empty'
}, {
label: locale.notEmpty,
value: 'not_empty'
}];
}
return [];
};
const typeOptions = actionByType(type).map(item => ({
...item,
key: item.key || item.value
}));
const fieldOptions = actionByFieldType(fieldType).map(item => ({
...item,
key: item.key || item.value
}));
return (0, _intersectionBy.default)(typeOptions, fieldOptions, 'key');
};
/** 强依赖form获取, 仅在form组件内使用 */
const useOperatorOptions = ({
name,
locale
}) => {
const type = _form.default.useWatch([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name, 'type']);
const fieldType = _form.default.useWatch([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name, 'fieldType']);
return (0, _react.useMemo)(() => getOperatorOption({
type,
fieldType,
locale
}), [type, fieldType]);
};
/** 表单 fieldName 字段项 */
const FieldItem = ({
name,
options
}) => {
const form = _form.default.useFormInstance();
const fieldNames = {
label: 'title',
value: _constants.DYNAMIC_ENUM.FIELD_NAME,
fieldType: _constants.DYNAMIC_ENUM.FIELD_TYPE
};
/** 前置更新: 赋值type、fieldType、operator */
const beforeShouldUpdate = value => {
const prevCheckedItem = form.getFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name]) || {};
const prevType = prevCheckedItem[_constants.DYNAMIC_ENUM.TYPE];
const prevFieldType = prevCheckedItem[_constants.DYNAMIC_ENUM.FIELD_TYPE];
const prevOperator = prevCheckedItem[_constants.DYNAMIC_ENUM.OPERATOR];
const option = options.find(option => option[fieldNames.value] === value) || {};
const currType = option.type;
const currFieldType = option[fieldNames.fieldType];
const currTableObj = option[_constants.DYNAMIC_ENUM.TABLE_OBJ];
const equalType = prevType === currType;
const equalFieldType = prevFieldType === currFieldType;
const isInput = equalType && currType === 'input';
form.setFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name, _constants.DYNAMIC_ENUM.TABLE_OBJ], currTableObj);
if (!isInput) {
form.setFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name, _constants.DYNAMIC_ENUM.VALUE], undefined);
}
if (!equalType) {
form.setFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name, _constants.DYNAMIC_ENUM.TYPE], currType);
}
if (!equalType || !equalFieldType) {
const exciting = getOperatorOption({
type: currType,
fieldType: currFieldType,
locale: {}
}).some(option => option.value === prevOperator);
if (!exciting) {
form.setFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name, _constants.DYNAMIC_ENUM.OPERATOR], undefined);
}
form.setFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name, _constants.DYNAMIC_ENUM.FIELD_TYPE], currFieldType);
}
};
// 在此处set防止数据更新不及时
const normalize = value => {
beforeShouldUpdate(value);
return value;
};
return /*#__PURE__*/_react.default.createElement(_form.default.Item, {
name: [name, 'fieldName'],
noStyle: true,
normalize: normalize
}, /*#__PURE__*/_react.default.createElement(_select.default, {
showSearch: true,
options: options,
fieldNames: fieldNames,
optionFilterProp: fieldNames.label
}));
};
/** 表单 operator 操作符字段项 */
const OperatorItem = ({
name,
locale
}) => {
const form = _form.default.useFormInstance();
const options = useOperatorOptions({
name,
locale
});
// 数据保存时的格式化
const normalize = (value, prev) => {
// 从 between 操作符切换时清空value(因为value组件不一样,值也不一样)
const prevCheckedItem = form.getFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name]) || {};
/**
* input、number切换条件时无需清空
* 切换为'空'/'不为空'时, 清空value
*/
if (!['input', 'number'].includes(prevCheckedItem[_constants.DYNAMIC_ENUM.TYPE]) || ['empty', 'not_empty'].includes(value)) {
form.setFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name, _constants.DYNAMIC_ENUM.VALUE], undefined);
}
return value;
};
return /*#__PURE__*/_react.default.createElement(_form.default.Item, {
name: [name, _constants.DYNAMIC_ENUM.OPERATOR],
noStyle: true,
normalize: normalize
}, /*#__PURE__*/_react.default.createElement(_select.default, {
showSearch: true,
optionFilterProp: "label",
options: options
}));
};
const DynamicValueItem = ({
name,
dataSource
}) => {
const form = _form.default.useFormInstance();
// 动态的字段 DYNAMIC_ENUM
const complexItem = _form.default.useWatch([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS, name]) || {};
// 从来源数据取配置参数: onOpenChange…
const itemProps = (0, _react.useMemo)(() => {
let origin = complexItem;
if (Array.isArray(dataSource)) {
// 匹配所需要的参数 options、multiple、……
origin = dataSource.find(v => v[_constants.DYNAMIC_ENUM.FIELD_NAME] === complexItem[_constants.DYNAMIC_ENUM.FIELD_NAME]);
}
// 为空、不为空时不可编辑
const disabled = ['empty', 'not_empty'].includes(complexItem[_constants.DYNAMIC_ENUM.OPERATOR]);
origin = {
...origin,
disabled
};
// 参数再调整, 用于改变使用组件类型
if (['select', 'checkbox'].includes(complexItem[_constants.DYNAMIC_ENUM.TYPE])) {
const isMultiple = ['in', 'not_in'].includes(complexItem[_constants.DYNAMIC_ENUM.OPERATOR]);
origin[_constants.DYNAMIC_ENUM.TYPE] = isMultiple ? 'checkbox' : 'select';
}
if (['cascader'].includes(complexItem[_constants.DYNAMIC_ENUM.TYPE])) {
// 特殊处理: 高级筛选级联组件为json类型的查询时重置为多选
const isJson = ['json'].includes(complexItem[_constants.DYNAMIC_ENUM.FIELD_TYPE]);
const isMultiple = ['in', 'not_in'].includes(complexItem[_constants.DYNAMIC_ENUM.OPERATOR]);
origin.multiple = isJson || isMultiple;
}
if (['date', 'range', 'dateRange'].includes(complexItem[_constants.DYNAMIC_ENUM.TYPE])) {
const isRange = complexItem[_constants.DYNAMIC_ENUM.OPERATOR] === 'between';
origin[_constants.DYNAMIC_ENUM.TYPE] = isRange ? 'range' : 'date';
}
return (0, _omit.default)(origin, [_constants.DYNAMIC_ENUM.FIELD_NAME, _constants.DYNAMIC_ENUM.FIELD_TYPE, _constants.DYNAMIC_ENUM.OPERATOR, _constants.DYNAMIC_ENUM.RELATION, _constants.DYNAMIC_ENUM.TABLE_OBJ]);
}, [dataSource, complexItem]);
const handleOpenChange = open => {
const conditions = form.getFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS]) || [];
const values = (0, _utils.getFilterKeyValue)(conditions);
itemProps.onOpenChange?.(open, values);
};
const shouldUpdate = (0, _ahooks.useMemoizedFn)(() => {
const updateFields = (0, _utils.flatDeepDeps)(complexItem[_constants.DYNAMIC_ENUM.FIELD_NAME], dataSource);
const conditions = form.getFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS]) || [];
const resetConditions = (0, _utils.getUpdateResult)(updateFields, conditions);
if (resetConditions?.length) {
form.setFieldValue([_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS], resetConditions);
}
});
const normalize = value => {
shouldUpdate();
if (Array.isArray(value) && !value.length) return undefined;
return value;
};
return /*#__PURE__*/_react.default.createElement(_form.default.Item, {
name: [name, 'value'],
noStyle: true,
normalize: normalize
}, /*#__PURE__*/_react.default.createElement(_DynamicComponent.default, (0, _extends2.default)({}, itemProps, {
onOpenChange: handleOpenChange
})));
};
/** 主体区域 */
const ComplexBody = props => {
const {
dataSource,
locale
} = props;
const fieldOptions = (0, _react.useMemo)(() => {
const uniqDataSource = (0, _uniqBy.default)(dataSource, _constants.DYNAMIC_ENUM.FIELD_NAME);
return uniqDataSource.map(item => (0, _pick.default)(item, ['title', _constants.DYNAMIC_ENUM.FIELD_NAME, _constants.DYNAMIC_ENUM.TYPE, _constants.DYNAMIC_ENUM.FIELD_TYPE, _constants.DYNAMIC_ENUM.TABLE_OBJ]));
}, [dataSource]);
return /*#__PURE__*/_react.default.createElement("div", {
className: "complex_body"
}, /*#__PURE__*/_react.default.createElement(_form.default.List, {
name: [_constants.FIELD_ENUM.COMPLEX, _constants.FIELD_ENUM.CONDITIONS],
initialValue: [{}]
}, (fields, {
add,
remove
}) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
className: "complex_list"
}, fields.map(({
key,
name
}) => {
return /*#__PURE__*/_react.default.createElement("div", {
key: key,
className: "complex_list_item"
}, /*#__PURE__*/_react.default.createElement(FieldItem, {
name: name,
options: fieldOptions
}), /*#__PURE__*/_react.default.createElement(_form.default.Item, {
name: [name, _constants.DYNAMIC_ENUM.FIELD_TYPE],
noStyle: true
}), /*#__PURE__*/_react.default.createElement(_form.default.Item, {
name: [name, _constants.DYNAMIC_ENUM.RELATION],
noStyle: true
}), /*#__PURE__*/_react.default.createElement(_form.default.Item, {
name: [name, _constants.DYNAMIC_ENUM.TABLE_OBJ],
noStyle: true
}), /*#__PURE__*/_react.default.createElement(OperatorItem, {
name: name,
locale: locale
}), /*#__PURE__*/_react.default.createElement(_form.default.Item, {
name: [name, 'type'],
noStyle: true
}), /*#__PURE__*/_react.default.createElement(DynamicValueItem, {
name: name,
dataSource: dataSource
}), /*#__PURE__*/_react.default.createElement(_button.default, {
type: "text",
danger: true,
icon: /*#__PURE__*/_react.default.createElement(_iconFont.default, {
type: "lm-icon-a-shidia1qingchu"
}),
onClick: () => remove(name)
}));
})), /*#__PURE__*/_react.default.createElement(_controls.default, {
type: "select",
options: fieldOptions,
fieldNames: {
label: 'title',
value: _constants.DYNAMIC_ENUM.FIELD_NAME
},
onChange: (fieldName, option) => add({
[_constants.DYNAMIC_ENUM.FIELD_NAME]: option[_constants.DYNAMIC_ENUM.FIELD_NAME],
[_constants.DYNAMIC_ENUM.TYPE]: option[_constants.DYNAMIC_ENUM.TYPE],
[_constants.DYNAMIC_ENUM.TABLE_OBJ]: option[_constants.DYNAMIC_ENUM.TABLE_OBJ],
[_constants.DYNAMIC_ENUM.FIELD_TYPE]: option[_constants.DYNAMIC_ENUM.FIELD_TYPE] || _constants.initialFieldsValue[_constants.DYNAMIC_ENUM.FIELD_TYPE],
[_constants.DYNAMIC_ENUM.OPERATOR]: option[_constants.DYNAMIC_ENUM.OPERATOR] || _constants.initialFieldsValue[_constants.DYNAMIC_ENUM.OPERATOR],
[_constants.DYNAMIC_ENUM.RELATION]: option[_constants.DYNAMIC_ENUM.RELATION] || _constants.initialFieldsValue[_constants.DYNAMIC_ENUM.RELATION]
}),
showSearch: false
}, /*#__PURE__*/_react.default.createElement(_button.default, {
type: "dashed",
icon: /*#__PURE__*/_react.default.createElement(_iconFont.default, {
type: "lm-icon-a-tongyonga0xinzeng"
})
}, locale.incrementQuery)))));
};
/** 底部区域 */
const ComplexFooter = props => {
const {
onCancel,
onOk,
locale
} = props;
const [loading, setLoading] = (0, _react.useState)(false);
const handleOk = async () => {
setLoading(true);
try {
await onOk();
} finally {
setLoading(false);
}
};
return /*#__PURE__*/_react.default.createElement("div", {
className: "complex_footer"
}, /*#__PURE__*/_react.default.createElement(_button.default, {
onClick: onCancel
}, locale.cancel), /*#__PURE__*/_react.default.createElement(_button.default, {
type: "primary",
icon: /*#__PURE__*/_react.default.createElement(_iconFont.default, {
type: "lm-icon-sousuo"
}),
onClick: handleOk,
loading: loading
}, locale.query));
};
const ComplexRender = props => {
return /*#__PURE__*/_react.default.createElement("div", {
className: "filter_dropdown_complex complex_container"
}, /*#__PURE__*/_react.default.createElement(ComplexHeader, {
locale: props.locale
}), /*#__PURE__*/_react.default.createElement(ComplexBody, props), /*#__PURE__*/_react.default.createElement(ComplexFooter, props));
};
var _default = ComplexRender;
exports.default = _default;