yidun送检新增账户下拉和导出优化
This commit is contained in:
@@ -656,6 +656,140 @@ func (s *MaterialVerifyService) PollPendingVideoResults(ctx context.Context) (in
|
||||
return s.PollPendingResultsByType(ctx, consts.SourceTableTencentVideo)
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 导出服务 - 不通过数据导出
|
||||
// =============================================================================
|
||||
|
||||
// ExportRejectedItem 导出的不通过数据项
|
||||
type ExportRejectedItem struct {
|
||||
ID int64 `json:"id"` // 素材表主键ID
|
||||
MaterialID string `json:"materialId"` // 素材ID(imageId/videoId)
|
||||
AccountID int64 `json:"accountId"` // 账户ID
|
||||
CorporationName string `json:"corporationName"` // 公司名称
|
||||
PreviewURL string `json:"previewUrl"` // 预览URL
|
||||
Description string `json:"description"` // 描述
|
||||
ErrorMsg string `json:"errorMsg"` // 失败原因(最后一条失败日志的error_msg)
|
||||
MaterialType string `json:"materialType"` // 素材类型 IMAGE/VIDEO
|
||||
ImageUsage string `json:"imageUsage"` // 图片用途(仅图片)
|
||||
CreatedAt string `json:"createdAt"` // 检测时间(日志创建时间)
|
||||
}
|
||||
|
||||
// getFailureReason 获取失败原因
|
||||
func getFailureReason(log *entity.MaterialVerifyLog) string {
|
||||
if log == nil {
|
||||
return "无校验日志"
|
||||
}
|
||||
// 优先使用 error_msg
|
||||
if log.ErrorMsg != "" {
|
||||
return log.ErrorMsg
|
||||
}
|
||||
// 根据 suggestion 和 label 生成原因
|
||||
reasonMap := map[int]string{
|
||||
0: "内容检测通过",
|
||||
1: "内容嫌疑(需人工审核)",
|
||||
2: "内容不通过",
|
||||
}
|
||||
suggestionText := reasonMap[log.Suggestion]
|
||||
if suggestionText == "" {
|
||||
suggestionText = fmt.Sprintf("未知(suggestion=%d)", log.Suggestion)
|
||||
}
|
||||
// 如果有 response_result,尝试提取更多信息
|
||||
if log.ResponseResult != "" {
|
||||
var resultMap map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(log.ResponseResult), &resultMap); err == nil {
|
||||
if labels, ok := resultMap["labels"]; ok {
|
||||
return fmt.Sprintf("%s (labels: %v)", suggestionText, labels)
|
||||
}
|
||||
}
|
||||
return suggestionText
|
||||
}
|
||||
return suggestionText
|
||||
}
|
||||
|
||||
// ExportRejectedData 导出不通过数据
|
||||
func (s *MaterialVerifyService) ExportRejectedData(ctx context.Context, materialType string) ([]ExportRejectedItem, error) {
|
||||
var items []ExportRejectedItem
|
||||
|
||||
// 加载账户名称映射
|
||||
accountMap := make(map[int64]string)
|
||||
if accounts, err := dao.TencentAccountRelation.GetAll(ctx); err == nil {
|
||||
for _, acc := range accounts {
|
||||
if acc.CorporationName != "" {
|
||||
accountMap[acc.AccountID] = acc.CorporationName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理图片
|
||||
if materialType == "" || materialType == entity.MaterialTypeImage {
|
||||
condition := map[string]interface{}{
|
||||
entity.TencentImageCols.VerifyStatus: entity.VerifyStatusRejected,
|
||||
}
|
||||
images, total, err := dao.TencentImage.GetByCondition(ctx, condition, 1, 100000)
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "查询不通过图片失败: %v", err)
|
||||
return nil, fmt.Errorf("查询不通过图片失败: %w", err)
|
||||
}
|
||||
g.Log().Infof(ctx, "导出不通过图片: total=%d, got=%d", total, len(images))
|
||||
|
||||
for _, img := range images {
|
||||
// 查询最后一条失败的校验日志
|
||||
log, _ := dao.MaterialVerifyLog.GetLastRejectedLogByMaterialID(ctx, img.ImageID, entity.VerifyStatusRejected)
|
||||
var createdAtStr string
|
||||
if log != nil && log.CreatedAt != nil {
|
||||
createdAtStr = log.CreatedAt.Format("Y-m-d H:i:s")
|
||||
}
|
||||
items = append(items, ExportRejectedItem{
|
||||
ID: img.Id,
|
||||
MaterialID: img.ImageID,
|
||||
AccountID: img.AccountID,
|
||||
CorporationName: accountMap[img.AccountID],
|
||||
PreviewURL: img.PreviewURL,
|
||||
Description: img.Description,
|
||||
ErrorMsg: getFailureReason(log),
|
||||
MaterialType: entity.MaterialTypeImage,
|
||||
ImageUsage: img.ImageUsage,
|
||||
CreatedAt: createdAtStr,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 处理视频
|
||||
if materialType == "" || materialType == entity.MaterialTypeVideo {
|
||||
condition := map[string]interface{}{
|
||||
entity.TencentVideoCols.VerifyStatus: entity.VerifyStatusRejected,
|
||||
}
|
||||
videos, total, err := dao.TencentVideo.GetByCondition(ctx, condition, 1, 100000)
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "查询不通过视频失败: %v", err)
|
||||
return nil, fmt.Errorf("查询不通过视频失败: %w", err)
|
||||
}
|
||||
g.Log().Infof(ctx, "导出不通过视频: total=%d, got=%d", total, len(videos))
|
||||
|
||||
for _, vid := range videos {
|
||||
// 查询最后一条失败的校验日志
|
||||
log, _ := dao.MaterialVerifyLog.GetLastRejectedLogByMaterialID(ctx, vid.VideoID, entity.VerifyStatusRejected)
|
||||
var createdAtStr string
|
||||
if log != nil && log.CreatedAt != nil {
|
||||
createdAtStr = log.CreatedAt.Format("Y-m-d H:i:s")
|
||||
}
|
||||
items = append(items, ExportRejectedItem{
|
||||
ID: vid.Id,
|
||||
MaterialID: vid.VideoID,
|
||||
AccountID: vid.AccountID,
|
||||
CorporationName: accountMap[vid.AccountID],
|
||||
PreviewURL: vid.PreviewURL,
|
||||
Description: vid.Description,
|
||||
ErrorMsg: getFailureReason(log),
|
||||
MaterialType: entity.MaterialTypeVideo,
|
||||
CreatedAt: createdAtStr,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
// GetPendingResultsCount 获取待查询结果的数量
|
||||
func (s *MaterialVerifyService) GetPendingResultsCount(ctx context.Context) (int, error) {
|
||||
return dao.MaterialVerifyLog.CountPendingResults(ctx)
|
||||
|
||||
Reference in New Issue
Block a user