Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+348
View File
@@ -0,0 +1,348 @@
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
}