lodash#isString JavaScript Examples

The following examples show how to use lodash#isString. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.js    From hzero-front with Apache License 2.0 7 votes vote down vote up
/**
 * 处理context属性 以及将 属性转为对象
 * @param {*} props - 属性
 * @param {*} context - 外面传进来的 this
 */
export function commonDealForProps(props, context) {
  const contextProps = {};
  const dealProps1 = {};
  forEach(props, prop => {
    let dealProp = prop.attributeValue;
    if (isString(dealProp) && startsWith(dealProp, contextPrefix)) {
      const attributePath = dealProp.substr(5);
      dealProp = undefined;
      Object.defineProperty(contextProps, prop.attributeName, {
        get: () => get(context, attributePath),
        enumerable: true,
      });
    }
    if (dealProp !== undefined) {
      dealProps1[prop.attributeName] = dealProp;
    }
  });
  return { contextProps, dealProps1 };
}
Example #2
Source File: reducerInjectors.js    From QiskitFlow with Apache License 2.0 6 votes vote down vote up
export function injectReducerFactory(store, isValid) {
  return function injectReducer(key, reducer) {
    if (!isValid) checkStore(store);

    invariant(
      isString(key) && !isEmpty(key) && isFunction(reducer),
      '(app/utils...) injectReducer: Expected `reducer` to be a reducer function',
    );

    // Check `store.injectedReducers[key] === reducer` for hot reloading when a key is the same but a reducer is different
    if (
      Reflect.has(store.injectedReducers, key) &&
      store.injectedReducers[key] === reducer
    )
      return;

    store.injectedReducers[key] = reducer; // eslint-disable-line no-param-reassign
    store.replaceReducer(createReducer(store.injectedReducers));
  };
}
Example #3
Source File: index.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
// field props

  /**
   * deal LinkButton
   */
  getLinkButtonConfigOfPropValues(propValues, newConfig = []) {
    if (isString(propValues.modalRef)) {
      newConfig.push({
        [attributeNameProp]: 'modalRef',
        [attributeValueProp]: propValues.modalRef,
        [attributeTypeProp]: DataType.String,
      });
    }
    if (isString(propValues.paramMap)) {
      newConfig.push({
        [attributeNameProp]: 'paramMap',
        [attributeValueProp]: propValues.paramMap,
        [attributeTypeProp]: DataType.String,
      });
    }
  }
Example #4
Source File: permission.js    From d2admin-permission with MIT License 6 votes vote down vote up
/**
 * @description 权限检查
 * @param {String|Array} value 需要的权限
 * @param {Object}} config {Boolean} all 全部匹配
 * @param {Object}} config {Boolean} not 取反
 */
export default function permission (value = '', { all = false, not = false } = {}) {
  if (isArray(value) || isString(value)) {
    const permissions = store.state.d2admin.permission.permissions
    let has = utils.helper[all ? 'allIn' : 'oneOf'](permissions, value)
    if (not) has = !has
    return has
  } else {
    return false
  }
}
Example #5
Source File: transpile.js    From jafar with MIT License 6 votes vote down vote up
function transpileFieldTerms(terms = [], term, index, termName, resources) {
  terms.forEach((t, i) => transpileFieldTerm(terms, t, i));

  if (isString(term)) {
    terms[index] = { name: term };
  } else if (isFunction(term)) {
    indexes[termName] += 1;
    const name = `${termName}${indexes[termName]}`;
    const func = term;
    terms[index] = { name };
    resources.terms = resources.terms || {};
    resources.terms[name] = { func };
  }
}
Example #6
Source File: sagaInjectors.js    From QiskitFlow with Apache License 2.0 6 votes vote down vote up
checkDescriptor = descriptor => {
  const shape = {
    saga: isFunction,
    mode: mode => isString(mode) && allowedModes.includes(mode),
  };
  invariant(
    conformsTo(descriptor, shape),
    '(app/utils...) injectSaga: Expected a valid saga descriptor',
  );
}
Example #7
Source File: normalizeOrderBy.js    From rate-repository-api with MIT License 6 votes vote down vote up
normalizeOrderByItem = item => {
  if (isString(item)) {
    return { column: item, order: 'asc' };
  }

  if (isObject(item) && isString(item.column)) {
    const { column, order = 'asc' } = item;

    return { column, order: order.toLowerCase() };
  }

  throw new Error('Order by item must be a string or an object');
}
Example #8
Source File: transpile.js    From jafar with MIT License 6 votes vote down vote up
function transpileFieldValidators(field, resources) {
  (field.validators || []).forEach((validator, index) => {
    if (isString(validator)) {
      field.validators[index] = { name: validator };
    } else if (isFunction(validator)) {
      indexes.validator += 1;
      const name = `validator${indexes.validator}`;
      const func = validator;
      field.validators[index] = { name };
      resources.validators = resources.validators || {};
      resources.validators[name] = { func };
    }
  });
}
Example #9
Source File: sagaInjectors.js    From rysolv with GNU Affero General Public License v3.0 6 votes vote down vote up
checkDescriptor = descriptor => {
  const shape = {
    saga: isFunction,
    mode: mode => isString(mode) && allowedModes.includes(mode),
  };
  invariant(
    conformsTo(descriptor, shape),
    '(app/utils...) injectSaga: Expected a valid saga descriptor',
  );
}
Example #10
Source File: index.js    From datapass with GNU Affero General Public License v3.0 6 votes vote down vote up
export function isValidNAFCode(provider, NAFcode) {
  if (!isString(NAFcode)) {
    return false;
  }

  if (isEmpty(validNAFCode[provider])) {
    return true;
  }

  if (!validNAFCode[provider].some((code) => NAFcode.startsWith(code))) {
    return false;
  }

  return true;
}
Example #11
Source File: general.js    From gutenberg-forms with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Will check if the given string contains the search string
 *
 * @param {string} string
 * @param {string} searchString
 */

