"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _tslib = require("tslib");

var _mobx = require("mobx");

var _raf = _interopRequireDefault(require("raf"));

var _isString = _interopRequireDefault(require("lodash/isString"));

var _isEqual = _interopRequireDefault(require("lodash/isEqual"));

var _isObject = _interopRequireDefault(require("lodash/isObject"));

var _merge = _interopRequireDefault(require("lodash/merge"));

var _utils = require("../utils");

var _DataSet = _interopRequireDefault(require("./DataSet"));

var _Validator = _interopRequireDefault(require("../validator/Validator"));

var _enum = require("./enum");

var _LookupCodeStore = _interopRequireDefault(require("../stores/LookupCodeStore"));

var _LovCodeStore = _interopRequireDefault(require("../stores/LovCodeStore"));

var _AttachmentStore = _interopRequireDefault(require("../stores/AttachmentStore"));

var _localeContext = _interopRequireDefault(require("../locale-context"));

var _utils2 = require("./utils");

var _utils3 = require("../axios/utils");

var _utils4 = require("../stores/utils");

var _AttachmentFile = _interopRequireDefault(require("./AttachmentFile"));

var _iteratorHelper = require("../iterator-helper");

var _treeHelper = require("../tree-helper");

var _LookupCache = _interopRequireDefault(require("./LookupCache"));

function isEqualDynamicProps(oldProps, newProps) {
  if (newProps === oldProps) {
    return true;
  }

  if ((0, _isObject["default"])(newProps) && (0, _isObject["default"])(oldProps)) {
    var newKeys = Object.keys(newProps);
    var length = newKeys.length;

    if (length) {
      if (length !== Object.keys(oldProps).length) {
        return false;
      }

      return newKeys.every(function (key) {
        var value = newProps[key];
        var oldValue = oldProps[key];

        if (oldValue === value) {
          return true;
        }

        if (typeof value === 'function' && typeof oldValue === 'function') {
          return value.toString() === oldValue.toString();
        }

        return (0, _isEqual["default"])(oldValue, value);
      });
    }
  }

  return (0, _isEqual["default"])(newProps, oldProps);
}

function getPropsFromLovConfig(lovCode, propsName) {
  var props = {};

  if (lovCode) {
    var config = _LovCodeStore["default"].getConfig(lovCode);

    if (config) {
      propsName.forEach(function (name) {
        var value = config[name];

        if (value) {
          props[name] = value;
        }
      });
    }
  }

  return props;
}

var LOOKUP_SIDE_EFFECT_KEYS = ['type', 'lookupUrl', 'lookupCode', 'lookupAxiosConfig', 'lovCode', 'lovQueryAxiosConfig', 'lovPara', 'cascadeMap', 'lovQueryUrl', 'optionsProps'];
var LOV_SIDE_EFFECT_KEYS = ['lovCode', 'lovDefineAxiosConfig', 'lovDefineUrl', 'optionsProps'];
var LOOKUP_DATA = 'lookupData';

function getLookupToken(field, record) {
  if (record) {
    var lookupTokens = record.lookupTokens;

    if (lookupTokens) {
      var name = field.name;

      if (lookupTokens.has(name)) {
        return lookupTokens.get(name);
      }
    }

    if (field.record) {
      var dsField = record.dataSet.getField(field.name);
      return dsField && dsField.lookupToken;
    }
  }

  return field.lookupToken;
}

function setLookupToken(field, token, record) {
  if (record) {
    if (token !== undefined || record.lookupTokens) {
      var lookupTokens = (0, _utils2.getIf)(record, 'lookupTokens', function () {
        return _mobx.observable.map();
      });
      lookupTokens.set(field.name, token);
    }
  } else if (token !== field.lookupToken) {
    field.lookupToken = token;
  }
}

function combineWithOldLookupData(lookup, field, record) {
  var lookupData = field.get(LOOKUP_DATA, record);

  if (lookupData) {
    var valueField = field.get('valueField', record);
    var others = lookupData.filter(function (data) {
      return lookup.every(function (item) {
        return item[valueField] !== data[valueField];
      });
    });

    if (others.length) {
      return others.concat(lookup.slice());
    }
  }

  return lookup;
}

var defaultProps = {
  type: _enum.FieldType.auto,
  required: false,
  readOnly: false,
  disabled: false,
  group: false,
  textField: _utils2.defaultTextField,
  valueField: _utils2.defaultValueField,
  trueValue: true,
  falseValue: false,
  trim: _enum.FieldTrim.both
};

