ny
昨天 282fbc6488f4e8ceb5fda759f963ee88fbf7b999
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
import { ref, unref } from 'vue';
 
export interface MaskOptions {
  filler: string;
  ignoreChar: string;
  maskType: number;
  prefixLimit: number;
  prefixSpecifyChar: string;
  prefixType: number;
  suffixLimit: number;
  suffixSpecifyChar: string;
  suffixType: number;
  unrealMaskLength: number;
  useUnrealMask: boolean;
}
 
/**
 * maskType
 * 1 - 全掩盖
 * 2 - 姓名-显示前1个字,后1个字
 * 3 - 手机号-显示前3位,后4位
 * 4 - 邮箱-显示前3个字,@和之后的字
 * 5 - 身份证-显示前6位,后3位,虚拟为4位
 * 6 - IP地址-显示第1段IP
 * 7 - 车牌号-显示前1个字,后2位
 * 8 - 银行卡号-显示前6位,后4位
 * 0 - 自定义规则
 */
export const defaultMaskOptions: MaskOptions = {
  filler: '*', // 填充符号
  ignoreChar: '', // 显示字符
  maskType: 1, // 掩码规则
  prefixLimit: 0, // 开头字数
  prefixSpecifyChar: '', // 开头字符
  prefixType: 1, // 开头显示
  suffixLimit: 0, // 结尾字数
  suffixSpecifyChar: '', // 结尾字符
  suffixType: 1, // 结尾显示
  unrealMaskLength: 1, // 虚拟掩码长度
  useUnrealMask: false, // 虚拟掩码
};
 
