diff --git a/README.md b/README.md
index f02ad92..4dbcd65 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
```sh
# 在解决方案下运行
docker build -t miaoyu:dev-0.0.3 -f src/2-api/HuanMeng.MiaoYu.WebApi/Dockerfile .
-docker build -t miaoyu:dev-0.0.3 --build-arg VERSION=7.0 --build-arg TARGET=dev -f src/2-api/HuanMeng.MiaoYu.WebApi/Dockerfile .
+docker build -t miaoyu:dev-0.0.4 --build-arg VERSION=7.0 --build-arg TARGET=dev -f src/2-api/HuanMeng.MiaoYu.WebApi/Dockerfile .
# 运行
diff --git a/src/0-core/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilterFrozen.cs b/src/0-core/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilterFrozen.cs
new file mode 100644
index 0000000..fcfd5d2
--- /dev/null
+++ b/src/0-core/HuanMeng.DotNetCore/TextCensor/SensitiveWord/SensitiveWordFilterFrozen.cs
@@ -0,0 +1,149 @@
+using System;
+using System.Collections.Frozen;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace HuanMeng.DotNetCore.TextCensor.SensitiveWord
+{
+ public class SensitiveWordFilterFrozen : ITextCensor
+ {
+ ///
+ /// 定义Trie树节点
+ ///
+ private class TrieNode
+ {
+ ///
+ /// 标记是否是一个敏感词的结尾
+ ///
+ public bool IsEnd { get; set; }
+ ///
+ /// 存储子节点
+ ///
+ public FrozenDictionary Children { get; private set; }
+
+ public TrieNode()
+ {
+ IsEnd = false;
+ Children = null;
+ }
+
+ ///
+ /// 将子节点字典冻结为 FrozenDictionary
+ ///
+ public void FreezeChildren(Dictionary children)
+ {
+ Children = children.ToFrozenDictionary();
+ }
+ }
+
+ ///
+ /// 根节点
+ ///
+ private TrieNode Root { get; set; }
+
+ public SensitiveWordFilterFrozen()
+ {
+ Root = new TrieNode();
+ }
+
+ ///
+ /// 添加敏感词到Trie树中
+ ///
+ ///
+ public void AddSensitiveWord(string word)
+ {
+ TrieNode currentNode = Root;
+ word = CleanText(word);
+ foreach (char c in word.ToLower())
+ {
+ // 如果当前字符不存在于子节点中,则添加
+ if (currentNode.Children == null || !currentNode.Children.ContainsKey(c))
+ {
+ var children = currentNode.Children?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value) ?? new Dictionary();
+ children[c] = new TrieNode();
+ currentNode.FreezeChildren(children);
+ }
+ currentNode = currentNode.Children[c];
+ }
+ currentNode.IsEnd = true; // 标记当前节点为敏感词结尾
+ }
+
+ ///
+ /// 清理文字
+ ///
+ ///
+ ///
+ public string CleanText(string sourceTxt)
+ {
+ if (string.IsNullOrEmpty(sourceTxt))
+ {
+ return string.Empty;
+ }
+
+ string cleanedText = sourceTxt
+ .Replace(',', ' ')
+ .Replace('.', ' ')
+ .Replace('。', ' ')
+ .Replace(',', ' ')
+ .Replace('@', ' ')
+ .Replace('-', ' ')
+ .Replace('*', ' ')
+ .Replace("1", string.Empty)
+ .Replace("2", string.Empty)
+ .Replace("3", string.Empty)
+ .Replace("4", string.Empty)
+ .Replace("5", string.Empty)
+ .Replace("6", string.Empty)
+ .Replace("9", string.Empty)
+ .Replace("0", string.Empty)
+ .Replace("_", string.Empty)
+ .Replace(" ", string.Empty).ToLower();
+ return cleanedText;
+ }
+
+ ///
+ /// 判断文本中是否包含敏感词
+ ///
+ ///
+ ///
+ public bool ContainsSensitiveWord(string text)
+ {
+ //过滤字符串
+ text = CleanText(text);
+ for (int i = 0; i < text.Length; i++)
+ {
+ TrieNode currentNode = Root;
+ int j = i;
+ // 从当前位置开始匹配敏感词
+ while (j < text.Length && currentNode.Children != null && currentNode.Children.ContainsKey(text[j]))
+ {
+ currentNode = currentNode.Children[text[j]];
+ // 如果当前节点是敏感词结尾,返回true
+ if (currentNode.IsEnd)
+ {
+ return true;
+ }
+ j++;
+ }
+ }
+ return false;
+ }
+
+ public bool TextCensor(string text)
+ {
+ return ContainsSensitiveWord(text);
+ }
+
+ public Task TextCensorAsync(string text)
+ {
+ return Task.Run(() =>
+ {
+ return ContainsSensitiveWord(text);
+ });
+
+ }
+ }
+}
diff --git a/src/0-core/HuanMeng.DotNetCore/TextCensor/TextCensorExtend.cs b/src/0-core/HuanMeng.DotNetCore/TextCensor/TextCensorExtend.cs
index c129f92..f5e2254 100644
--- a/src/0-core/HuanMeng.DotNetCore/TextCensor/TextCensorExtend.cs
+++ b/src/0-core/HuanMeng.DotNetCore/TextCensor/TextCensorExtend.cs
@@ -24,8 +24,12 @@ namespace HuanMeng.DotNetCore.TextCensor
public static ITextCensor GetITextCensor(string _dirPath)
{
- return GetSensitiveWordFilter(_dirPath);
+ return GetSensitiveWordFilterFrozen(_dirPath)
+ //GetSensitiveWordFilter(_dirPath)
+ ;
}
+
+
///
///
///
@@ -43,6 +47,50 @@ namespace HuanMeng.DotNetCore.TextCensor
return sensitiveWordFilter;
}
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static SensitiveWordFilterFrozen GetSensitiveWordFilterFrozen(string _dirPath)
+ {
+ SensitiveWordFilterFrozen sensitiveWordFilter = new SensitiveWordFilterFrozen();
+ var ckPath = Path.GetFullPath(_dirPath);
+ var filePath = Directory.EnumerateFiles(ckPath);
+ foreach (var item in filePath)
+ {
+ AddShieldString(item, sensitiveWordFilter);
+ }
+ return sensitiveWordFilter;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void AddShieldString(string path, SensitiveWordFilterFrozen sensitiveWordFilter)
+ {
+
+ if (!File.Exists(path))
+ {
+ throw new Exception("文件不存在");
+ }
+ using (StreamReader reader = new StreamReader(path, UnicodeEncoding.UTF8))
+ {
+
+ while (reader.Peek() > 0)
+ {
+
+ var tempStr = (reader.ReadLine() ?? "");
+ if (!string.IsNullOrEmpty(tempStr))
+ {
+ sensitiveWordFilter.AddSensitiveWord(tempStr);
+
+ }
+ }
+ }
+ }
///
///
///
@@ -68,8 +116,6 @@ namespace HuanMeng.DotNetCore.TextCensor
}
}
-
-
}
}
}
diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Cache/MiaoYuCache.cs b/src/0-core/HuanMeng.MiaoYu.Code/Cache/MiaoYuCache.cs
index d2d05b0..6a655aa 100644
--- a/src/0-core/HuanMeng.MiaoYu.Code/Cache/MiaoYuCache.cs
+++ b/src/0-core/HuanMeng.MiaoYu.Code/Cache/MiaoYuCache.cs
@@ -162,6 +162,30 @@ namespace HuanMeng.MiaoYu.Code.Cache
}
#endregion
+
+ #region 角色类型缓存表
+
+
+ ///
+ /// 菜单类型缓存表
+ ///
+ public CommonDataEntityCache? _category_Child_Menu { get; set; }
+ ///
+ /// 菜单类型的角色
+ ///
+ public List CategoryChildMenuList
+ {
+ get
+ {
+ if (_category_Child_Menu == null)
+ {
+ _category_Child_Menu = MiaoYuCacheExtend.GetMiaoYuDataEntityCache(cacheBase, expWhere: it => it.IsEnabled);
+ }
+ return _category_Child_Menu.DataList ?? new List();
+ }
+ }
+
+ #endregion
}
///
/// 缓存扩展类
diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Category/CategoryBLL.cs b/src/0-core/HuanMeng.MiaoYu.Code/Category/CategoryBLL.cs
index 96db245..a3a8658 100644
--- a/src/0-core/HuanMeng.MiaoYu.Code/Category/CategoryBLL.cs
+++ b/src/0-core/HuanMeng.MiaoYu.Code/Category/CategoryBLL.cs
@@ -69,7 +69,8 @@ namespace HuanMeng.MiaoYu.Code.Category
public BaseResponse>> GetRecommendList()
{
List> recommendDtos = new List>();
- var menuList = Dao.daoDbMiaoYu.context.T_Category_Child_Menu.Where(it => it.IsEnabled).ToList();
+
+ var menuList = MiaoYuCache.CategoryChildMenuList.Where(it => it.IsEnabled).ToList();
var node = DictionaryInfo.GetDictionariesChildNode(T_Sys_DictionaryEnum.categorymenu);
node.ForEach(_node =>
{
@@ -85,59 +86,6 @@ namespace HuanMeng.MiaoYu.Code.Category
recommendDtos.Add(banner);
}
});
- //#region 假数据
- //RecommendDto banner = new RecommendDto();
- //banner.Title = "Banner";
- //banner.Type = RecommendTypeEnum.banner.ToString();
- //banner.Data = new List();
- //banner.Data.Add(new CommonRecommendData
- //{
- // ActionId = "1",
- // ActionType = RecommendActionTypeEnum.Mall.ToString(),
- // ImageUrl = "https://cos.shhuanmeng.com/banner/20240717214627.png",
- //});
- //banner.Data.Add(new CommonRecommendData
- //{
- // ActionId = "2",
- // ActionType = RecommendActionTypeEnum.Page.ToString(),
- // ImageUrl = "https://cos.shhuanmeng.com/banner/202407172146272.png",
- //});
- //banner.Data.Add(new CommonRecommendData
- //{
- // ActionId = "3",
- // ActionType = RecommendActionTypeEnum.Chat.ToString(),
- // ImageUrl = "https://cos.shhuanmeng.com/banner/20240717214735.png",
- //});
- //recommendDtos.Add(banner);
- //RecommendDto tuijian = new RecommendDto();
- //tuijian.Title = "推荐";
- //tuijian.Type = RecommendTypeEnum.tuijian.ToString();
- //tuijian.Data = new List();
-
-
- //RecommendDto xiaoshuo = new RecommendDto();
- //xiaoshuo.Data = new List();
- //xiaoshuo.Title = "小说";
- //xiaoshuo.Type = RecommendTypeEnum.xiaoshuo.ToString();
- //int index = 0;
- //MiaoYuCache.CharacterList.ForEach(x =>
- //{
- // if (index > 5)
- // {
- // return;
- // }
- // var data = Mapper.Map(x);
- // data.ActionType = RecommendActionTypeEnum.Chat.ToString();
- // data.ActionId = data.Id.ToString();
- // data.ImageUrl = x.BgImage;//data.BgImage;
-
- // tuijian.Data.Add(data);
- // xiaoshuo.Data.Add(data);
- // index++;
- //});
- //recommendDtos.Add(tuijian);
- //recommendDtos.Add(xiaoshuo);
- //#endregion
return new BaseResponse>>(ResonseCode.Success, "", recommendDtos);
}
}
diff --git a/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs b/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs
index 2e511f1..c5db5ac 100644
--- a/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs
+++ b/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs
@@ -64,6 +64,9 @@ builder.Services.AddControllers()
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; // 忽略循环引用
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();// 首字母小写(驼峰样式)
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";// 时间格式化
+ #if !DEBUG
+ options.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.None;
+ #endif
//options.SerializerSettings.Converters.Add()
// 其他配置...
})
@@ -155,7 +158,7 @@ app.UseAuthorization();
//使用跨域
app.UseCors(_myAllowSpecificOrigins);
app.MapControllers();
-
+
app.UseStaticFiles();//静态文件访问配置
//数据库中间件
app.UseMultiTenantMiaoYu();
@@ -187,4 +190,4 @@ app.MapGet("/system", () =>
};
}).WithName("获取系统数据");
#endregion
- app.Run();
+app.Run();
diff --git a/src/9-test/TextCensorFilterTest/SensitiveWordFilterTest.cs b/src/9-test/TextCensorFilterTest/SensitiveWordFilterTest.cs
index 3d398e6..b8f02c1 100644
--- a/src/9-test/TextCensorFilterTest/SensitiveWordFilterTest.cs
+++ b/src/9-test/TextCensorFilterTest/SensitiveWordFilterTest.cs
@@ -14,6 +14,7 @@ namespace TextCensorFilterTest
[MemoryDiagnoser]
public class SensitiveWordFilterTest
{
+
public SensitiveWordFilterTest()
{
string path = "DataStorage/TextCensor/";
@@ -21,22 +22,56 @@ namespace TextCensorFilterTest
{
sensitiveWordFilter = TextCensorExtend.GetSensitiveWordFilter(path);
}
+ if (sensitiveWordFilterFrozen == null)
+ {
+ sensitiveWordFilterFrozen = TextCensorExtend.GetSensitiveWordFilterFrozen(path);
+ }
+
//CheckTextVerification.VerifyTxtString("");
}
- SensitiveWordFilter sensitiveWordFilter = null;
+ SensitiveWordFilter sensitiveWordFilter = null;
+ SensitiveWordFilterFrozen sensitiveWordFilterFrozen = null;
[Benchmark]
public bool SensitiveWordFiltermax()
{
return sensitiveWordFilter.TextCensor("*林婉儿面露疑惑之色,你突然来这么一声问候,实在令她有些摸不着头脑。作为一位淑女,她自是明白礼数之重要性的。见你竟三番两次地打断了她们之间正在深入的对话,不禁蹙起秀眉,神色间略带不悦。* \"阁下这般反复无常,却是何意?\"她语气平和,却不无不满,\"我们方才正在讨论魔兽山脉的来历,你也说了许多让婉儿费解的奇闻逸事。我正渴望能从你这里获知更多有益的解惑呢。\" *她优雅地抿了一口香茶,似在给自己一些缓冲的时间*\"不知阁下可曾见过其他游历山川的高人?他们对于这处所在是否也有过非同寻常的评说?又或是流传下来的什么古老传闻?\" *说着,她的目光缓缓流转,最终重新落在你的身上,眸中满怀期盼之色*\"若阁下实在没什么更多可说的了,不若就让我回忆起从前所读所闻,慢慢为你道来一二吧?或许还能给你带来一些新的启发。\"");
}
-
+ [Benchmark]
+ public bool SensitiveWordFiltermaxs()
+ {
+ var b = false;
+ for (int i = 0; i < 10; i++)
+ {
+ b = sensitiveWordFilter.TextCensor("*林婉儿面露疑惑之色,你突然来这么一声问候,实在令她有些摸不着头脑。作为一位淑女,她自是明白礼数之重要性的。见你竟三番两次地打断了她们之间正在深入的对话,不禁蹙起秀眉,神色间略带不悦。* \"阁下这般反复无常,却是何意?\"她语气平和,却不无不满,\"我们方才正在讨论魔兽山脉的来历,你也说了许多让婉儿费解的奇闻逸事。我正渴望能从你这里获知更多有益的解惑呢。\" *她优雅地抿了一口香茶,似在给自己一些缓冲的时间*\"不知阁下可曾见过其他游历山川的高人?他们对于这处所在是否也有过非同寻常的评说?又或是流传下来的什么古老传闻?\" *说着,她的目光缓缓流转,最终重新落在你的身上,眸中满怀期盼之色*\"若阁下实在没什么更多可说的了,不若就让我回忆起从前所读所闻,慢慢为你道来一二吧?或许还能给你带来一些新的启发。\"");
+ }
+ return b;
+ }
[Benchmark]
public bool SensitiveWordFilter()
{
return sensitiveWordFilter.TextCensor("*林婉儿面露疑惑之色,");
}
+ [Benchmark]
+ public bool SensitiveWordFiltermaxFrozen()
+ {
+ return sensitiveWordFilterFrozen.TextCensor("*林婉儿面露疑惑之色,你突然来这么一声问候,实在令她有些摸不着头脑。作为一位淑女,她自是明白礼数之重要性的。见你竟三番两次地打断了她们之间正在深入的对话,不禁蹙起秀眉,神色间略带不悦。* \"阁下这般反复无常,却是何意?\"她语气平和,却不无不满,\"我们方才正在讨论魔兽山脉的来历,你也说了许多让婉儿费解的奇闻逸事。我正渴望能从你这里获知更多有益的解惑呢。\" *她优雅地抿了一口香茶,似在给自己一些缓冲的时间*\"不知阁下可曾见过其他游历山川的高人?他们对于这处所在是否也有过非同寻常的评说?又或是流传下来的什么古老传闻?\" *说着,她的目光缓缓流转,最终重新落在你的身上,眸中满怀期盼之色*\"若阁下实在没什么更多可说的了,不若就让我回忆起从前所读所闻,慢慢为你道来一二吧?或许还能给你带来一些新的启发。\"");
+ }
-
+ [Benchmark]
+ public bool SensitiveWordFilterFrozen()
+ {
+ return sensitiveWordFilterFrozen.TextCensor("*林婉儿面露疑惑之色,");
+ }
+ [Benchmark]
+ public bool SensitiveWordFilterFrozens()
+ {
+ var b = false;
+ for (int i = 0; i < 10; i++)
+ {
+ b = sensitiveWordFilterFrozen.TextCensor("*林婉儿面露疑惑之色,你突然来这么一声问候,实在令她有些摸不着头脑。作为一位淑女,她自是明白礼数之重要性的。见你竟三番两次地打断了她们之间正在深入的对话,不禁蹙起秀眉,神色间略带不悦。* \"阁下这般反复无常,却是何意?\"她语气平和,却不无不满,\"我们方才正在讨论魔兽山脉的来历,你也说了许多让婉儿费解的奇闻逸事。我正渴望能从你这里获知更多有益的解惑呢。\" *她优雅地抿了一口香茶,似在给自己一些缓冲的时间*\"不知阁下可曾见过其他游历山川的高人?他们对于这处所在是否也有过非同寻常的评说?又或是流传下来的什么古老传闻?\" *说着,她的目光缓缓流转,最终重新落在你的身上,眸中满怀期盼之色*\"若阁下实在没什么更多可说的了,不若就让我回忆起从前所读所闻,慢慢为你道来一二吧?或许还能给你带来一些新的启发。\"");
+ }
+ return b;
+ }
}
}