广州矛调粤政易端
xusd
7 days ago d27794814b69d18aeb8ee96a46cae91d5613570c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import React from 'react';
 
/**
 * CharacterCounter - 字符计数逻辑组件
 * 只处理字符计数逻辑,不包含任何样式
 * 
 * @param {string} value - 要计数的文本值
 * @param {number} maxLength - 允许的最大字符数
 * @param {function} onChange - 文本变化时的回调函数
 * @param {function} onCountChange - 字符数量变化时的回调函数
 * @param {function} setFormValue - 设置表单值的函数
 * @param {string} formFieldName - 表单字段名
 * @returns {Object} - 返回字符数相关的数据和更新方法
 */
const useCharacterCounter = (props) => {
  const { 
    value, 
    maxLength, 
    onChange, 
    onCountChange, 
    setFormValue, 
    formFieldName 
  } = props;
 
  // 计算字符数的函数(中文占2个,其他占1个)
  const countCharacters = (str) => {
    if (!str) return 0;
    let count = 0;
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      if (char >= 0x4e00 && char <= 0x9fa5) {
        count += 1; // 中文占1个字符(基于客户需求调整)
      } else {
        count += 1; // 其他字符占1个字符
      }
    }
    return count;
  };
  
  // 处理文本变化
  const handleTextChange = (textValue) => {
    if (typeof textValue === 'string') {  // 允许空字符串通过验证
      const count = countCharacters(textValue);
      const isExceeded = count > maxLength;
      
      // 更新文本值 - 即使超出也更新文本,但返回超出标记
      if (onChange) {
        onChange(textValue);
      }
      
      // 更新字符计数 - 即使超出也更新计数
      if (onCountChange) {
        onCountChange(count);
      }
      
      // 更新表单值
      if (setFormValue && formFieldName) {
        setFormValue({ [formFieldName]: textValue });
      }
      
      // 返回结果包含超出标记
      return {
        success: !isExceeded,
        isExceeded,
        count
      };
    }
    return {
      success: false,
      isExceeded: false,
      count: 0
    };
  };
  
  // 检查当前是否超出字数限制
  const checkIsExceeded = () => {
    const count = countCharacters(value);
    return count > maxLength;
  };
  
  return {
    countCharacters,
    handleTextChange,
    currentCount: countCharacters(value),
    maxLength,
    isExceeded: checkIsExceeded()
  };
};
 
export default useCharacterCounter;