export function useTextMask(options?: Nullable<Partial<MaskOptions>>) {
  const config = ref({ ...defaultMaskOptions, ...options });
 
  // 全掩盖
  function maskAll(str: string): string {
    return unref(config).filler.repeat(str.length);
  }
  // 姓名 显示前1个字,后1个字
  function maskName(str: string): string {
    if (str.length <= 1) return str;
    const prefix = str[0];
    if (str.length === 2) return prefix + unref(config).filler;
    const suffix = str.slice(-1);
    const maskedChars = unref(config).filler.repeat(str.length - 2);
    return prefix + maskedChars + suffix;
  }
  // 手机号 - 显示前3位,后4位
  function maskPhoneNumber(str: string): string {
    if (str.length <= 7) return str;
    const prefix = str.slice(0, 3);
    const suffix = str.slice(-4);
    const maskedChars = unref(config).filler.repeat(str.length - 7);
    return prefix + maskedChars + suffix;
  }
  // 邮箱 - 显示前3个字,@和之后的字
  function maskEmailAddress(str: string): string {
    const atIndex = str.indexOf('@');
    if (str.length <= 3 || (atIndex !== -1 && atIndex < 3)) return str;
    let suffixLength = 0;
    let maskedCharsLength = str.length - 3;
    if (atIndex > 0) {
      suffixLength = atIndex;
      maskedCharsLength = atIndex - 3;
    }
    const prefix = str.slice(0, 3);
    const suffix = suffixLength ? str.slice(suffixLength) : '';
    const maskedChars = unref(config).filler.repeat(maskedCharsLength);
    return prefix + maskedChars + suffix;
  }
  // 身份证 - 显示前6位,后3位,虚拟为4位
  function maskIdNumber(str: string): string {
    if (str.length <= 9) return str;
    const prefix = str.slice(0, 6);
    const suffix = str.slice(-3);
    const maskedChars = unref(config).filler.repeat(4);
    return prefix + maskedChars + suffix;
  }
  // IP地址-显示第1段IP
  function maskIPAddress(str: string): string {
    const segments = str.split('.');
    if (segments.length === 0) return str;
    const maskedChars = `.${unref(config).filler.repeat(3)}`.repeat(3);
    return segments[0] + maskedChars;
  }
  // 车牌号-显示前1个字,后2位
  function maskLicensePlate(str: string): string {
    if (str.length <= 3) return str;
    const prefix = str[0];
    const suffix = str.slice(-2);
    const maskedChars = unref(config).filler.repeat(str.length - 3);
    return prefix + maskedChars + suffix;
  }
  // 银行卡号-显示前6位,后4位
  function maskBankCard(str: string): string {
    if (str.length <= 10) return str;
    const prefix = str.slice(0, 6);
    const suffix = str.slice(-4);
    const maskedChars = unref(config).filler.repeat(str.length - 10);
    return prefix + maskedChars + suffix;
  }
  // 自定义掩码规则
  function maskCustom(str: string): string {
    let prefixLength = 0;
    let suffixLength = 0;
    if (unref(config).prefixType === 2)
      prefixLength = unref(config).prefixLimit || 0;
    if (
      (unref(config).prefixType === 3 || unref(config).prefixType === 4) &&
      unref(config).prefixSpecifyChar
    ) {
      const specifyCharIndex = str.indexOf(unref(config).prefixSpecifyChar);
      if (specifyCharIndex !== -1)
        prefixLength =
          unref(config).prefixType === 3
            ? specifyCharIndex
            : specifyCharIndex + unref(config).prefixSpecifyChar.length;
    }
    if (unref(config).suffixType === 2)
      suffixLength = unref(config).suffixLimit || 0;
    if (
      (unref(config).suffixType === 3 || unref(config).suffixType === 4) &&
      unref(config).suffixSpecifyChar
    ) {
      const specifyCharIndex = str.indexOf(unref(config).suffixSpecifyChar);
      if (specifyCharIndex !== -1)
        suffixLength =
          unref(config).suffixType === 3
            ? str.length -
              specifyCharIndex -
              unref(config).suffixSpecifyChar.length
            : str.length - specifyCharIndex;
    }
    if (prefixLength + suffixLength >= str.length) return str;
    const prefix = prefixLength ? str.slice(0, prefixLength) : '';
    const suffix = suffixLength ? str.slice(-suffixLength) : '';
    let middleChar = '';
    if (unref(config).ignoreChar) {
      const ignoreCharList = unref(config).ignoreChar.split(',');
      const middleStr = str.slice(prefixLength, str.length - suffixLength);
      const reg = new RegExp(
        `(${ignoreCharList.map((o) => o.replaceAll('*', String.raw`\*`)).join('|')})`,
        'g',
      );
      let list = middleStr.split(reg);
      list = list.map((o) => {
        if (o && !ignoreCharList.includes(o)) {
          const maskedLength = unref(config).useUnrealMask
            ? unref(config).unrealMaskLength || 1
            : o.length;
          o = unref(config).filler.repeat(maskedLength);
        }
        return o;
      });
      middleChar = list.join('');
    } else {
      const maskedLength = unref(config).useUnrealMask
        ? unref(config).unrealMaskLength || 1
        : str.length - prefixLength - suffixLength;
      middleChar = unref(config).filler.repeat(maskedLength);
    }
 
    return prefix + middleChar + suffix;
  }
 
  // 获取掩码后文本
  function getMaskedText(str: string): string {
    if (!str) return '';
    if (unref(config).maskType === 1) return maskAll(str);
    if (unref(config).maskType === 2) return maskName(str);
    if (unref(config).maskType === 3) return maskPhoneNumber(str);
    if (unref(config).maskType === 4) return maskEmailAddress(str);
    if (unref(config).maskType === 5) return maskIdNumber(str);
    if (unref(config).maskType === 6) return maskIPAddress(str);
    if (unref(config).maskType === 7) return maskLicensePlate(str);
    if (unref(config).maskType === 8) return maskBankCard(str);
    if (unref(config).maskType === 0) return maskCustom(str);
    return str;
  }
 
  return {
    getMaskedText,
    maskAll,
    maskBankCard,
    maskCustom,
    maskEmailAddress,
    maskIdNumber,
    maskIPAddress,
    maskLicensePlate,
    maskName,
    maskPhoneNumber,
  };
}