111 lines
3.4 KiB
Go
111 lines
3.4 KiB
Go
package plant
|
|
|
|
import (
|
|
"sundynix-go/global"
|
|
"sundynix-go/model/plant"
|
|
plantres "sundynix-go/model/plant/response"
|
|
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type CallbackService struct{}
|
|
|
|
var CallbackServiceApp = new(CallbackService)
|
|
|
|
// HandleMediaCheckCallback 处理媒体检测回调
|
|
func (s *CallbackService) HandleMediaCheckCallback(cb plantres.WeChatCheckResultCallback) error {
|
|
global.Logger.Info("收到微信媒体检测回调", zap.String("traceId", cb.TraceId), zap.String("suggest", cb.Result.Suggest))
|
|
|
|
var checkResult plant.MediaCheckResult
|
|
err := global.DB.Where("trace_id = ?", cb.TraceId).First(&checkResult).Error
|
|
if err != nil {
|
|
global.Logger.Error("回调traceId未找到", zap.String("traceId", cb.TraceId), zap.Error(err))
|
|
return err
|
|
}
|
|
|
|
// 1. 更新检测结果状态
|
|
status := 0
|
|
if cb.Result.Suggest == "pass" {
|
|
status = 1
|
|
} else {
|
|
status = 2
|
|
}
|
|
|
|
err = global.DB.Model(&checkResult).Updates(map[string]interface{}{
|
|
"status": status,
|
|
"err_msg": cb.Result.Suggest,
|
|
}).Error
|
|
|
|
if err != nil {
|
|
global.Logger.Error("更新检测结果失败", zap.Error(err))
|
|
return err
|
|
}
|
|
|
|
// 2. 根据结果处理帖子状态
|
|
return s.updatePostStatus(checkResult.PostId)
|
|
}
|
|
|
|
// updatePostStatus 更新帖子状态
|
|
// 逻辑:
|
|
// 1. 如果有任意一个检测结果为违规(2) -> 帖子违规(2)
|
|
// 2. 如果所有检测结果都为通过(1) -> 帖子通过(1)
|
|
// 3. 否则保持待审核(0)
|
|
func (s *CallbackService) updatePostStatus(postId string) error {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var post plant.Post
|
|
if err := tx.Where("id = ?", postId).First(&post).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// 如果帖子已经是违规状态,无需再处理(可能之前已经由文本检测判定违规)
|
|
if post.HasReviewed == 2 {
|
|
return nil
|
|
}
|
|
|
|
var results []plant.MediaCheckResult
|
|
if err := tx.Where("post_id = ?", postId).Find(&results).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
hasRisky := false
|
|
allPass := true
|
|
|
|
for _, res := range results {
|
|
if res.Status == 2 {
|
|
hasRisky = true
|
|
break
|
|
}
|
|
if res.Status != 1 {
|
|
allPass = false
|
|
}
|
|
}
|
|
|
|
var newStatus = post.HasReviewed // 默认保持原状态
|
|
|
|
if hasRisky {
|
|
newStatus = 2
|
|
// TODO: 这里可以执行额外的封禁逻辑,例如不仅标记违规,还软删除Oss关联等
|
|
global.Logger.Warn("帖子包含违规图片,标记为违规", zap.String("postId", postId))
|
|
} else if allPass {
|
|
// 只有当所有图片都通过,且原状态不是违规时,才标记为通过
|
|
// 注意:这里假设文本检测已经通过(文本检测是同步的,若不通过早已设为2)
|
|
// 如果文本检测尚未完成(理论上不可能,因为是先文本后图片),这里可能会有竞态,但文本检测在发帖goroutine中是串行的。
|
|
// 唯一需要注意的是,如果文本检测还在进行中,这里不应覆盖。
|
|
// 但我们在PublishPost中是先改HasReviewed再发图片检查。
|
|
// 如果文本通过,HasReviewed会被设为1? 不,根据新逻辑,PublishPost中只有无图才设为1。
|
|
// 有图时,PublishPost中HasReviewed保持0。
|
|
newStatus = 1
|
|
global.Logger.Info("帖子所有图片检测通过,标记为通过", zap.String("postId", postId))
|
|
}
|
|
|
|
if newStatus != post.HasReviewed {
|
|
if err := tx.Model(&post).Update("has_reviewed", newStatus).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|