- 更新陈云、鲁迅、聂耳等故居的展品图片素材 - 更新拼图细节图片 - 优化学习地图底图和详情图 - 更新音频素材 - 优化各故居 store 和页面组件
172 lines
4.4 KiB
TypeScript
172 lines
4.4 KiB
TypeScript
/**
|
|
* 敏感词屏蔽字库
|
|
* 用于过滤用户输入中的敏感词汇,将其替换为 *
|
|
*/
|
|
|
|
import { SENSITIVE_WORDS } from './sensitiveWordList'
|
|
type FileSaveHandle = {
|
|
createWritable: () => Promise<{
|
|
write: (data: Blob) => Promise<void>
|
|
close: () => Promise<void>
|
|
}>
|
|
}
|
|
|
|
type WindowWithFilePicker = Window & {
|
|
showSaveFilePicker?: (options?: {
|
|
suggestedName?: string
|
|
types?: Array<{
|
|
accept: Record<string, string[]>
|
|
}>
|
|
}) => Promise<FileSaveHandle>
|
|
}
|
|
|
|
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<void> {
|
|
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: '' }
|
|
}
|