feat: 异步校验社区post文本内容是否违规
This commit is contained in:
@@ -12,6 +12,7 @@ type ApiGroup struct {
|
|||||||
LevelConfigApi
|
LevelConfigApi
|
||||||
UserProfileApi
|
UserProfileApi
|
||||||
BadgeConfigApi
|
BadgeConfigApi
|
||||||
|
CallbackApi
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -24,4 +25,5 @@ var (
|
|||||||
levelConfigService = service.GroupApp.PlantServiceGroup.LevelConfigService
|
levelConfigService = service.GroupApp.PlantServiceGroup.LevelConfigService
|
||||||
userProfileService = service.GroupApp.PlantServiceGroup.UserProfileService
|
userProfileService = service.GroupApp.PlantServiceGroup.UserProfileService
|
||||||
badgeConfigService = service.GroupApp.PlantServiceGroup.BadgeConfigService
|
badgeConfigService = service.GroupApp.PlantServiceGroup.BadgeConfigService
|
||||||
|
callbackService = service.GroupApp.PlantServiceGroup.CallbackService
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ func MigrateTable() {
|
|||||||
plant.CareTask{}, //植物养护任务
|
plant.CareTask{}, //植物养护任务
|
||||||
plant.CareRecord{}, //植物养护记录
|
plant.CareRecord{}, //植物养护记录
|
||||||
plant.GrowthRecord{}, //植物成长记录
|
plant.GrowthRecord{}, //植物成长记录
|
||||||
|
plant.MediaCheckResult{}, //媒体安全检测结果
|
||||||
plant.Topic{}, //帖子话题
|
plant.Topic{}, //帖子话题
|
||||||
plant.Post{}, //帖子
|
plant.Post{}, //帖子
|
||||||
plant.PostLike{}, //帖子点赞
|
plant.PostLike{}, //帖子点赞
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ func Routers() {
|
|||||||
{
|
{
|
||||||
//无须鉴权的路由
|
//无须鉴权的路由
|
||||||
systemRouter.InitAuthRouter(PublicGroup) //登录不需要鉴权
|
systemRouter.InitAuthRouter(PublicGroup) //登录不需要鉴权
|
||||||
|
plantGroup.InitCallbackRouter(PublicGroup) // 回调
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type Post struct {
|
|||||||
LikeCount int `json:"likeCount" form:"likeCount" gorm:"default:0;column:like_count;comment:点赞次数"`
|
LikeCount int `json:"likeCount" form:"likeCount" gorm:"default:0;column:like_count;comment:点赞次数"`
|
||||||
StarCount int `json:"starCount" form:"starCount" gorm:"default:0;column:star_count;comment:收藏次数"`
|
StarCount int `json:"starCount" form:"starCount" gorm:"default:0;column:star_count;comment:收藏次数"`
|
||||||
Location string `json:"location" form:"location" gorm:"column:location;size:100;comment:位置"`
|
Location string `json:"location" form:"location" gorm:"column:location;size:100;comment:位置"`
|
||||||
HasReviewed int `json:"hasReviewed" form:"hasReviewed" gorm:"column:has_reviewed;default:0;comment:是否审核通过"`
|
HasReviewed int `json:"hasReviewed" form:"hasReviewed" gorm:"column:has_reviewed;default:0;comment:是否审核通过"` // 0-未审核 1-审核通过 2-违规
|
||||||
HasLiked int `json:"hasLiked" form:"hasLiked" gorm:"-"`
|
HasLiked int `json:"hasLiked" form:"hasLiked" gorm:"-"`
|
||||||
HasStar int `json:"hasStar" form:"hasStar" gorm:"-"`
|
HasStar int `json:"hasStar" form:"hasStar" gorm:"-"`
|
||||||
//图片
|
//图片
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ type RouterGroup struct {
|
|||||||
LevelConfigRouter
|
LevelConfigRouter
|
||||||
BadgeConfigRouter
|
BadgeConfigRouter
|
||||||
UserProfileRouter
|
UserProfileRouter
|
||||||
|
CallbackRouter
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化路由
|
// 初始化路由
|
||||||
@@ -25,4 +26,5 @@ var (
|
|||||||
levelConfigApi = v1.ApiGroupApp.PlantApiGroup.LevelConfigApi
|
levelConfigApi = v1.ApiGroupApp.PlantApiGroup.LevelConfigApi
|
||||||
userProfileApi = v1.ApiGroupApp.PlantApiGroup.UserProfileApi
|
userProfileApi = v1.ApiGroupApp.PlantApiGroup.UserProfileApi
|
||||||
badgeConfigApi = v1.ApiGroupApp.PlantApiGroup.BadgeConfigApi
|
badgeConfigApi = v1.ApiGroupApp.PlantApiGroup.BadgeConfigApi
|
||||||
|
callbackApi = v1.ApiGroupApp.PlantApiGroup.CallbackApi
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ type ServiceGroup struct {
|
|||||||
LevelConfigService
|
LevelConfigService
|
||||||
BadgeConfigService
|
BadgeConfigService
|
||||||
UserProfileService
|
UserProfileService
|
||||||
|
CallbackService
|
||||||
}
|
}
|
||||||
|
|||||||
+91
-2
@@ -6,7 +6,11 @@ import (
|
|||||||
plantReq "sundynix-go/model/plant/request"
|
plantReq "sundynix-go/model/plant/request"
|
||||||
"sundynix-go/model/system"
|
"sundynix-go/model/system"
|
||||||
|
|
||||||
|
"sundynix-go/utils/wechat"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PostService struct{}
|
type PostService struct{}
|
||||||
@@ -15,9 +19,11 @@ var PostServiceApp = new(PostService)
|
|||||||
|
|
||||||
// PublishPost 发表帖子
|
// PublishPost 发表帖子
|
||||||
func (s *PostService) PublishPost(req plantReq.CreatePost, userId string) error {
|
func (s *PostService) PublishPost(req plantReq.CreatePost, userId string) error {
|
||||||
return global.DB.Transaction(func(tx *gorm.DB) error {
|
var postId string
|
||||||
//1.验证oss是否存在
|
|
||||||
var ossList []*system.Oss
|
var ossList []*system.Oss
|
||||||
|
|
||||||
|
err := global.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
//1.验证oss是否存在
|
||||||
err := tx.Where("id in ?", req.OssIds).Find(&ossList).Error
|
err := tx.Where("id in ?", req.OssIds).Find(&ossList).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -33,6 +39,8 @@ func (s *PostService) PublishPost(req plantReq.CreatePost, userId string) error
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
postId = post.Id
|
||||||
|
|
||||||
//3.处理图片关系
|
//3.处理图片关系
|
||||||
if len(ossList) > 0 {
|
if len(ossList) > 0 {
|
||||||
var relations []map[string]interface{}
|
var relations []map[string]interface{}
|
||||||
@@ -49,6 +57,87 @@ func (s *PostService) PublishPost(req plantReq.CreatePost, userId string) error
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.异步内容安全检查
|
||||||
|
// 4.异步内容安全检查
|
||||||
|
go func(pid, uid, title, content string, imgs []*system.Oss) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
global.Logger.Error("异步内容安全检查Panic", zap.Any("panic", r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// 获取用户 openid
|
||||||
|
var user system.User
|
||||||
|
if err := global.DB.Where("id = ?", uid).First(&user).Error; err != nil {
|
||||||
|
global.Logger.Error("获取用户失败,跳过安全检查", zap.String("userId", uid), zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
openid := user.MiniOpenId
|
||||||
|
if openid == "" {
|
||||||
|
global.Logger.Warn("用户无MiniOpenId,跳过安全检查", zap.String("userId", uid))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文本检查
|
||||||
|
fullContent := title + "\n" + content
|
||||||
|
isSafe := wechat.MsgSecCheck(fullContent, openid)
|
||||||
|
|
||||||
|
// 文本违规 -> 直接拒绝
|
||||||
|
if !isSafe {
|
||||||
|
if err := global.DB.Model(&plant.Post{}).Where("id = ?", pid).Update("has_reviewed", 2).Error; err != nil {
|
||||||
|
global.Logger.Error("更新帖子违规状态失败", zap.String("postId", pid), zap.Error(err))
|
||||||
|
}
|
||||||
|
global.Logger.Info("帖子内容违规,已标记", zap.String("postId", pid))
|
||||||
|
return // 文本违规,无需再检查图片
|
||||||
|
}
|
||||||
|
if err := global.DB.Model(&plant.Post{}).Where("id = ?", pid).Update("has_reviewed", 1).Error; err != nil {
|
||||||
|
global.Logger.Error("更新帖子违规状态失败", zap.String("postId", pid), zap.Error(err))
|
||||||
|
}
|
||||||
|
return // 文本违规,无需再检查图片
|
||||||
|
|
||||||
|
// 文本通过,判断是否有图片
|
||||||
|
//if len(imgs) == 0 {
|
||||||
|
// // 无图且文本通过 -> 直接通过
|
||||||
|
// if err := global.DB.Model(&plant.Post{}).Where("id = ?", pid).Update("has_reviewed", 1).Error; err != nil {
|
||||||
|
// global.Logger.Error("更新帖子通过状态失败", zap.String("postId", pid), zap.Error(err))
|
||||||
|
// }
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
|
// 有图,文本通过 -> 保持状态为0(待审核),等待图片回调
|
||||||
|
|
||||||
|
// todo 图片检查
|
||||||
|
//for _, oss := range imgs {
|
||||||
|
// // 假设 oss.Url 是完整链接
|
||||||
|
// traceId, err := wechat.MediaCheckAsync(oss.Url, 2, openid)
|
||||||
|
// if err != nil {
|
||||||
|
// global.Logger.Error("图片安全检查请求失败", zap.String("url", oss.Url), zap.Error(err))
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// global.Logger.Info("图片安全检查请求成功", zap.String("traceId", traceId))
|
||||||
|
//
|
||||||
|
// // 保存检测记录
|
||||||
|
// checkResult := plant.MediaCheckResult{
|
||||||
|
// TraceId: traceId,
|
||||||
|
// PostId: pid,
|
||||||
|
// OssId: oss.Id,
|
||||||
|
// UserId: uid,
|
||||||
|
// Status: 0, // 检测中
|
||||||
|
// Type: 2, // 图片
|
||||||
|
// }
|
||||||
|
// if err := global.DB.Create(&checkResult).Error; err != nil {
|
||||||
|
// global.Logger.Error("保存媒体检测记录失败", zap.Error(err))
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
}(postId, userId, req.Title, req.Content, ossList)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostPage 帖子列表
|
// PostPage 帖子列表
|
||||||
|
|||||||
Reference in New Issue
Block a user