package tianyuctrl import ( "91porn-server/common" "91porn-server/common/log" "91porn-server/common/stderr" "91porn-server/models/v/mediacontentmod" "91porn-server/models/v/mediamod" "91porn-server/models/v/mediatagmod" "91porn-server/models/v/usermod" "91porn-server/models/v/vidmod" "91porn-server/web/api/tianyuctrl/proxy" "91porn-server/web/service/vidser" "context" "fmt" "math/rand" "net/http" "strings" "time" "github.com/gin-gonic/gin" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo/options" ) // VideoSearch doc // @Tags 媒体文件 // @Summary 根据参数获取视频文件列表 // @Description 获取视频列表文件 // @Accept json // @Produce json // @Param req body proxy.MediaSearchReq true "参数列表" // @Success 200 {object} proxy.MediaSearchResp "成功" // @Failure 400 {string} string "获取失败的返回结果" // @Router /api/web/admin/tianyu/search [post] func VideoSearch(ctx *gin.Context) { var req proxy.MediaSearchReq if err := ctx.ShouldBind(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, err.Error()) return } videoUploadDomain := proxy.BucketVideoAddressV2 result, err := proxy.PostSearch(&req, videoUploadDomain) if err != nil { common.ServeJSON(ctx, stderr.Failure, err.Error()) return } sourceMediaIds := make([]string, 0) for _, mediaInfo := range result.Data.List { sourceMediaIds = append(sourceMediaIds, mediaInfo.ID.Hex()) } videoList, _ := vidmod.GetList(bson.M{"sourceID": bson.M{"$in": sourceMediaIds}}) if err != nil { log.Error(fmt.Sprintf("mediamod queryAllList error:%+v:", err)) common.ServeJSON(ctx, stderr.Failure, err) return } for _, v := range result.Data.List { if v.Type == "AI" { v.FieldNameFs += ".mp4" } for _, v1 := range videoList { if v.ID.Hex() == v1.SourceID { v.IsAdd = true } } } common.ServeJSON(ctx, stderr.Success, result.Data) } // AddOneMedia doc // @Tags 视频 // @Summary 添加一个视频视频 // @Description 添加一个视频视频 // @Accept json // @Produce json // @Param param body MediaAdd true "参数列表" // @Success 200 {string} string "成功" // @Failure 400 {string} string "获取失败的返回结果" // @Router /api/web/admin/tianyu/add [post] func AddOneMedia(ctx *gin.Context) { var req = &MediaAdd{} if err := ctx.ShouldBind(req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, err) return } manager, err := common.GetAdminAct(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, err.Error()) return } var resp = MediaAddResp{SensitiveHits: make([]vidser.SensitiveHit, 0)} terms := vidser.LoadEnabledSensitiveTerms() for _, s := range req.FileId { in := proxy.MediaQueryeReq{ Id: s, } videoUploadDomain := proxy.BucketVideoAddressV2 result, err := proxy.QueryMedia(&in, videoUploadDomain) if err != nil || result.Code != http.StatusOK { resp.FailCount++ continue } var hit *vidser.SensitiveHit if result.Data.ContentType == 3 { hit, err = AddMedia(ctx, &result.Data, manager, terms) } else { hit, err = AddVideo(ctx, &result.Data, manager, terms) } if err != nil { log.Error(fmt.Sprintf("add tianyu media error:%+v:", err)) resp.FailCount++ continue } if hit != nil { resp.SensitiveHits = append(resp.SensitiveHits, *hit) } resp.SuccessCount++ } if len(resp.SensitiveHits) > 0 { resp.SensitiveTip = vidser.SensitiveForcedOfflineTip } common.ServeJSON(ctx, stderr.Success, resp) } func AddMedia(ctx context.Context, data *proxy.MediaResp, manager string, terms []string) (*vidser.SensitiveHit, error) { now := time.Now() mediaResource, err := mediamod.GetListByLsjId(data.FileId) if err != nil { err = fmt.Errorf("mediamod GetListByLsjId error:%+v", err) return nil, err } if !mediaResource.ID.IsZero() { return nil, nil } tag, err := mediatagmod.FindOneTagOrInset(data.FirstTag) if err != nil { return nil, err } media := mediamod.Media{ ID: primitive.NewObjectID(), LsjId: data.FileId, SortCode: 0, Status: 1, Title: data.Title, HorizontalCover: data.CoverImg, VerticalCover: "", Tags: []primitive.ObjectID{tag.ID}, TagDetails: nil, Summary: data.Desc, TotalEpisode: 1, CurrentEpisode: 1, FreeEpisode: 0, UpdateStatus: 2, MediaType: "video", MediaSubType: 0, Kind: 0, PermissionIconHide: false, Permission: 0, Style: 0, Price: 100, ContentsPrice: 0, Direction: 0, FreeTime: 30, DefaultContent: mediamod.DefaultContent{}, MID: primitive.NilObjectID, ModuleName: "", SectionName: "", SID: primitive.NilObjectID, SectionSort: 0, Choice: primitive.NilObjectID, ChoiceSort: 0, CountComment: 0, CountPurchases: 0, CountContentPurchases: 0, CountBrowse: 0, CountCollect: 0, CountLike: 0, CountDisLike: 0, HasFollow: false, CountView: 0, Hot: 0, Number: 0, Anchor: data.Studio, CountPurchasesRate: 0, IsDelete: false, UpdatedAct: "", CreatedAt: now, UpdateTime: time.Now(), //ContentUpdateTime: time.Time{}, MediaCenterId: 0, SyncTime: 0, } if data.CoverType == 1 { media.VerticalCover = data.CoverImg } // 创建子集 mediaContent := mediacontentmod.MediaContent{ ID: primitive.ObjectID{}, MediaID: media.ID, MediaType: "video", EpisodeNumber: 1, ListenPermission: 0, Cover: data.CoverImg, Price: 100, Name: data.Title, Text: "", Md5: "", AudioUrl: "", Author: "", VideoUrl: strings.TrimSpace(data.FieldNameFs) + ".m3u8", UrlSet: nil, Height: 0, Weight: 0, MediaSize: data.Size, PlayTime: uint(data.VideoTime), Status: 1, IsActive: true, CountComment: 0, CountPurchases: 0, CountBrowse: 0, FakeCountBrowse: 0, CountCollect: 0, CountLike: 0, CountDisLike: 0, Ratio: 0, IsDelete: false, UpdatedAct: "", CreatedAt: time.Now(), HashId: data.FileId, } // 敏感词命中 → 强制下架(Status=0) hit := vidser.CheckTextHits(terms, data.FileId, media.Title, media.Summary, "") if hit != nil { media.Status = 0 log.Warn("tianyu AddMedia sensitive hit, forced offline", log.Any("sourceId", hit.SourceID), log.Any("title", hit.Title), log.Any("detail", hit.Detail)) } // 不处理标签 _, err = mediamod.Insert(nil, media) if err != nil { return nil, err } if _, err = mediacontentmod.Insert(nil, mediaContent); err != nil { return nil, err } return hit, nil } func AddVideo(ctx context.Context, data *proxy.MediaResp, manager string, terms []string) (*vidser.SensitiveHit, error) { now := time.Now() postList, err := vidmod.GetList(bson.M{"sourceID": bson.M{"$in": []string{data.FileId}}}) if err != nil { log.Warn("syncOneMovie GetList failed", log.Any("id", data.FileId), log.E(err)) return nil, err } if postList != nil && len(postList) > 0 { return nil, nil } upUsers, err := usermod.FindMany(bson.M{"uid": bson.M{"$gt": 300000}}, &options.FindOptions{}, 0, 300) if err != nil { log.Warn("PostAddList FindManyUser failed", log.E(err)) return nil, err } vidInfo := vidmod.VideoModel{ ID: primitive.NewObjectID(), Title: data.Title, Content: data.Desc, Tags: make([]primitive.ObjectID, 0), MimeType: "video/mp4", SeriesCover: make([]string, 0), Via: "tianyu", Status: vidmod.CheckPass, Location: primitive.ObjectID{}, Actor: strings.Join(data.Actors, " "), NewUpdatedAt: "tianyu", ReviewAt: now, CreatedAt: now, Cover: data.CoverImg, ReviewAccount: manager, } if data.CoverType == 1 { vidInfo.VerticalCover = data.CoverImg } if data.CoverType == 1 { vidInfo.NewsType = vidmod.SHORT vidInfo.Cover = data.CoverImg vidInfo.CoverThumb = data.CoverImg vidInfo.Direction = "vertical" } else { vidInfo.NewsType = vidmod.SP vidInfo.Cover = data.CoverImg vidInfo.CoverThumb = data.CoverImg vidInfo.Direction = "horizontal" } vidInfo.PlayTime = uint(data.VideoTime) uIndex := rand.Intn(len(upUsers)) u := upUsers[uIndex] vidInfo.PublisherID = u.UID vidInfo.SourceURL = data.FieldNameFs vidInfo.PreviewURL = data.PreFileName vidInfo.SourceID = data.FileId vidInfo.Filename = data.FieldNameFs if !strings.Contains(data.PreFileName, ".m3u8") { vidInfo.SourceURL = strings.TrimSpace(data.PreFileName) + ".m3u8" } if !strings.Contains(data.FieldNameFs, ".m3u8") { vidInfo.SourceURL = strings.TrimSpace(data.FieldNameFs) + ".m3u8" } // 敏感词命中 → 强制为待审核(WaitingCheck=0) hit := vidser.CheckTextHits(terms, data.FileId, vidInfo.Title, vidInfo.Content, "") if hit != nil { vidInfo.Status = vidmod.WaitingCheck log.Warn("tianyu AddVideo sensitive hit, forced offline", log.Any("sourceId", hit.SourceID), log.Any("title", hit.Title), log.Any("detail", hit.Detail)) } // 不处理标签 if _, err = vidmod.InsertBase(vidInfo); err != nil { return nil, err } return hit, nil }