var Field = /*#__PURE__*/function () {
  function Field() {
    var _this = this;

    var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    var dataSet = arguments.length > 1 ? arguments[1] : undefined;
    var record = arguments.length > 2 ? arguments[2] : undefined;
    (0, _classCallCheck2["default"])(this, Field);
    (0, _mobx.runInAction)(function () {
      _this.dataSet = dataSet;
      _this.record = record;
      _this.props = _mobx.observable.map(props);

      if (!props.options) {
        var dynamicProps = props.dynamicProps,
            computedProps = props.computedProps;

        if (typeof dynamicProps === 'function') {
          _this.hasLookupSideEffects = true;
          _this.hasLovSideEffects = true;
        } else {
          var keys = Object.keys((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, computedProps), dynamicProps));

          if (keys.length) {
            _this.hasLookupSideEffects = keys.some(function (key) {
              return LOOKUP_SIDE_EFFECT_KEYS.includes(key);
            });
            _this.hasLovSideEffects = keys.some(function (key) {
              return LOV_SIDE_EFFECT_KEYS.includes(key);
            });
          }
        }

        if (record) {
          var dsField = dataSet.getField(props.name);

          if (dsField) {
            if (!_this.hasLookupSideEffects) {
              _this.hasLookupSideEffects = dsField.hasLookupSideEffects;
            }

            if (!_this.hasLovSideEffects) {
              _this.hasLovSideEffects = dsField.hasLovSideEffects;
            }
          }

          _this.processForLookupAndLovConfig(record);
        } else {
          (0, _raf["default"])(function () {
            _this.fetchLookup();

            _this.fetchLovConfig();
          });
        }
      }
    });
  }

  (0, _createClass2["default"])(Field, [{
    key: "attachments",
    get: function get() {
      return this.getAttachments();
    },
    set: function set(attachments) {
      this.setAttachments(attachments);
    }
  }, {
    key: "attachmentCount",
    get: function get() {
      return this.getAttachmentCount();
    },
    set: function set(count) {
      this.setAttachmentCount(count);
    }
  }, {
    key: "pristineProps",
    get: function get() {
      return (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, this.props.toPOJO()), this.dirtyProps);
    },
    set: function set(props) {
      var _this2 = this;

      (0, _mobx.runInAction)(function () {
        var dirtyProps = _this2.dirtyProps;

        if (dirtyProps) {
          var newProps = {};
          var dirtyKeys = Object.keys(dirtyProps);

          if (dirtyKeys.length) {
            dirtyKeys.forEach(function (key) {
              var item = _this2.props.get(key);

              newProps[key] = item;

              if ((0, _utils.isSame)(item, props[key])) {
                delete dirtyProps[key];
              } else {
                dirtyProps[key] = props[key];
              }
            });
          }

          _this2.props.replace((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, props), newProps));
        } else {
          _this2.props.replace(props);
        }
      });
    }
  }, {
    key: "lookup",
    get: function get() {
      return this.getLookup();
    }
  }, {
    key: "options",
    get: function get() {
      return this.getOptions();
    }
  }, {
    key: "dirty",
    get: function get() {
      return this.isDirty();
    }
  }, {
    key: "name",
    get: function get() {
      return this.props.get('name');
    }
  }, {
    key: "order",
    get: function get() {
      return this.get('order');
    },
    set: function set(order) {
      this.set('order', order);
    }
  }, {
    key: "valid",
    get: function get() {
      return this.isValid();
    }
  }, {
    key: "validationMessage",
    get: function get() {
      return this.getValidationMessage();
    }
  }, {
    key: "processForLookupAndLovConfig",
    value: function processForLookupAndLovConfig(record) {
      var _this3 = this;

      var hasLovSideEffects = this.hasLovSideEffects,
          hasLookupSideEffects = this.hasLookupSideEffects;

      if (hasLovSideEffects || hasLookupSideEffects) {
        (0, _raf["default"])(function () {
          if (hasLookupSideEffects) {
            _this3.fetchLookup(undefined, record);
          }

          if (hasLovSideEffects) {
            _this3.fetchLovConfig(record);
          }
        });
      }
    }
  }, {
    key: "isDirty",
    value: function isDirty() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;

      if (record) {
        var name = this.name;
        var dirtyData = record.dirtyData;

        if (dirtyData && dirtyData.size) {
          var chainFieldName = (0, _utils2.getChainFieldName)(record, name);

          if (dirtyData.has(chainFieldName) || (0, _iteratorHelper.iteratorSome)(dirtyData.keys(), function (key) {
            return chainFieldName.startsWith("".concat(key, "."));
          })) {
            return true;
          }

          if (this.get('type', record) === _enum.FieldType.intl) {
            var tlsKey = this.dataSet.getConfig('tlsKey');

            if (record.get(tlsKey) && Object.keys(_localeContext["default"].supports).some(function (lang) {
              return dirtyData.has((0, _utils2.getChainFieldName)(record, "".concat(tlsKey, ".").concat(name, ".").concat(lang)));
            })) {
              return true;
            }
          }
        }
      }

      return false;
    }
    /**
     * 获取所有属性
     * @return 属性对象
     */

  }, {
    key: "getProps",
    value: function getProps() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;
      var dsField = this.findDataSetField();
      var lovCode = this.get('lovCode', record);
      return (0, _merge["default"])({
        lookupUrl: this.dataSet.getConfig('lookupUrl')
      }, defaultProps, getPropsFromLovConfig(lovCode, ['textField', 'valueField']), dsField && dsField.props.toPOJO(), this.props.toPOJO());
    }
    /**
     * 根据属性名获取属性值
     * @param propsName 属性名
     * @return {any}
     */

  }, {
    key: "get",
    value: function get(propsName) {
      var record = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.record;
      var prop = this.getProp(propsName, record);

      if (prop !== undefined) {
        return prop;
      }

      return defaultProps[propsName];
    }
  }, {
    key: "getProp",
    value: function getProp(propsName) {
      var _this4 = this;

      var record = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.record;

      if (record && !this.record) {
        var recordField = record.ownerFields.get(this.name);

        if (recordField) {
          var recordProp = recordField.getProp(propsName);

          if (recordProp !== undefined) {
            return recordProp;
          }
        }
      }

      if (!['computedProps', 'dynamicProps'].includes(propsName)) {
        var computedPropsMap = record ? (0, _utils2.getIf)(record, 'computedFieldProps', function () {
          return new Map();
        }) : (0, _utils2.getIf)(this, 'computedProps', function () {
          return new Map();
        });
        var computedKey = "__".concat(this.name, "$").concat(propsName, "__");
        var computedProp = computedPropsMap.get(computedKey);

        if (computedProp) {
          var computedValue = computedProp.get();

          if (computedValue !== undefined) {
            return computedValue;
          }
        } else {
          var computedProps = this.get('computedProps', record);

          if (computedProps) {
            var newComputedProp = (0, _mobx.computed)(function () {
              var computProp = computedProps[propsName];

              if (typeof computProp === 'function') {
                var prop = _this4.executeDynamicProps(computProp, propsName, record);

                if (prop !== undefined) {
                  _this4.checkDynamicProp(propsName, prop, record);

                  return prop;
                }
              }
            }, {
              name: computedKey,
              context: record || this
            });
            computedPropsMap.set(computedKey, newComputedProp);

            var _computedValue = newComputedProp.get();

            if (_computedValue !== undefined) {
              return _computedValue;
            }
          }
        }

        var dynamicProps = this.get('dynamicProps', record);

        if (dynamicProps) {
          if (typeof dynamicProps === 'function') {
            (0, _utils.warning)(false, " The dynamicProps hook will be deprecated. Please use dynamicProps map.\n              For e.g,\n              Bad case:\n              dynamicProps({ record }) {\n                return {\n                  bind: record.get('xx'),\n                  label: record.get('yy'),\n                }\n              }\n              Good case:\n              dynamicProps = {\n                bind({ record }) {\n                  return record.get('xx')\n                },\n                label({ record }) {\n                  return record.get('yy'),\n                }\n              }");
            var props = this.executeDynamicProps(dynamicProps, propsName, record);

            if (props && propsName in props) {
              var prop = props[propsName];
              this.checkDynamicProp(propsName, prop, record);
              return prop;
            }
          } else {
            var dynamicProp = dynamicProps[propsName];

            if (typeof dynamicProp === 'function') {
              var _prop = this.executeDynamicProps(dynamicProp, propsName, record);

              if (_prop !== undefined) {
                this.checkDynamicProp(propsName, _prop, record);
                return _prop;
              }
            }
          }

          this.checkDynamicProp(propsName, undefined, record);
        }
      }

      var value = this.props.get(propsName);

      if (value !== undefined) {
        return value;
      }

      if (propsName === 'lookup') {
        var dataSet = this.dataSet;
        var lookupToken = getLookupToken(this, record);
        var lookupCaches = dataSet.lookupCaches;

        if (lookupToken && lookupCaches) {
          var lookup = lookupCaches.get(lookupToken);

          if (lookup) {
            var items = lookup.items;

            if (items) {
              return items;
            }
          }

          return undefined;
        }
      }

      var dsField = this.findDataSetField();

      if (dsField) {
        var dsValue = dsField.getProp(propsName);

        if (dsValue !== undefined) {
          return dsValue;
        }
      }

      if (propsName === 'textField' || propsName === 'valueField') {
        var lovCode = this.get('lovCode', record);
        var lovProp = getPropsFromLovConfig(lovCode, [propsName])[propsName];

        if (lovProp) {
          return lovProp;
        }
      }

      if (propsName === 'lookupUrl') {
        return this.dataSet.getConfig('lookupUrl');
      }

      if (['min', 'max'].includes(propsName)) {
        if (this.get('type', record) === _enum.FieldType.number) {
          if (propsName === 'max') {
            return Infinity;
          }

          return -Infinity;
        }
      }

      return undefined;
    }
    /**
     * 设置属性值
     * @param propsName 属性名
     * @param value 属性值
     * @return {any}
     */

  }, {
    key: "set",
    value: function set(propsName, value) {
      var _this5 = this;

      var record = this.record,
          name = this.name;

      if (record) {
        var recordField = record.ownerFields.get(name);

        if (recordField) {
          if (recordField !== this) {
            recordField.set(propsName, value);
            return recordField;
          }
        } else {
          record.ownerFields.set(name, this);
        }
      }

      var oldValue = this.get(propsName);

      if (!isEqualDynamicProps((0, _mobx.toJS)(oldValue), value)) {
        var dirtyProps = (0, _utils2.getIf)(this, 'dirtyProps', {});

        if (!(propsName in dirtyProps)) {
          (0, _mobx.set)(dirtyProps, propsName, oldValue);
        } else if ((0, _utils.isSame)((0, _mobx.toJS)(dirtyProps[propsName]), value)) {
          (0, _mobx.remove)(dirtyProps, propsName);
        }

        this.props.set(propsName, value);
        var dataSet = this.dataSet;
        dataSet.fireEvent(_enum.DataSetEvents.fieldChange, {
          dataSet: dataSet,
          record: record,
          name: name,
          field: this,
          propsName: propsName,
          value: value,
          oldValue: oldValue
        });
        this.handlePropChange(propsName, value, oldValue, record);

        if (!record) {
          dataSet.forEach(function (r) {
            var recordField = r.ownerFields.get(name);

            if (!recordField || !recordField.props.has(propsName)) {
              _this5.handlePropChange(propsName, value, oldValue, r);
            }
          });
        }
      }

      return this;
    }
  }, {
    key: "replace",
    value: function replace() {
      var _this6 = this;

      var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      var p = (0, _objectSpread2["default"])({}, props);
      this.props.forEach(function (_v, key) {
        if (![LOOKUP_DATA, 'name'].includes(key)) {
          _this6.set(key, props[key]);
        }

        delete p[key];
      });
      return this.merge(p);
    }
  }, {
    key: "merge",
    value: function merge(props) {
      var _this7 = this;

      Object.keys(props).forEach(function (key) {
        if (key !== 'name') {
          _this7.set(key, props[key]);
        }
      });
      return this;
    }
  }, {
    key: "getLookup",
    value: function getLookup() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;
      var lookupToken = getLookupToken(this, record);
      var lookupCaches = this.dataSet.lookupCaches;

      if (lookupToken && lookupCaches) {
        var lookup = lookupCaches.get(lookupToken);

        if (lookup) {
          var items = lookup.items;

          if (items) {
            return combineWithOldLookupData(items, this, record);
          }
        }
      }
    }
    /**
     * 根据lookup值获取lookup对象
     * @param value lookup值
     * @return {object}
     */

  }, {
    key: "getLookupData",
    value: function getLookupData(value) {
      var record = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.record;
      value = value === undefined ? this.getValue(record) : value;
      var valueField = this.get('valueField', record);
      var data = {};
      var lookup = this.getLookup(record);

      if (lookup) {
        return lookup.find(function (obj) {
          return (0, _utils.isSameLike)((0, _mobx.get)(obj, valueField), value);
        }) || data;
      }

      return data;
    }
  }, {
    key: "getValue",
    value: function getValue() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;
      var r = record || this.dataSet.current;

      if (r) {
        return r.get(this.name);
      }
    }
    /**
     * 可以根据lookup值获取含义
     * @param value lookup值
     * @param boolean showValueIfNotFound
     * @return {string}
     */

  }, {
    key: "getLookupText",
    value: function getLookupText(value, showValueIfNotFound) {
      var record = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.record;
      value = value === undefined ? this.getValue(record) : value;
      var textField = this.get('textField', record);
      var valueField = this.get('valueField', record);
      var lookup = this.getLookup(record);

      if (lookup) {
        var optionsProps = this.get('optionsProps', record);
        var found;

        if (optionsProps && optionsProps.childrenField) {
          found = (0, _treeHelper.treeFind)(lookup, function (node) {
            return (0, _utils.isSameLike)((0, _mobx.get)(node, valueField), value);
          }, optionsProps.childrenField);
        } else {
          found = lookup.find(function (obj) {
            return (0, _utils.isSameLike)((0, _mobx.get)(obj, valueField), value);
          });
        }

        if (found) {
          return (0, _mobx.get)(found, textField);
        }

        if (showValueIfNotFound) {
          return value;
        }

        return undefined;
      }
    }
    /**
     * 可以根据options值获取含义
     * @param value opions值
     * @param boolean showValueIfNotFound
     * @return {string}
     */

  }, {
    key: "getOptionsText",
    value: function getOptionsText(value, showValueIfNotFound) {
      var record = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.record;
      value = value === undefined ? this.getValue(record) : value;
      var textField = this.get('textField', record);
      var valueField = this.get('valueField', record);
      var options = this.getOptions(record);

      if (options) {
        var found = options.find(function (item) {
          return (0, _utils.isSameLike)(item.get(valueField), value);
        });

        if (found) {
          return found.get(textField);
        }

        if (showValueIfNotFound) {
          return value;
        }

        return undefined;
      }
    }
    /**
     * 根据lookup值获取lookup含义
     * @param value lookup值
     * @param boolean showValueIfNotFound
     * @return {string}
     */

  }, {
    key: "getText",
    value: function getText(value, showValueIfNotFound) {
      var record = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.record;
      value = value === undefined ? this.getValue(record) : value;
      var lookup = this.getLookup(record);

      if (lookup && !(0, _isObject["default"])(value)) {
        return this.getLookupText(value, showValueIfNotFound, record);
      }

      var options = this.get('options', record);
      var textField = this.get('textField', record);

      if (options) {
        var valueField = this.get('valueField', record);
        var found = options.find(function (item) {
          return (0, _utils.isSameLike)(item.get(valueField), value);
        });

        if (found) {
          return found.get(textField);
        }
      }

      if (textField && (0, _isObject["default"])(value)) {
        if ((0, _mobx.isObservableObject)(value)) {
          return (0, _mobx.get)(value, textField);
        }

        return value[textField];
      }

      return value;
    }
  }, {
    key: "setOptions",
    value: function setOptions(options) {
      this.set('options', options);
    }
  }, {
    key: "getOptions",
    value: function getOptions() {
      var _this8 = this;

      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;
      var options = this.get('options', record);

      if (options) {
        return options;
      }

      var name = this.name;
      var computedOptionsMap = record ? (0, _utils2.getIf)(record, 'computedFieldOptions', function () {
        return new Map();
      }) : undefined;
      var computedOptions = computedOptionsMap ? computedOptionsMap.get(name) : this.computedOptions;

      if (computedOptions) {
        return computedOptions.get();
      }

      var newComputedOptions = (0, _mobx.computed)(function () {
        var optionsProps = _this8.get('optionsProps', record);

        var lovCode = _this8.get('lovCode', record);

        if (lovCode) {
          var type = _this8.get('type', record);

          if (type === _enum.FieldType.object || type === _enum.FieldType.auto) {
            return _LovCodeStore["default"].getLovDataSet(lovCode, _this8, optionsProps, record);
          }
        } // 确保 lookup 相关配置介入观察


        _LookupCodeStore["default"].getAxiosConfig(_this8, record);

        var lookupToken = getLookupToken(_this8, record);

        if (lookupToken) {
          var lookupCaches = _this8.dataSet.lookupCaches;

          if (lookupCaches) {
            var lookup = lookupCaches.get(lookupToken);

            if (lookup) {
              var items = lookup.items,
                  promise = lookup.promise;

              if (items) {
                var parentField = _this8.get('parentField', record);

                var idField = _this8.get('idField', record) || _this8.get('valueField', record);

                var selection = _this8.get('multiple', record) ? _enum.DataSetSelection.multiple : _enum.DataSetSelection.single;
                var props = {
                  data: combineWithOldLookupData(items, _this8, record),
                  paging: false,
                  selection: selection,
                  idField: idField,
                  parentField: parentField,
                  status: promise ? _enum.DataSetStatus.loading : _enum.DataSetStatus.ready
                };
                return new _DataSet["default"]((0, _utils2.mergeDataSetProps)(props, optionsProps), _this8.dataSet.context);
              }

              if (promise) {
                return new _DataSet["default"]({
                  status: _enum.DataSetStatus.loading
                }, _this8.dataSet.context);
              }
            }
          }
        }

        return undefined;
      });

      if (computedOptionsMap) {
        computedOptionsMap.set(name, newComputedOptions);
      } else {
        this.computedOptions = newComputedOptions;
      }

      return newComputedOptions.get();
    }
    /**
     * 重置设置的属性
     */

  }, {
    key: "reset",
    value: function reset() {
      var dirtyProps = this.dirtyProps;

      if (dirtyProps) {
        this.props.merge(dirtyProps);
        this.dirtyProps = undefined;
      }
    }
  }, {
    key: "commit",
    value: function commit() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;

      if (record) {
        record.clearValidationError(this.name);
      }
    }
    /**
     * 是否必选
     * @return true | false
     */

  }, {
    key: "required",
    get: function get() {
      return this.get('required');
    }
    /**
     * 设置是否必选
     * @param required 是否必选
     */
    ,
    set: function set(required) {
      this.set('required', required);
    }
    /**
     * 是否只读
     * @return true | false
     */

  }, {
    key: "readOnly",
    get: function get() {
      return this.get('readOnly');
    }
    /**
     * 设置是否只读
     * @param readOnly 是否只读
     */
    ,
    set: function set(readOnly) {
      this.set('readOnly', readOnly);
    }
    /**
     * 是否禁用
     * @return true | false
     */

  }, {
    key: "disabled",
    get: function get() {
      return this.get('disabled');
    }
    /**
     * 设置是否禁用
     * @param disabled 是否禁用
     */
    ,
    set: function set(disabled) {
      this.set('disabled', disabled);
    }
    /**
     * 获取字段类型
     * @return 获取字段类型
     */

  }, {
    key: "type",
    get: function get() {
      return this.get('type');
    }
    /**
     * 设置字段类型
     * @param type 字段类型
     */
    ,
    set: function set(type) {
      this.set('type', type);
    }
    /**
     * 设置Lov的查询参数
     * @param {String} name
     * @param {Object} value
     */

  }, {
    key: "setLovPara",
    value: function setLovPara(name, value) {
      var record = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.record;
      var p = (0, _mobx.toJS)(this.get('lovPara', record)) || {};

      if (value === null) {
        delete p[name];
      } else {
        p[name] = value;
      }

      this.set('lovPara', p);
    }
  }, {
    key: "getValidatorPropGetter",
    value: function getValidatorPropGetter() {
      var _this9 = this;

      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;
      return function (key) {
        if (record) {
          switch (key) {
            case 'attachmentCount':
              {
                var attachments = _this9.getAttachments(record);

                var validAttachments = attachments && attachments.filter(function (_ref) {
                  var status = _ref.status;
                  return !status || ['success', 'done'].includes(status);
                });
                return validAttachments ? validAttachments.length : _this9.getAttachmentCount(record);
              }

            case 'max':
            case 'min':
              return (0, _utils2.getLimit)(_this9.get(key, record), record, key, _this9.get('type', record));

            case 'minLength':
            case 'maxLength':
              return (0, _utils2.getBaseType)(_this9.get('type', record)) !== _enum.FieldType.string ? undefined : _this9.get(key, record);

            case 'format':
              return _this9.get('format', record) || (0, _utils.getDateFormatByField)(_this9, _this9.get('type', record), record);

            case 'nonStrictStep':
              {
                var nonStrictStep = _this9.get('nonStrictStep', record);

                if (nonStrictStep === undefined) {
                  return _this9.dataSet.getConfig('numberFieldNonStrictStep');
                }

                return nonStrictStep;
              }

            case 'customValidator':
              return _this9.get('validator', record);

            case 'defaultValidationMessages':
              return (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, _this9.dataSet.getConfig('defaultValidationMessages')), _this9.get('defaultValidationMessages', record));

            default:
              return _this9.get(key, record);
          }
        }
      };
    }
    /**
     * 校验字段值
     * 只有通过record.getField()获取的field才能校验
     * @return true | false
     */

  }, {
    key: "checkValidity",
    value: function () {
      var _checkValidity = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
        var record,
            name,
            _yield$Validator$chec,
            valid,
            validationResults,
            _args = arguments;

        return _regenerator["default"].wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                record = _args.length > 0 && _args[0] !== undefined ? _args[0] : this.record;

                if (!record) {
                  _context.next = 11;
                  break;
                }

                name = this.name;
                _context.next = 5;
                return _Validator["default"].checkValidity(record.get(name), {
                  dataSet: record.dataSet,
                  name: name,
                  record: record
                }, this.getValidatorPropGetter(record));

              case 5:
                _yield$Validator$chec = _context.sent;
                valid = _yield$Validator$chec.valid;
                validationResults = _yield$Validator$chec.validationResults;
                record.setValidationError(name, validationResults);

                if (!record.validating) {
                  record.reportValidity({
                    field: this,
                    errors: validationResults,
                    valid: valid
                  }, true);
                }

                return _context.abrupt("return", valid);

              case 11:
                return _context.abrupt("return", true);

              case 12:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      function checkValidity() {
        return _checkValidity.apply(this, arguments);
      }

      return checkValidity;
    }()
    /**
     * 请求lookup值, 如有缓存值直接获得。
     * @param noCache default: undefined
     * @return Promise<object[]>
     */

  }, {
    key: "fetchLookup",
    value: function fetchLookup() {
      var _this10 = this;

      var noCache = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var record = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.record;
      var lookupCaches = (0, _utils2.getIf)(this.dataSet, 'lookupCaches', function () {
        return _mobx.observable.map();
      });
      var oldToken = getLookupToken(this, record);
      var batch = this.get('lookupBatchAxiosConfig', record) || this.dataSet.getConfig('lookupBatchAxiosConfig');
      var lookupCode = this.get('lookupCode', record);
      var useLookupBatch = lookupCode && this.dataSet.getConfig('useLookupBatch')(lookupCode, this) !== false;
      var promise;

      if (batch && lookupCode && Object.keys((0, _utils4.getLovPara)(this, record)).length === 0 && useLookupBatch) {
        var cachedLookup = (0, _utils2.getIfForMap)(lookupCaches, lookupCode, function () {
          return new _LookupCache["default"]();
        });

        if (lookupCode !== oldToken) {
          setLookupToken(this, lookupCode, record);
        }

        var items = cachedLookup.items;

        if (items) {
          promise = Promise.resolve(items);
        } else {
          promise = cachedLookup.promise;
        }

        if (!promise) {
          promise = _LookupCodeStore["default"].fetchLookupDataInBatch(lookupCode, batch).then((0, _mobx.action)(function (result) {
            if (result) {
              cachedLookup.items = result;
              cachedLookup.promise = undefined;
            }

            return result;
          }));
          cachedLookup.promise = promise;
        }
      } else {
        var axiosConfig = _LookupCodeStore["default"].getAxiosConfig(this, record, noCache);

        if (axiosConfig.url) {
          var lookupToken = (0, _utils3.buildURLWithAxiosConfig)(axiosConfig);

          if (lookupToken !== oldToken) {
            setLookupToken(this, lookupToken, record);
          }

          var _cachedLookup = (0, _utils2.getIfForMap)(lookupCaches, lookupToken, function () {
            return new _LookupCache["default"]();
          });

          if (!noCache) {
            var _items = _cachedLookup.items;

            if (_items) {
              promise = Promise.resolve(_items);
            } else {
              promise = _cachedLookup.promise;
            }
          }

          if (!promise) {
            promise = _LookupCodeStore["default"].fetchLookupData(axiosConfig, undefined, this).then((0, _mobx.action)(function (result) {
              if (result) {
                _cachedLookup.items = result;
                _cachedLookup.promise = undefined;
              }

              return result;
            }));
            _cachedLookup.promise = promise;
          }
        } else {
          setLookupToken(this, undefined, record);
        }
      }

      if (promise) {
        return promise.then((0, _mobx.action)(function (result) {
          var lookup = oldToken ? lookupCaches.get(oldToken) : undefined;

          if (lookup) {
            var _items2 = lookup.items;

            if (_items2 && oldToken !== getLookupToken(_this10, record)) {
              var value = _this10.getValue(record);

              var valueField = _this10.get('valueField', record);

              if (value && valueField) {
                var _ref2;

                var values = _this10.get('multiple', record) ? (_ref2 = []).concat.apply(_ref2, (0, _toConsumableArray2["default"])(value)) : [].concat(value);

                _this10.set(LOOKUP_DATA, values.reduce(function (lookupData, v) {
                  var found = _items2.find(function (item) {
                    return (0, _utils.isSameLike)(item[valueField], v);
                  });

                  if (found) {
                    lookupData.push(found);
                  }

                  return lookupData;
                }, []));
              }
            }
          }

          return (0, _mobx.toJS)(result);
        }));
      }

      return Promise.resolve(undefined);
    }
  }, {
    key: "fetchLovConfig",
    value: function fetchLovConfig() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;
      var lovCode = this.get('lovCode', record);

      if (lovCode) {
        _LovCodeStore["default"].fetchConfig(lovCode, this, record);
      }
    }
  }, {
    key: "fetchAttachments",
    value: function fetchAttachments(props) {
      var _this11 = this;

      var record = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.record;
      var bucketName = props.bucketName,
          bucketDirectory = props.bucketDirectory,
          attachmentUUID = props.attachmentUUID,
          storageCode = props.storageCode,
          isPublic = props.isPublic;

      var _this$dataSet$getConf = this.dataSet.getConfig('attachment'),
          fetchList = _this$dataSet$getConf.fetchList;

      if (fetchList) {
        fetchList({
          bucketName: bucketName,
          bucketDirectory: bucketDirectory,
          attachmentUUID: attachmentUUID,
          storageCode: storageCode,
          isPublic: isPublic
        }).then((0, _mobx.action)(function (results) {
          _this11.setAttachments(results.map(function (file) {
            return new _AttachmentFile["default"](file);
          }), record, undefined);
        }));
      }
    }
  }, {
    key: "fetchAttachmentCount",
    value: function fetchAttachmentCount(uuid, isPublic) {
      var _this12 = this;

      var record = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.record;

      var _this$dataSet$getConf2 = this.dataSet.getConfig('attachment'),
          batchFetchCount = _this$dataSet$getConf2.batchFetchCount;

      if (batchFetchCount && !this.attachments) {
        _AttachmentStore["default"].fetchCountInBatch({
          attachmentUUID: uuid,
          bucketName: this.get('bucketName', record),
          bucketDirectory: this.get('bucketDirectory', record),
          storageCode: this.get('storageCode', record),
          isPublic: isPublic
        }, this).then(function (count) {
          _this12.setAttachmentCount(count, record);
        });
      }
    }
  }, {
    key: "isValid",
    value: function isValid() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;

      if (record) {
        var results = this.getValidationErrorValues(record);
        return !results || !results.length;
      }

      return true;
    }
  }, {
    key: "getValidationMessage",
    value: function getValidationMessage() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;

      if (record) {
        var results = this.getValidationErrorValues(record);

        if (results && results.length) {
          return results[0].validationMessage;
        }
      }

      return undefined;
    }
  }, {
    key: "getValidationErrorValues",
    value: function getValidationErrorValues() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;

      if (record) {
        var errors = record.getValidationError(this.name);

        if (errors && errors.length) {
          return errors;
        }

        var unique = this.get('unique', record);

        if ((0, _isString["default"])(unique)) {
          var validationErrors = record.validationErrors;

          if (validationErrors) {
            var uniqueErrors = (0, _iteratorHelper.iteratorFind)(validationErrors.values(), function (errors) {
              return errors.some(function (error) {
                return error.ruleName === 'uniqueError' && error.validationProps.unique === unique;
              });
            });

            if (uniqueErrors) {
              return uniqueErrors;
            }
          }
        }
      }

      return [];
    }
  }, {
    key: "setAttachments",
    value: function setAttachments(attachments) {
      var record = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.record;
      var uuid = arguments.length > 2 ? arguments[2] : undefined;

      if (record) {
        var value = uuid || record.get(this.name);

        if (value) {
          var attachmentCaches = (0, _utils2.getIf)(record, 'attachmentCaches', function () {
            return _mobx.observable.map();
          });
          var cache = attachmentCaches.get(value);

          if (cache) {
            (0, _mobx.set)(cache, 'attachments', attachments);
          } else {
            attachmentCaches.set(value, {
              attachments: attachments
            });
          }
        }
      } else {
        this.set('attachments', attachments);
      }
    }
  }, {
    key: "getAttachments",
    value: function getAttachments() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;
      var uuid = arguments.length > 1 ? arguments[1] : undefined;

      if (record) {
        var value = uuid || record.get(this.name);

        if (value) {
          var attachmentCaches = record.attachmentCaches;

          if (attachmentCaches) {
            var cache = attachmentCaches.get(value);

            if (cache) {
              return (0, _mobx.get)(cache, 'attachments');
            }
          }
        }
      } else {
        return this.get('attachments');
      }

      return undefined;
    }
  }, {
    key: "setAttachmentCount",
    value: function setAttachmentCount(count) {
      var record = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.record;

      if (record) {
        var uuid = record.get(this.name);

        if (uuid) {
          var attachmentCaches = (0, _utils2.getIf)(record, 'attachmentCaches', function () {
            return _mobx.observable.map();
          });
          var cache = attachmentCaches.get(uuid);

          if (cache) {
            (0, _mobx.set)(cache, 'count', count);
          } else {
            attachmentCaches.set(uuid, {
              count: count
            });
          }
        }
      } else {
        this.set('attachmentCount', count);
      }
    }
  }, {
    key: "getAttachmentCount",
    value: function getAttachmentCount() {
      var record = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.record;
      var attachments = this.getAttachments(record);

      if (attachments) {
        return attachments.length;
      }

      if (record) {
        var uuid = record.get(this.name);

        if (uuid) {
          var attachmentCaches = record.attachmentCaches;

          if (attachmentCaches) {
            var cache = attachmentCaches.get(uuid);

            if (cache) {
              return (0, _mobx.get)(cache, 'count');
            }
          }
        }
      } else {
        return this.get('attachmentCount');
      }

      return undefined;
    }
  }, {
    key: "ready",
    value: function ready() {
      return Promise.resolve(true);
    }
  }, {
    key: "checkDynamicProp",
    value: function checkDynamicProp(propsName, newProp) {
      var _this13 = this;

      var record = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.record;
      var name = this.name;
      var lastDynamicProps = record ? function () {
        var lastDynamicFieldProps = (0, _utils2.getIf)(record, 'lastDynamicFieldProps', function () {
          return new Map();
        });
        var last = lastDynamicFieldProps.get(name);

        if (!last) {
          last = {};
          lastDynamicFieldProps.set(name, last);
        }

        return last;
      }() : (0, _utils2.getIf)(this, 'lastDynamicProps', {});
      var oldProp = lastDynamicProps[propsName];

      if (!isEqualDynamicProps(oldProp, newProp)) {
        (0, _raf["default"])((0, _mobx.action)(function () {
          if (record && oldProp !== undefined) {
            var _name = _this13.name;
            var errors = record.getValidationError(_name);

            if (errors) {
              if (propsName === 'validator') {
                record.clearValidationError(_name);
              } else if (!['label', 'defaultValidationMessages'].includes(propsName)) {
                errors.some(function (error) {
                  var validationProps = error.validationProps;

                  if (validationProps && Object.keys(validationProps).includes(propsName)) {
                    record.clearValidationError(_name);
                    return true;
                  }

                  return false;
                });
              }
            }
          }

          _this13.handlePropChange(propsName, newProp, oldProp, record);
        }));
      }

      lastDynamicProps[propsName] = newProp;
    }
  }, {
    key: "handlePropChange",
    value: function handlePropChange(propsName, newProp, oldProp) {
      var record = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : this.record;

      if (propsName === 'bind' && this.get('type', record) !== _enum.FieldType.intl) {
        if (record && !this.isDirty(record)) {
          if (newProp && oldProp) {
            record.init(newProp, record.get(oldProp));
          }

          if (oldProp) {
            record.init(oldProp, undefined);
          }
        }

        return;
      }

      if (LOOKUP_SIDE_EFFECT_KEYS.includes(propsName) || ['dynamicProps', 'computedProps'].includes(propsName) && (typeof newProp === 'function' || typeof oldProp === 'function' || newProp && Object.keys(newProp).some(function (key) {
        return LOOKUP_SIDE_EFFECT_KEYS.includes(key);
      }) || oldProp && Object.keys(oldProp).some(function (key) {
        return LOOKUP_SIDE_EFFECT_KEYS.includes(key);
      }))) {
        var noCache = this.get('noCache', record);
        this.set(LOOKUP_DATA, undefined);
        this.fetchLookup(noCache, record);
      }

      if (LOV_SIDE_EFFECT_KEYS.includes(propsName) || ['dynamicProps', 'computedProps'].includes(propsName) && (typeof newProp === 'function' || typeof oldProp === 'function' || newProp && Object.keys(newProp).some(function (key) {
        return LOV_SIDE_EFFECT_KEYS.includes(key);
      }) || oldProp && Object.keys(oldProp).some(function (key) {
        return LOV_SIDE_EFFECT_KEYS.includes(key);
      }))) {
        this.fetchLovConfig(record);
      }
    }
  }, {
    key: "executeDynamicProps",
    value: function executeDynamicProps(dynamicProps, propsName) {
      var record = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.record;
      var dataSet = this.dataSet,
          name = this.name;
      var dynamicPropsComputingChains = (0, _utils2.getIf)(this, 'dynamicPropsComputingChains', []);

      if (dynamicPropsComputingChains.includes(propsName)) {
        (0, _utils.warning)(false, "Cycle dynamicProps execution of field<".concat(name, ">. [").concat(dynamicPropsComputingChains.join(' -> '), " -> ").concat(propsName, "]"));
      } else {
        dynamicPropsComputingChains.push(propsName);

        try {
          return dynamicProps({
            dataSet: dataSet,
            record: record,
            name: name
          });
        } catch (e) {
          if (record) {
            throw e;
          }

          if (process.env.NODE_ENV !== 'production') {
            console.warn(e);
          }
        } finally {
          dynamicPropsComputingChains.pop();
        }
      }
    }
  }, {
    key: "findDataSetField",
    value: function findDataSetField() {
      var dataSet = this.dataSet,
          name = this.name,
          record = this.record;

      if (record && dataSet && name) {
        return dataSet.getField(name);
      }
    }
  }]);
  return Field;
}();

exports["default"] = Field;
Field.defaultProps = defaultProps;
(0, _tslib.__decorate)([_mobx.observable], Field.prototype, "lookupToken", void 0);
(0, _tslib.__decorate)([_mobx.observable], Field.prototype, "props", void 0);
(0, _tslib.__decorate)([_mobx.observable], Field.prototype, "dirtyProps", void 0);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "set", null);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "replace", null);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "merge", null);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "reset", null);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "commit", null);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "setLovPara", null);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "checkValidity", null);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "fetchLookup", null);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "setAttachments", null);
(0, _tslib.__decorate)([_mobx.action], Field.prototype, "setAttachmentCount", null);
//# sourceMappingURL=Field.js.map