export function search(string, searchString) {
    // type validation
    if (!isString(string) || !isString(searchString)) {
        return false
    }

    // changing case
    string = toLower(string)
    searchString = toLower(searchString)

    // comparing
    return -1 !== searchString.indexOf(string) ? true : false
}
Example #12
Source File: search.js    From mapstore2-cadastrapp with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Triggers a search of owners to show the list of results.
 * @param {*} action$
 */
export function cadastrappOwnersSearch(action$) {
    return action$.ofType(OWNERS_SEARCH).switchMap(({searchType, rawParams}) => {
        const { commune, proprietaire, birthsearch, comptecommunal } = rawParams; // proprietaire in this case is a string
        // ddenom birthsearch=true
        const { cgocommune } = commune;
        const ddenom = isString(proprietaire) ? proprietaire : proprietaire?.value;
        return Rx.Observable.defer(() => searchType === SEARCH_TYPES.USER
            ? getProprietaire({ ddenom, birthsearch, cgocommune, details: 2 })
            : getCoProprietaireList({ ddenom, cgocommune, comptecommunal, details: 1})
        )
            .switchMap( owners => Rx.Observable.of(
                // if proprietaire was an object, a selection of the user occurred. So if owner is one, can perform search.
                // Otherwise, always show the list of users to avoid ambiguity or to do textual search.
                owners.length > 1 || isString(proprietaire)
                    ? showOwners(owners)
                    : search(searchType, rawParams)))
            .let(wrapStartStop(loading(true, 'search'), loading(false, 'search')));
    });
}
Example #13
Source File: reducerInjectors.js    From hackchat-client with Do What The F*ck You Want To Public License 6 votes vote down vote up
/**
 * Add target reducer
 * @param {Store} store Target redux store context
 * @param {boolean} isValid Validation has already happened
 */
