153 lines
3.5 KiB
Go
153 lines
3.5 KiB
Go
package utils
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
|
swd "github.com/kirklin/go-swd"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type SensitiveWordUtil struct {
|
|
detector *swd.SWD
|
|
once sync.Once
|
|
initErr error
|
|
}
|
|
|
|
// 全局单例实例
|
|
var (
|
|
sensitiveWordInstance *SensitiveWordUtil
|
|
sensitiveWordOnce sync.Once
|
|
)
|
|
|
|
// GetSensitiveWordUtil 获取敏感词工具单例实例
|
|
func GetSensitiveWordUtil() *SensitiveWordUtil {
|
|
sensitiveWordOnce.Do(func() {
|
|
sensitiveWordInstance = &SensitiveWordUtil{}
|
|
})
|
|
return sensitiveWordInstance
|
|
}
|
|
|
|
// InitDetector 初始化敏感词检测器(单例模式)
|
|
func (s *SensitiveWordUtil) InitDetector() error {
|
|
s.once.Do(func() {
|
|
detector, err := swd.New()
|
|
if err != nil {
|
|
s.initErr = err
|
|
global.GVA_LOG.Error("Failed to initialize sensitive word detector", zap.Error(err))
|
|
return
|
|
}
|
|
s.detector = detector
|
|
global.GVA_LOG.Info("Sensitive word detector initialized successfully")
|
|
})
|
|
return s.initErr
|
|
}
|
|
|
|
// DetectSensitive 检测文本中的敏感词
|
|
func (s *SensitiveWordUtil) DetectSensitive(text string) ([]swd.SensitiveWord, error) {
|
|
if s.detector == nil {
|
|
if err := s.InitDetector(); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
words := s.detector.MatchAll(text)
|
|
return words, nil
|
|
}
|
|
|
|
// HasSensitive 检查文本是否包含敏感词
|
|
func (s *SensitiveWordUtil) HasSensitive(text string) (bool, error) {
|
|
if s.detector == nil {
|
|
if err := s.InitDetector(); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
|
|
return s.detector.Detect(text), nil
|
|
}
|
|
|
|
// FilterText 过滤文本中的敏感词,返回过滤后的文本和是否包含敏感词
|
|
func (s *SensitiveWordUtil) FilterText(text string) (filtered string, hasSensitive bool, err error) {
|
|
if s.detector == nil {
|
|
if err := s.InitDetector(); err != nil {
|
|
return text, false, err
|
|
}
|
|
}
|
|
|
|
// 检查是否包含敏感词
|
|
hasSensitive = s.detector.Detect(text)
|
|
|
|
if !hasSensitive {
|
|
return text, false, nil
|
|
}
|
|
|
|
// 使用星号替换敏感词
|
|
filtered = s.detector.ReplaceWithAsterisk(text)
|
|
return filtered, true, nil
|
|
}
|
|
|
|
// FilterTextWithCustomReplace 使用自定义替换策略过滤敏感词
|
|
func (s *SensitiveWordUtil) FilterTextWithCustomReplace(text string, replaceFunc func(swd.SensitiveWord) string) (filtered string, hasSensitive bool, err error) {
|
|
if s.detector == nil {
|
|
if err := s.InitDetector(); err != nil {
|
|
return text, false, err
|
|
}
|
|
}
|
|
|
|
// 检查是否包含敏感词
|
|
hasSensitive = s.detector.Detect(text)
|
|
|
|
if !hasSensitive {
|
|
return text, false, nil
|
|
}
|
|
|
|
// 使用自定义替换策略
|
|
filtered = s.detector.ReplaceWithStrategy(text, replaceFunc)
|
|
return filtered, true, nil
|
|
}
|
|
|
|
// GetFirstSensitiveWord 获取文本中第一个敏感词
|
|
func (s *SensitiveWordUtil) GetFirstSensitiveWord(text string) (*swd.SensitiveWord, error) {
|
|
if s.detector == nil {
|
|
if err := s.InitDetector(); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
word := s.detector.Match(text)
|
|
return word, nil
|
|
}
|
|
|
|
// AddCustomWords 添加自定义敏感词
|
|
func (s *SensitiveWordUtil) AddCustomWords(words map[string]swd.Category) error {
|
|
if s.detector == nil {
|
|
if err := s.InitDetector(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return s.detector.AddWords(words)
|
|
}
|
|
|
|
// RemoveWord 移除指定敏感词
|
|
func (s *SensitiveWordUtil) RemoveWord(word string) error {
|
|
if s.detector == nil {
|
|
if err := s.InitDetector(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return s.detector.RemoveWord(word)
|
|
}
|
|
|
|
// Clear 清空词库
|
|
func (s *SensitiveWordUtil) Clear() error {
|
|
if s.detector == nil {
|
|
if err := s.InitDetector(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return s.detector.Clear()
|
|
}
|