You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

快速现金按键场景下的数字替换逻辑实现求助

解决方案

问题根源

你的现有代码使用lastIndexOf('0')每次替换字符串最后一个0,导致1000.00按2后变成1000.02,与预期的1002.00不符;同时未处理“输入0后再按其他数字时仅覆盖该0”的逻辑。

实现方案

我们需要提前标记快速现金数值中需要替换的0的位置,并通过指针跟踪当前替换位置,根据输入数字类型决定是否移动指针:

  1. 添加状态:跟踪可替换的0的索引列表,以及当前替换的位置指针。
  2. 快速现金选中逻辑:仅标记整数部分最后一个0和小数部分的所有0(匹配你的示例需求)。
  3. 键盘输入处理:替换指针指向的0,输入非0时移动指针,输入0时保持指针位置以便后续覆盖。

修改后的完整代码

import { useState, useCallback } from 'react';

const CashInput = () => {
  const [isQuickCash, setIsQuickCash] = useState(false);
  const [selectedValues, setSelectedValues] = useState('');
  // 新增状态:可替换的0的索引列表、当前替换位置指针
  const [replaceableIndices, setReplaceableIndices] = useState<number[]>([]);
  const [currentReplaceIdx, setCurrentReplaceIdx] = useState<number>(0);

  // 快速现金按键点击处理
  const handleQuickCash = (amount: string) => {
    setIsQuickCash(true);
    setSelectedValues(amount);
    
    const [integerPart, decimalPart] = amount.split('.');
    // 仅收集整数部分最后一个0的索引
    const lastIntegerZeroIdx = integerPart.lastIndexOf('0');
    const integerZeroIndices = lastIntegerZeroIdx !== -1 ? [lastIntegerZeroIdx] : [];
    // 收集小数部分所有0的索引(需加上整数部分长度+1,对应原字符串中的位置)
    const decimalZeroIndices = [...decimalPart]
      .map((char, idx) => char === '0' ? integerPart.length + 1 + idx : -1)
      .filter(idx => idx !== -1);
    
    // 合并索引:先替换整数最后一个0,再替换小数部分的0
    setReplaceableIndices([...integerZeroIndices, ...decimalZeroIndices]);
    setCurrentReplaceIdx(0);
  };

  // 键盘按键处理
  const handleKeypadButton = useCallback(
    (value: string) => {
      if (value === 'C') {
        setIsQuickCash(false);
        setSelectedValues('');
        setReplaceableIndices([]);
        setCurrentReplaceIdx(0);
      } else if (value === '.') {
        setSelectedValues((prev) => {
          const str = prev?.toString() || '';
          return str.includes('.') ? str : str + value;
        });
      } else if (isQuickCash) {
        setSelectedValues((prev) => {
          // 无可用替换位置时,直接追加输入
          if (replaceableIndices.length === 0 || currentReplaceIdx >= replaceableIndices.length) {
            return prev + value;
          }
          
          const charArr = prev.split('');
          const targetIdx = replaceableIndices[currentReplaceIdx];
          // 替换目标位置的0
          charArr[targetIdx] = value;
          const newStr = charArr.join('');
          
          // 输入非0数字时,移动指针到下一个替换位置
          if (value !== '0') {
            setCurrentReplaceIdx(prevIdx => prevIdx + 1);
          }
          
          return newStr;
        });
      } else {
        setSelectedValues(prev => (prev || '') + value);
      }
    },
    [isQuickCash, replaceableIndices, currentReplaceIdx],
  );

  // 组件渲染示例
  return (
    <div>
      <div>当前金额:{selectedValues || '0.00'}</div>
      <button onClick={() => handleQuickCash('1000.00')}>1000.00</button>
      <button onClick={() => handleQuickCash('500.00')}>500.00</button>
      <div className="keypad">
        {['1','2','3','4','5','6','7','8','9','0','.','C'].map(key => (
          <button key={key} onClick={() => handleKeypadButton(key)}>{key}</button>
        ))}
      </div>
    </div>
  );
};

export default CashInput;

测试验证

选中1000.00后依次按2、0、8:

  1. 按2 → 替换整数最后一个0,得到1002.00,指针移动到小数第一个0的位置。
  2. 按0 → 替换小数第一个0为0,指针保持不动。
  3. 按8 → 覆盖刚才输入的0为8,得到1002.08,指针移动到小数第二个0的位置。

完全符合你的需求。

内容的提问来源于stack exchange,提问作者Kaito Pader

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 14:17:01