export function injectReducerFactory(store, isValid) {
  return function injectReducer(key, reducer) {
    if (!isValid) checkStore(store);

    invariant(
      isString(key) && !isEmpty(key) && isFunction(reducer),
      '(app/utils...) injectReducer: Expected `reducer` to be a reducer function',
    );

    if (
      Reflect.has(store.injectedReducers, key) &&
      store.injectedReducers[key] === reducer
    )
      return;

    store.injectedReducers[key] = reducer; // eslint-disable-line no-param-reassign
    store.replaceReducer(createReducer(store.injectedReducers));
  };
}
Example #14
Source File: Switch.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
export function getConfigOfPropValues(propValues, newConfig = []) {
  if (isString(propValues.checkedChildren)) {
    newConfig.push({
      [attributeNameProp]: 'checkedChildren',
      [attributeValueProp]: propValues.checkedChildren,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.unCheckedChildren)) {
    newConfig.push({
      [attributeNameProp]: 'unCheckedChildren',
      [attributeValueProp]: propValues.unCheckedChildren,
      [attributeTypeProp]: DataType.String,
    });
  }
  return newConfig;
}
Example #15
Source File: sagaInjectors.js    From hackchat-client with Do What The F*ck You Want To Public License 6 votes vote down vote up
checkDescriptor = (descriptor) => {
  const shape = {
    saga: isFunction,
    mode: (mode) => isString(mode) && allowedModes.includes(mode),
  };
  invariant(
    conformsTo(descriptor, shape),
    '(app/utils...) injectSaga: Expected a valid saga descriptor',
  );
}
Example #16
Source File: Lov.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
export function getConfigOfPropValues(propValues, newConfig = []) {
  if (isString(propValues.code)) {
    newConfig.push({
      [attributeNameProp]: 'code',
      [attributeValueProp]: propValues.code,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isBoolean(propValues.cascadeFlag)) {
    newConfig.push({
      [attributeNameProp]: 'cascadeFlag',
      [attributeValueProp]: propValues.cascadeFlag,
      [attributeTypeProp]: DataType.Boolean,
    });
  }
  if (isString(propValues.cascadeFrom)) {
    newConfig.push({
      [attributeNameProp]: 'cascadeFrom',
      [attributeValueProp]: propValues.cascadeFrom,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.cascadeField)) {
    newConfig.push({
      [attributeNameProp]: 'cascadeField',
      [attributeValueProp]: propValues.cascadeField,
      [attributeTypeProp]: DataType.String,
    });
  }
  if (isString(propValues.textField)) {
    newConfig.push({
      [attributeNameProp]: 'textField',
      [attributeValueProp]: propValues.textField,
      [attributeTypeProp]: DataType.String,
    });
  }
  return newConfig;
}
Example #17
Source File: sagaInjectors.js    From rysolv with GNU Affero General Public License v3.0 5 votes vote down vote up
checkKey = key =>
  invariant(
    isString(key) && !isEmpty(key),
    '(app/utils...) injectSaga: Expected `key` to be a non empty string',
  )
Example #18
Source File: index.js    From hzero-front with Apache License 2.0 5 votes vote down vote up
// field props

  /**
   * deal Button
   */
  getButtonConfigOfPropValues(propValues, newConfig = [], field) {
    if (isString(propValues.type)) {
      newConfig.push({
        [attributeNameProp]: 'type',
        [attributeValueProp]: propValues.type,
        [attributeTypeProp]: DataType.String,
      });
      // warn will remove when save
      // eslint-disable-next-line no-param-reassign
      field.type = propValues.type;
    }
    if (isString(propValues.onClick)) {
      newConfig.push({
        [attributeNameProp]: 'onClick',
        [attributeValueProp]: propValues.onClick,
        [attributeTypeProp]: DataType.String,
      });
    }
    if (isNumber(propValues.style.marginRight)) {
      newConfig.push({
        [attributeNameProp]: 'style.marginRight',
        [attributeValueProp]: propValues.style.marginRight,
        [attributeTypeProp]: DataType.Number,
      });
      // warn will remove when save
      // eslint-disable-next-line no-param-reassign
      field.style = {
        marginRight: propValues.style.marginRight,
      };
    }
    const { btnProps, btnConfigs } = propValues;
    forEach(btnProps, (btnPropValue, btnPropKey) => {
      if (btnPropKey === 'modalBtns') {
        for (let i = 0; i < btnPropValue.length; i += 1) {
          newConfig.push({
            [attributeNameProp]: `${TOOLBAR_BTN_PREFIX}${modalBtnPrefix}[${i}]`,
            [attributeValueProp]: btnPropValue[i][attributeValueProp],
            [attributeTypeProp]: DataType.String,
          });
        }
      } else if (btnPropKey === 'subEvents') {
        for (let i = 0; i < btnPropValue.length; i += 1) {
          newConfig.push({
            [attributeNameProp]: `${TOOLBAR_BTN_PREFIX}${subEventPrefix}[${i}]`,
            [attributeValueProp]: btnPropValue[i][attributeValueProp],
            [attributeTypeProp]: DataType.String,
          });
        }
      } else {
        newConfig.push({
          [attributeNameProp]: `${TOOLBAR_BTN_PREFIX}[${btnPropKey}]`,
          [attributeValueProp]: btnPropValue,
          [attributeTypeProp]: btnConfigs[btnPropKey],
        });
      }
    });
  }
Example #19
Source File: Notify.jsx    From kube-design with MIT License 5 votes vote down vote up
convert = (args1, args2, type) => {
  if (isString(args1)) {
    return open({ title: args1, content: args2, type });
  }
  return open({ ...args1, type });
}
Example #20
Source File: sagaInjectors.js    From hackchat-client with Do What The F*ck You Want To Public License 5 votes vote down vote up
checkKey = (key) =>
  invariant(
    isString(key) && !isEmpty(key),
    '(app/utils...) injectSaga: Expected `key` to be a non empty string',
  )
Example #21
Source File: CoownershipSearch.jsx    From mapstore2-cadastrapp with GNU General Public License v3.0 5 votes vote down vote up
export default function CoownershipSearch({ loading, onSearch = () => { }, onOwnersSearch = () => {} }) {
    const [searchState, setFormState, resetFormState] = useFormState();
    const values = searchState[SEARCH_TYPES.COOWNER];
    const setValue = (k, v) => setFormState(SEARCH_TYPES.COOWNER, k, v);
    return (
        <div className="coownership-search">
            <h3><Message msgId={'cadastrapp.search.copropriete.title'}/></h3>
            <div style={{padding: "10px", height: 242}}>
                <div className="item-row">
                    <div className="label-col">
                        <ControlLabel><Message msgId={'cadastrapp.parcelle.city'}/></ControlLabel>
                    </div>
                    <div className="form-col">
                        <MunicipalityCombo value={values?.commune} onSelect={v => setValue('commune', v)} />
                        <div className="text-muted"><Message msgId={'cadastrapp.parcelle.cityExample'}/></div>
                    </div>
                </div>

                <div className="item-row">
                    <div className="label-col">
                        <ControlLabel><Message msgId={'cadastrapp.proprietaire.name.title'}/></ControlLabel>
                    </div>
                    <div className="form-col">
                        <ProprietaireCombo
                            value={values?.proprietaire}
                            disabled={!values?.commune}
                            cgocommune={values?.commune?.cgocommune}
                            onSelect={v => setValue('proprietaire', v)}
                            onChange={v => setValue('proprietaire', v)}
                        />
                        <div className="text-muted"><Message msgId={'cadastrapp.proprietaire.name.example'}/></div>
                    </div>
                </div>

                <div className="item-row">
                    <div className="label-col">
                        <ControlLabel><Message msgId={'cadastrapp.search.copropriete.parcelle.ident'}/></ControlLabel>
                    </div>
                    <div className="form-col">
                        <FormControl value={values?.parcelle ?? ""} onChange={e => setValue('parcelle', e.target.value)} type="text" bsSize="sm"/>
                        <div className="text-muted"><Message msgId={'cadastrapp.parcelle.ident.example'}/></div>
                    </div>
                </div>

                <div className="item-row">
                    <div className="label-col">
                        <ControlLabel><Message msgId={'cadastrapp.search.copropriete.comptecommunal.ident'}/></ControlLabel>
                    </div>
                    <div className="form-col">
                        <FormControl value={values?.comptecommunal ?? ""} onChange={e => setValue('comptecommunal', e.target.value)} type="text" bsSize="sm"/>
                        <div className="text-muted"><Message msgId={'cadastrapp.search.copropriete.comptecommunal.example'}/></div>
                    </div>
                </div>
            </div>
            <SearchButtons
                loading={loading}
                valid={isSearchValid(SEARCH_TYPES.COOWNER, searchState[SEARCH_TYPES.COOWNER])}
                onClear={() => resetFormState(SEARCH_TYPES.COOWNER)}
                onSearch={() => {
                    if (isString(searchState[SEARCH_TYPES.COOWNER]?.proprietaire) && !values?.parcelle) {
                        onOwnersSearch(SEARCH_TYPES.COOWNER, searchState[SEARCH_TYPES.COOWNER]);
                    } else {
                        // plot search
                        onSearch(SEARCH_TYPES.COOWNER, searchState[SEARCH_TYPES.COOWNER]);
                    }
                }}/>
        </div>
    );
}
Example #22
Source File: ETHWallet.js    From RRWallet with MIT License 5 votes vote down vote up
async sendContractTransaction(
    contract,
    amount,
    data,
    gasPrice,
    gasLimit,
    pwd,
    broadcast = true,
    nonce = -1,
    chainID = ethereumChainID()
  ) {
    contract = contract.toLowerCase();
    gasPrice = toFixedString(gasPrice);
    gasLimit = toFixedString(gasLimit);
    const fee = toFixedString(ethereum.toEther(new BigNumber(gasLimit).multipliedBy(gasPrice), "gwei"));
    data = data || "";
    if (nonce == -1) {
      nonce = await ETHRPCProvider.ethGetTransactionCount(this.address, "pending");
      nonce = Math.max(nonce, this.lastNonce + 1);
    }
    const result = await RRRNEthereum.sendContractTransaction(
      this.id,
      this.address,
      contract,
      amount + "",
      data,
      gasLimit,
      ethereum.toWei(gasPrice, "gwei"),
      Platform.select({ ios: nonce, android: nonce + "" }),
      chainID,
      broadcast,
      pwd
    );
    if (broadcast) {
      if (_.isString(result.nonce)) {
        result.nonce = parseInt(result.nonce);
      }
      if (result.hasOwnProperty("nonce") && _.isNumber(result.nonce)) {
        this.lastNonce = result.nonce;
      }
    }
    result.fee = fee;
    return result;
  }
Example #23
Source File: sagaInjectors.js    From QiskitFlow with Apache License 2.0 5 votes vote down vote up
checkKey = key =>
  invariant(
    isString(key) && !isEmpty(key),
    '(app/utils...) injectSaga: Expected `key` to be a non empty string',
  )
Example #24
Source File: index.js    From hzero-front with Apache License 2.0 4 votes vote down vote up
/**
   * deal field's attribute change
   */
  handleFieldValuesChange(props, changeValues, allValues) {
    // 使用 allValues 重写 field 的属性
    const { field, component, onRefresh } = this.props;
    const { validateFields } = this.editFormRef.current || {};
    if (validateFields) {
      validateFields(err => {
        if (!err) {
          const newConfig = [];
          field[fieldLabelProp] = allValues[fieldLabelProp];
          field[fieldNameProp] = allValues[fieldNameProp];
          // fields's common prop;
          field.requiredFlag = allValues.requiredFlag;
          // enabledFlag 是用来字段禁用的
          field.enabledFlag = allValues.enabledFlag;
          if (isBoolean(allValues.labelDisplayFlag)) {
            newConfig.push({
              [attributeNameProp]: 'labelDisplayFlag',
              [attributeValueProp]: allValues.labelDisplayFlag,
              [attributeTypeProp]: DataType.Boolean,
            });
          }

          if (isString(allValues.description)) {
            newConfig.push({
              [attributeNameProp]: 'description',
              [attributeValueProp]: allValues.description,
              [attributeTypeProp]: DataType.String,
            });
          }
          if (isString(allValues.placeholder)) {
            newConfig.push({
              [attributeNameProp]: 'placeholder',
              [attributeValueProp]: allValues.placeholder,
              [attributeTypeProp]: DataType.String,
            });
          }
          if (isString(allValues.onChange)) {
            newConfig.push({
              [attributeNameProp]: 'onChange',
              [attributeValueProp]: allValues.onChange,
              [attributeTypeProp]: DataType.String,
            });
          }

          const FieldComponent = fieldComponents[field.componentType];
          if (FieldComponent) {
            FieldComponent.getConfigOfPropValues(allValues, newConfig);
          } else {
            const getConfigOfPropValuesFunc = `get${field.componentType}ConfigOfPropValues`;

            if (this[getConfigOfPropValuesFunc]) {
              this[getConfigOfPropValuesFunc](allValues, newConfig);
            }
          }

          const prevFieldConfigs = field.config;
          field.config = newConfig.map(fieldConfig => {
            const prevFieldConfig = find(
              prevFieldConfigs,
              prevC => prevC[attributeNameProp] === fieldConfig[attributeNameProp]
            );
            return { ...prevFieldConfig, ...fieldConfig };
          });
          const newField = field; // { ...field };
          // 更新 feild 在 component 中的引用
          let fieldRefUpdate = false;
          forEach(component.fields, (fArr, rowIndex) => {
            forEach(fArr, (f, colIndex) => {
              if (f === field) {
                fieldRefUpdate = true;
                component.fields[rowIndex][colIndex] = newField;
                return false;
              }
            });
            return !fieldRefUpdate;
          });
          if (isFunction(onRefresh)) {
            onRefresh();
          }
        }
      });
    }
  }
Example #25
Source File: ETHWallet.js    From RRWallet with MIT License 4 votes vote down vote up
async sendBatchTransaction(coin, targets, gasPrice, perGasLimit, pwd, callback) {
    targets = JSON.parse(JSON.stringify(targets));

    const token = coin;
    if (!token || !isNumber(token.decimals)) {
      throw new Error("token不存在");
    }

    if (!isArray(targets) || targets.length === 0) {
      throw new Error("targets参数格式不正确");
    }

    gasPrice = new BigNumber(gasPrice + "");
    perGasLimit = new BigNumber(perGasLimit + "");

    if (perGasLimit.isLessThan(ETH_ERC20_TX_MIN_GASLIMIT)) {
      throw new Error(
        `单笔转账的gasLimit需大于${ETH_ERC20_TX_MIN_GASLIMIT}, 为保证交易正常, 请尽可能多的设置gasLimit, 未使用的gas将会在交易结束后退回`
      );
    }

    const tos = [];
    const amounts = [];

    let totalAmount = new BigNumber(0);

    for (const { address, amount } of targets) {
      if (isNil(address) || isNil(amount)) {
        throw new Error("targets含有非法输入");
      }

      if (!isString(address) || !isString(amount)) {
        throw new Error("非法输入,地址和数量必须为字符串");
      }

      let isStartsWith0x = _.startsWith(address, "0x"); //address.indexOf('0x') == 0;
      if ((isStartsWith0x && address.length != 42) || (!isStartsWith0x && address.length != 40)) {
        throw new Error(`含有非法地址${address}`);
      }

      tos.push(address);
      const amountBigNumber = new BigNumber(amount);
      amounts.push(new BigNumber(amountBigNumber));
      totalAmount = totalAmount.plus(amountBigNumber);
    }

    const balanceBigNumber = new BigNumber(token.balance + "");
    if (totalAmount.isGreaterThan(balanceBigNumber)) {
      throw new Error(
        `${token.name}余额不足, 转账数量:${toFixedLocaleString(totalAmount)}}, 余额:${toFixedLocaleString(
          balanceBigNumber
        )}`
      );
    }

    //两次approve 一次测试转账, 所以需要预留3笔gas数量
    const totalGasBignumber = ethereum.toEther(perGasLimit.multipliedBy(tos.length + 3).multipliedBy(gasPrice), "gwei");
    if (totalGasBignumber.isGreaterThan(this.ETH.balance + "")) {
      throw new Error(
        `ETH余额不足, 矿工费:${toFixedLocaleString(totalGasBignumber)}}, 余额:${toFixedLocaleString(this.ETH.balance)}`
      );
    }

    if (token instanceof ETH) {
      if (totalGasBignumber.plus(totalAmount).isGreaterThan(token.balance + "")) {
        throw new Error(
          `ETH余额不足, 矿工费:${toFixedLocaleString(totalGasBignumber)}}, 转账数量:${toFixedLocaleString(
            totalAmount
          )} 余额:${toFixedLocaleString(balanceBigNumber)}`
        );
      }
    }

    Device.keepScreenOn(true);
    try {
      if (coin instanceof ETH) {
        await this.sendETHBatchTransactionContract(token, tos, amounts, gasPrice, perGasLimit, pwd, callback);
      } else if (await this.shouldUseBatchTransactionContract(token.contract)) {
        let skinTestSuccess = false;
        try {
          //尝试调用单笔批量合约, 如果合约执行失败则降级到looping, 其他异常则中断发币
          await this.sendERC20BatchTransactionContract(
            token,
            _.take(tos, 1),
            _.take(amounts, 1),
            gasPrice,
            perGasLimit,
            pwd,
            callback
          );
          skinTestSuccess = true;
        } catch (error) {
          if (error.message === "批量发币合约执行失败") {
            await this.sendERC20BatchTransactionLooping(token, tos, amounts, gasPrice, perGasLimit, pwd, callback);
          } else {
            throw error;
          }
        }

        if (!skinTestSuccess) {
          return;
        }

        tos.splice(0, 1);
        amounts.splice(0, 1);
        await this.sendERC20BatchTransactionContract(token, tos, amounts, gasPrice, perGasLimit, pwd, result => {
          _.isFunction(callback) &&
            callback({
              ...result,
              from: result.from + 1,
            });
        });
      } else {
        await this.sendERC20BatchTransactionLooping(token, tos, amounts, gasPrice, perGasLimit, pwd, callback);
      }
    } catch (error) {
      throw error;
    }
    Device.keepScreenOn(false);
  }