UNPKG

linkmore-design

Version:

🌈 🚀lm组件库。🚀

636 lines (621 loc) 21.1 kB
"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;