feat: Add callback and exchange features, refactor care plan task generation logic, and update wiki ordering to prioritize hot items.

This commit is contained in:
Blizzard
2026-02-26 08:57:13 +08:00
parent 9d4a5c6375
commit 3f05dccdce
23 changed files with 955 additions and 56 deletions
+110
View File
@@ -0,0 +1,110 @@
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
})
}