574 lines
16 KiB
Go
574 lines
16 KiB
Go
// Copyright © 2023 OpenIM open source community. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package chat
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
|
|
"git.imall.cloud/openim/chat/pkg/common/db/table/chat"
|
|
"git.imall.cloud/openim/chat/pkg/common/mctx"
|
|
chatpb "git.imall.cloud/openim/chat/pkg/protocol/chat"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// ==================== 敏感词管理相关 RPC ====================
|
|
|
|
// AddSensitiveWord 添加敏感词
|
|
func (o *chatSvr) AddSensitiveWord(ctx context.Context, req *chatpb.AddSensitiveWordReq) (*chatpb.AddSensitiveWordResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 创建敏感词对象
|
|
word := &chat.SensitiveWord{
|
|
ID: uuid.New().String(),
|
|
Word: req.Word,
|
|
Level: req.Level,
|
|
Type: req.Type,
|
|
Action: req.Action,
|
|
Status: req.Status,
|
|
Creator: getAdminUserID(ctx),
|
|
Updater: getAdminUserID(ctx),
|
|
CreateTime: time.Now(),
|
|
UpdateTime: time.Now(),
|
|
Remark: req.Remark,
|
|
}
|
|
|
|
// 保存到数据库
|
|
err := o.Database.CreateSensitiveWord(ctx, word)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.AddSensitiveWordResp{}, nil
|
|
}
|
|
|
|
// UpdateSensitiveWord 更新敏感词
|
|
func (o *chatSvr) UpdateSensitiveWord(ctx context.Context, req *chatpb.UpdateSensitiveWordReq) (*chatpb.UpdateSensitiveWordResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 构建更新数据
|
|
data := make(map[string]any)
|
|
if req.Word != "" {
|
|
data["word"] = req.Word
|
|
}
|
|
if req.Level > 0 {
|
|
data["level"] = req.Level
|
|
}
|
|
if req.Type > 0 {
|
|
data["type"] = req.Type
|
|
}
|
|
if req.Action > 0 {
|
|
data["action"] = req.Action
|
|
}
|
|
if req.Status >= 0 {
|
|
data["status"] = req.Status
|
|
}
|
|
if req.Remark != "" {
|
|
data["remark"] = req.Remark
|
|
}
|
|
data["updater"] = getAdminUserID(ctx)
|
|
|
|
// 更新数据库
|
|
err := o.Database.UpdateSensitiveWord(ctx, req.Id, data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.UpdateSensitiveWordResp{}, nil
|
|
}
|
|
|
|
// DeleteSensitiveWord 删除敏感词
|
|
func (o *chatSvr) DeleteSensitiveWord(ctx context.Context, req *chatpb.DeleteSensitiveWordReq) (*chatpb.DeleteSensitiveWordResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 删除数据
|
|
err := o.Database.DeleteSensitiveWord(ctx, req.Ids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.DeleteSensitiveWordResp{}, nil
|
|
}
|
|
|
|
// GetSensitiveWord 获取敏感词
|
|
func (o *chatSvr) GetSensitiveWord(ctx context.Context, req *chatpb.GetSensitiveWordReq) (*chatpb.GetSensitiveWordResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 查询数据
|
|
word, err := o.Database.GetSensitiveWord(ctx, req.Id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.GetSensitiveWordResp{
|
|
Word: convertToSensitiveWordDetailInfo(word),
|
|
}, nil
|
|
}
|
|
|
|
// SearchSensitiveWords 搜索敏感词
|
|
func (o *chatSvr) SearchSensitiveWords(ctx context.Context, req *chatpb.SearchSensitiveWordsReq) (*chatpb.SearchSensitiveWordsResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 搜索数据
|
|
total, words, err := o.Database.SearchSensitiveWords(ctx, req.Keyword, req.Action, req.Status, req.Pagination)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 转换结果
|
|
var wordInfos []*chatpb.SensitiveWordDetailInfo
|
|
for _, word := range words {
|
|
wordInfos = append(wordInfos, convertToSensitiveWordDetailInfo(word))
|
|
}
|
|
|
|
return &chatpb.SearchSensitiveWordsResp{
|
|
Total: uint32(total),
|
|
Words: wordInfos,
|
|
}, nil
|
|
}
|
|
|
|
// BatchAddSensitiveWords 批量添加敏感词
|
|
func (o *chatSvr) BatchAddSensitiveWords(ctx context.Context, req *chatpb.BatchAddSensitiveWordsReq) (*chatpb.BatchAddSensitiveWordsResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 转换为数据库模型
|
|
var words []*chat.SensitiveWord
|
|
now := time.Now()
|
|
adminID := getAdminUserID(ctx)
|
|
for _, wordInfo := range req.Words {
|
|
words = append(words, &chat.SensitiveWord{
|
|
ID: uuid.New().String(),
|
|
Word: wordInfo.Word,
|
|
Level: wordInfo.Level,
|
|
Type: wordInfo.Type,
|
|
Action: wordInfo.Action,
|
|
Status: wordInfo.Status,
|
|
Creator: adminID,
|
|
Updater: adminID,
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
Remark: wordInfo.Remark,
|
|
})
|
|
}
|
|
|
|
// 批量保存
|
|
err := o.Database.BatchAddSensitiveWords(ctx, words)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.BatchAddSensitiveWordsResp{}, nil
|
|
}
|
|
|
|
// BatchUpdateSensitiveWords 批量更新敏感词
|
|
func (o *chatSvr) BatchUpdateSensitiveWords(ctx context.Context, req *chatpb.BatchUpdateSensitiveWordsReq) (*chatpb.BatchUpdateSensitiveWordsResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 转换为数据库模型
|
|
updates := make(map[string]map[string]any)
|
|
adminID := getAdminUserID(ctx)
|
|
for id, wordInfo := range req.Updates {
|
|
data := make(map[string]any)
|
|
if wordInfo.Word != "" {
|
|
data["word"] = wordInfo.Word
|
|
}
|
|
if wordInfo.Level > 0 {
|
|
data["level"] = wordInfo.Level
|
|
}
|
|
if wordInfo.Type > 0 {
|
|
data["type"] = wordInfo.Type
|
|
}
|
|
if wordInfo.Action > 0 {
|
|
data["action"] = wordInfo.Action
|
|
}
|
|
if wordInfo.Status >= 0 {
|
|
data["status"] = wordInfo.Status
|
|
}
|
|
if wordInfo.Remark != "" {
|
|
data["remark"] = wordInfo.Remark
|
|
}
|
|
data["updater"] = adminID
|
|
updates[id] = data
|
|
}
|
|
|
|
// 批量更新
|
|
err := o.Database.BatchUpdateSensitiveWords(ctx, updates)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.BatchUpdateSensitiveWordsResp{}, nil
|
|
}
|
|
|
|
// BatchDeleteSensitiveWords 批量删除敏感词
|
|
func (o *chatSvr) BatchDeleteSensitiveWords(ctx context.Context, req *chatpb.BatchDeleteSensitiveWordsReq) (*chatpb.BatchDeleteSensitiveWordsResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 批量删除
|
|
err := o.Database.BatchDeleteSensitiveWords(ctx, req.Ids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.BatchDeleteSensitiveWordsResp{}, nil
|
|
}
|
|
|
|
// ==================== 敏感词分组管理相关 RPC ====================
|
|
|
|
// AddSensitiveWordGroup 添加敏感词分组
|
|
func (o *chatSvr) AddSensitiveWordGroup(ctx context.Context, req *chatpb.AddSensitiveWordGroupReq) (*chatpb.AddSensitiveWordGroupResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 创建分组对象
|
|
group := &chat.SensitiveWordGroup{
|
|
ID: primitive.NewObjectID(),
|
|
Name: req.Name,
|
|
Remark: req.Remark,
|
|
CreateTime: time.Now(),
|
|
UpdateTime: time.Now(),
|
|
}
|
|
|
|
// 保存到数据库
|
|
err := o.Database.CreateSensitiveWordGroup(ctx, group)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.AddSensitiveWordGroupResp{}, nil
|
|
}
|
|
|
|
// UpdateSensitiveWordGroup 更新敏感词分组
|
|
func (o *chatSvr) UpdateSensitiveWordGroup(ctx context.Context, req *chatpb.UpdateSensitiveWordGroupReq) (*chatpb.UpdateSensitiveWordGroupResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 构建更新数据
|
|
data := make(map[string]any)
|
|
if req.Name != "" {
|
|
data["name"] = req.Name
|
|
}
|
|
if req.Remark != "" {
|
|
data["remark"] = req.Remark
|
|
}
|
|
|
|
// 更新数据库
|
|
err := o.Database.UpdateSensitiveWordGroup(ctx, req.Id, data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.UpdateSensitiveWordGroupResp{}, nil
|
|
}
|
|
|
|
// DeleteSensitiveWordGroup 删除敏感词分组
|
|
func (o *chatSvr) DeleteSensitiveWordGroup(ctx context.Context, req *chatpb.DeleteSensitiveWordGroupReq) (*chatpb.DeleteSensitiveWordGroupResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 删除数据
|
|
err := o.Database.DeleteSensitiveWordGroup(ctx, req.Ids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.DeleteSensitiveWordGroupResp{}, nil
|
|
}
|
|
|
|
// GetSensitiveWordGroup 获取敏感词分组
|
|
func (o *chatSvr) GetSensitiveWordGroup(ctx context.Context, req *chatpb.GetSensitiveWordGroupReq) (*chatpb.GetSensitiveWordGroupResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 查询数据
|
|
group, err := o.Database.GetSensitiveWordGroup(ctx, req.Id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.GetSensitiveWordGroupResp{
|
|
Group: convertToSensitiveWordGroupInfo(group),
|
|
}, nil
|
|
}
|
|
|
|
// GetAllSensitiveWordGroups 获取所有敏感词分组
|
|
func (o *chatSvr) GetAllSensitiveWordGroups(ctx context.Context, req *chatpb.GetAllSensitiveWordGroupsReq) (*chatpb.GetAllSensitiveWordGroupsResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 查询数据
|
|
groups, err := o.Database.GetAllSensitiveWordGroups(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 转换结果
|
|
var groupInfos []*chatpb.SensitiveWordGroupInfo
|
|
for _, group := range groups {
|
|
groupInfos = append(groupInfos, convertToSensitiveWordGroupInfo(group))
|
|
}
|
|
|
|
return &chatpb.GetAllSensitiveWordGroupsResp{
|
|
Groups: groupInfos,
|
|
}, nil
|
|
}
|
|
|
|
// ==================== 敏感词配置管理相关 RPC ====================
|
|
|
|
// GetSensitiveWordConfig 获取敏感词配置
|
|
func (o *chatSvr) GetSensitiveWordConfig(ctx context.Context, req *chatpb.GetSensitiveWordConfigReq) (*chatpb.GetSensitiveWordConfigResp, error) {
|
|
fmt.Println("GetSensitiveWordConfig", "_________11", req)
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
fmt.Println("GetSensitiveWordConfig", "_________22", err)
|
|
return nil, err
|
|
}
|
|
fmt.Println("GetSensitiveWordConfig", "_________33")
|
|
// 查询数据
|
|
config, err := o.Database.GetSensitiveWordConfig(ctx)
|
|
if err != nil {
|
|
fmt.Println("GetSensitiveWordConfig", "_________44", err)
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.GetSensitiveWordConfigResp{
|
|
Config: convertToSensitiveWordConfigInfo(config),
|
|
}, nil
|
|
}
|
|
|
|
// UpdateSensitiveWordConfig 更新敏感词配置
|
|
func (o *chatSvr) UpdateSensitiveWordConfig(ctx context.Context, req *chatpb.UpdateSensitiveWordConfigReq) (*chatpb.UpdateSensitiveWordConfigResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 转换为数据库模型
|
|
config := &chat.SensitiveWordConfig{
|
|
ID: req.Config.Id,
|
|
EnableFilter: req.Config.EnableFilter,
|
|
FilterMode: req.Config.FilterMode,
|
|
ReplaceChar: req.Config.ReplaceChar,
|
|
WhitelistUsers: req.Config.WhitelistUsers,
|
|
WhitelistGroups: req.Config.WhitelistGroups,
|
|
LogEnabled: req.Config.LogEnabled,
|
|
AutoApprove: req.Config.AutoApprove,
|
|
UpdateTime: time.Now(),
|
|
}
|
|
|
|
// 更新数据库
|
|
err := o.Database.UpdateSensitiveWordConfig(ctx, config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.UpdateSensitiveWordConfigResp{}, nil
|
|
}
|
|
|
|
// ==================== 敏感词日志管理相关 RPC ====================
|
|
|
|
// GetSensitiveWordLogs 获取敏感词日志
|
|
func (o *chatSvr) GetSensitiveWordLogs(ctx context.Context, req *chatpb.GetSensitiveWordLogsReq) (*chatpb.GetSensitiveWordLogsResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 查询数据
|
|
total, logs, err := o.Database.GetSensitiveWordLogs(ctx, req.UserId, req.GroupId, req.Pagination)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 转换结果
|
|
var logInfos []*chatpb.SensitiveWordLogInfo
|
|
for _, log := range logs {
|
|
logInfos = append(logInfos, convertToSensitiveWordLogInfo(log))
|
|
}
|
|
|
|
return &chatpb.GetSensitiveWordLogsResp{
|
|
Total: uint32(total),
|
|
Logs: logInfos,
|
|
}, nil
|
|
}
|
|
|
|
// DeleteSensitiveWordLogs 删除敏感词日志
|
|
func (o *chatSvr) DeleteSensitiveWordLogs(ctx context.Context, req *chatpb.DeleteSensitiveWordLogsReq) (*chatpb.DeleteSensitiveWordLogsResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 删除数据
|
|
err := o.Database.DeleteSensitiveWordLogs(ctx, req.Ids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.DeleteSensitiveWordLogsResp{}, nil
|
|
}
|
|
|
|
// ==================== 敏感词统计相关 RPC ====================
|
|
|
|
// GetSensitiveWordStats 获取敏感词统计
|
|
func (o *chatSvr) GetSensitiveWordStats(ctx context.Context, req *chatpb.GetSensitiveWordStatsReq) (*chatpb.GetSensitiveWordStatsResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 查询数据
|
|
stats, err := o.Database.GetSensitiveWordStats(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.GetSensitiveWordStatsResp{
|
|
Stats: &chatpb.SensitiveWordStatsInfo{
|
|
Total: stats["total"],
|
|
Enabled: stats["enabled"],
|
|
Disabled: stats["disabled"],
|
|
Replace: stats["replace"],
|
|
Block: stats["block"],
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// GetSensitiveWordLogStats 获取敏感词日志统计
|
|
func (o *chatSvr) GetSensitiveWordLogStats(ctx context.Context, req *chatpb.GetSensitiveWordLogStatsReq) (*chatpb.GetSensitiveWordLogStatsResp, error) {
|
|
// 检查管理员权限
|
|
if _, err := mctx.CheckAdmin(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 查询数据
|
|
startTime := time.Unix(req.StartTime, 0)
|
|
endTime := time.Unix(req.EndTime, 0)
|
|
stats, err := o.Database.GetSensitiveWordLogStats(ctx, startTime, endTime)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chatpb.GetSensitiveWordLogStatsResp{
|
|
Stats: &chatpb.SensitiveWordLogStatsInfo{
|
|
Total: stats["total"],
|
|
Replace: stats["replace"],
|
|
Block: stats["block"],
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// ==================== 辅助函数 ====================
|
|
|
|
// getAdminUserID 获取当前管理员用户ID
|
|
func getAdminUserID(ctx context.Context) string {
|
|
userID, _ := mctx.CheckAdmin(ctx)
|
|
return userID
|
|
}
|
|
|
|
// convertToSensitiveWordDetailInfo 转换为敏感词详细信息
|
|
func convertToSensitiveWordDetailInfo(word *chat.SensitiveWord) *chatpb.SensitiveWordDetailInfo {
|
|
return &chatpb.SensitiveWordDetailInfo{
|
|
Id: word.ID,
|
|
Word: word.Word,
|
|
Level: word.Level,
|
|
Type: word.Type,
|
|
Action: word.Action,
|
|
Status: word.Status,
|
|
Creator: word.Creator,
|
|
Updater: word.Updater,
|
|
CreateTime: word.CreateTime.UnixMilli(),
|
|
UpdateTime: word.UpdateTime.UnixMilli(),
|
|
Remark: word.Remark,
|
|
}
|
|
}
|
|
|
|
// convertToSensitiveWordGroupInfo 转换为敏感词分组信息
|
|
func convertToSensitiveWordGroupInfo(group *chat.SensitiveWordGroup) *chatpb.SensitiveWordGroupInfo {
|
|
return &chatpb.SensitiveWordGroupInfo{
|
|
Id: group.ID.Hex(),
|
|
Name: group.Name,
|
|
Remark: group.Remark,
|
|
CreateTime: group.CreateTime.UnixMilli(),
|
|
UpdateTime: group.UpdateTime.UnixMilli(),
|
|
}
|
|
}
|
|
|
|
// convertToSensitiveWordConfigInfo 转换为敏感词配置信息
|
|
func convertToSensitiveWordConfigInfo(config *chat.SensitiveWordConfig) *chatpb.SensitiveWordConfigInfo {
|
|
return &chatpb.SensitiveWordConfigInfo{
|
|
Id: config.ID,
|
|
EnableFilter: config.EnableFilter,
|
|
FilterMode: config.FilterMode,
|
|
ReplaceChar: config.ReplaceChar,
|
|
WhitelistUsers: config.WhitelistUsers,
|
|
WhitelistGroups: config.WhitelistGroups,
|
|
LogEnabled: config.LogEnabled,
|
|
AutoApprove: config.AutoApprove,
|
|
UpdateTime: config.UpdateTime.UnixMilli(),
|
|
}
|
|
}
|
|
|
|
// convertToSensitiveWordLogInfo 转换为敏感词日志信息
|
|
func convertToSensitiveWordLogInfo(log *chat.SensitiveWordLog) *chatpb.SensitiveWordLogInfo {
|
|
return &chatpb.SensitiveWordLogInfo{
|
|
Id: log.ID.Hex(),
|
|
UserId: log.UserID,
|
|
GroupId: log.GroupID,
|
|
Content: log.Content,
|
|
MatchedWords: log.MatchedWords,
|
|
Action: log.Action,
|
|
ProcessedText: log.ProcessedText,
|
|
CreateTime: log.CreateTime.UnixMilli(),
|
|
}
|
|
}
|