/** * 敏感词屏蔽字库 * 用于过滤用户输入中的敏感词汇,将其替换为 * */ import { SENSITIVE_WORDS } from './sensitiveWordList' type FileSaveHandle = { createWritable: () => Promise<{ write: (data: Blob) => Promise close: () => Promise }> } type WindowWithFilePicker = Window & { showSaveFilePicker?: (options?: { suggestedName?: string types?: Array<{ accept: Record }> }) => Promise } const isAbortError = (error: unknown) => error instanceof DOMException && error.name === 'AbortError' const triggerAnchorDownload = (blob: Blob, filename: string) => { const url = URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = filename link.rel = 'noopener' document.body.appendChild(link) link.click() document.body.removeChild(link) setTimeout(() => URL.revokeObjectURL(url), 1000) } export async function downloadDataUrlImage(dataUrl: string, filename: string): Promise { if (!dataUrl) return const response = await fetch(dataUrl) const blob = await response.blob() const fileType = blob.type || 'image/png' const picker = (window as WindowWithFilePicker).showSaveFilePicker if (picker) { try { const handle = await picker({ suggestedName: filename, types: [{ accept: { [fileType]: ['.png'] } }], }) const writable = await handle.createWritable() await writable.write(blob) await writable.close() return } catch (error) { if (isAbortError(error)) return } } triggerAnchorDownload(blob, filename) } /** * 检查文本中是否包含英文字母 */ export function containsEnglish(text: string): boolean { return /[a-zA-Z]/.test(text) } /** * 检查文本中是否包含数字 */ export function containsNumber(text: string): boolean { return /\d/.test(text) } /** * 检查文本中是否包含特殊符号或标点符号 */ export function containsSpecialChars(text: string): boolean { // 检测除中文逗号、顿号、句号之外的标点符号和特殊符号 return /[\p{P}\p{S}]/u.test(text.replace(/[,、。]/g, '')) } /** * 检查文本中是否包含敏感词 * @param text 待检查的文本 * @returns 是否包含敏感词 */ export function containsSensitiveWord(text: string): boolean { if (!text) return false const normalizedText = text.toLowerCase().trim() return SENSITIVE_WORDS.some((word) => normalizedText.includes(word.toLowerCase())) } /** * 将文本中的敏感词替换为 * * @param text 待处理的文本 * @returns 处理后的文本 */ export function filterSensitiveWords(text: string): string { if (!text) return text let result = text SENSITIVE_WORDS.forEach((word) => { const regex = new RegExp(word, 'gi') result = result.replace(regex, '*'.repeat(word.length)) }) return result } /** * 实时过滤输入内容(在用户输入时调用) * @param input 用户输入的内容 * @returns 过滤后的内容 */ export function filterInput(input: string): string { if (!input) return input let filtered = input // 过滤英文字母 filtered = filtered.replace(/[a-zA-Z]/g, '') // 过滤数字 filtered = filtered.replace(/\d/g, '') // 过滤其他标点符号和特殊符号 // 保留:中文字符、空格、中文逗号、顿号、句号 // 过滤:除 ,、。 之外的标点符号和特殊符号 filtered = filtered.replace(/(?![,、。])[\p{P}\p{S}]/gu, '') // 进行敏感词过滤(替换为星号,不直接删除) filtered = filterSensitiveWords(filtered) return filtered } /** * 验证输入内容的完整性 * @param input 用户输入的内容 * @returns 验证结果 { valid: boolean, message: string } */ export function validateInput(input: string): { valid: boolean; message: string } { if (!input || !input.trim()) { return { valid: false, message: '内容不能为空' } } if (containsEnglish(input)) { return { valid: false, message: '不能包含英文字母' } } if (containsNumber(input)) { return { valid: false, message: '不能包含数字' } } if (containsSpecialChars(input)) { return { valid: false, message: '不能包含特殊符号' } } if (containsSensitiveWord(input)) { return { valid: false, message: '内容包含敏感词,请修改后重试' } } return { valid: true, message: '' } }