package vidctrl import ( "91porn-server/models/v/discount_area_mod" "errors" "fmt" "strings" "time" "91porn-server/app/service/m3u8ticket" "91porn-server/app/service/vidser" "91porn-server/common" "91porn-server/common/log" "91porn-server/common/stderr" "91porn-server/middleware/requestid" "91porn-server/models/commod" "91porn-server/models/v/usermod" "91porn-server/models/v/vidmod" "github.com/gin-gonic/gin" "go.mongodb.org/mongo-driver/bson/primitive" ) // GetLocationList doc // @Summary 获取同城视频 // @Description 获取同城视频 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param ip formData string true "用户ip地址" // @Param pageNumber formData integer true "查询页码" // @Param pageSize formData integer true "页码大小" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/vid/location/list [get] func GetLocationList(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } req := vidmod.LocVideoReq{} if err = ctx.ShouldBind(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } if req.PageSize < 1 { req.PageSize = 10 } code, data := vidser.GetLocationList(uid, ctx.ClientIP(), req.City, req.PageNumber, req.PageSize, vidmod.SP) common.ServeJSON(ctx, code, data) } // GetLocationHot doc // @Summary 获取热门城市 // @Description 获取热门城市 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/vid/location/hot [get] func GetLocationHot(ctx *gin.Context) { code, data := vidser.GetLocationHot() common.ServeJSON(ctx, code, data) } // GetVidInfo doc // @Summary 获取视频详情 // @Description 获取视频详情 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param videoID formData string true "视频id" // @Param searchAccessToken query string false "搜索结果返回的短时效访问凭证" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/vid/info [get] func GetVidInfo(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } param := vidmod.VideoReq{} if err = ctx.ShouldBind(¶m); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } if len(param.VideoID) == 0 { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } code, data := vidser.GetInfoWithSearchAccess(uid, param.VideoID, param.SearchAccessToken) // 视频详情:对 m3u8 播放地址签发 H5 防盗链票据 m3u8ticket.Sign(ctx, data) common.ServeJSON(ctx, code, data) } // Submit doc // @Summary 提交视频的基本信息 // @Description 视频基本信息提交 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param uid formData integer false "用户ID" // @Param title formData string false "视频标题" // @Param content formData string false "视频内容" // @Param newsType formData string false "上传类型 COVER-图集 SP-视频" // @Param tags formData array true "视频标签数组" // @Param playTime formData integer false "视频时长" // @Param cover formData string false "封面图" // @Param coverThumb formData string false "小图" // @Param seriesCover formData array false "图集图片地址" // @Param via formData string false "视频来源" // @Param coins formData integer false "观看金币" // @Param size formData integer false "文件大小" // @Param mimeType formData string false "影片类型" // @Param actor formData string false "演员名字" // @Param sourceURL formData string false "资源url 为SP时 必传" // @Param sourceID formData string false "上传视频成功后 返回的ID 为SP时必传" // @Param filename formData string false "文件名" // @Param resolution formData string false "分辨率" // @Param ratio formData number false "视频比列" // @Param md5 formData string false "文件摘要" // @Param freeTime formData integer false "免费观影时长" // @Param location formData string false "地理位置信息" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /vid/submit [post] func Submit(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, err) return } param := vidmod.SubmitReq{} if err = ctx.ShouldBind(¶m); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, err) return } //判断该用户是否被禁止上传视频 user, err := usermod.FindUserByUID(uid) if err != nil || (user != nil && user.ForbidUpload) { common.ServeJSON(ctx, stderr.ForbidUploadVideo, err) return } if param.NewsType == vidmod.COVER || param.NewsType == vidmod.PIC { if user.CoverUploadCount > 3 && !user.IsPaidVIP() { common.ServeJSON(ctx, stderr.NoVipNoUpload, err) return } } else if param.NewsType == vidmod.SP || param.NewsType == vidmod.SHORT { if user.VidUploadCount >= 3 && !user.IsPaidVIP() { common.ServeJSON(ctx, stderr.NoVipNoUpload, err) return } } //默认newsType if len(param.NewsType) == 0 { param.NewsType = vidmod.SP } //图集的第一张放到封面中 if (param.NewsType == vidmod.COVER || param.NewsType == vidmod.PIC) && len(param.SeriesCover) != 0 { param.Cover = param.SeriesCover[0] param.CoverThumb = param.SeriesCover[0] } //免费时长设置,收费视频 if param.Coins > 0 { param.FreeTime = vidmod.GetFreeTime(param.PlayTime) } ip := common.GetIP(ctx) code, vid := vidser.SubmitBase(uid, param, ip) if code != stderr.Success { _, _ = vidser.DeleteManyByTTL(uid, vid) common.ServeJSON(ctx, code, vid) return } n := int64(1) if param.NewsType == vidmod.COVER || param.NewsType == vidmod.PIC { // code = vidser.SendCoverInfo2FS(param) // if code != stderr.Success { // vidser.DeleteManyByTTL(uid, vid) // } _ = usermod.IncUploadCount(uid, usermod.UploadCountInc{ TotalWorks: &n, CoverUploadCount: &n, }) common.ServeJSON(ctx, code, vid) return } if param.NewsType == vidmod.SP || param.NewsType == vidmod.SHORT { _ = usermod.IncUploadCount(uid, usermod.UploadCountInc{ TotalWorks: &n, VidUploadCount: &n, }) } param.SourceID = vid.Hex() code = vidser.SendBaseInfo2FS(param) if code != stderr.Success { _, _ = vidser.DeleteManyByTTL(uid, vid) } common.ServeJSON(ctx, code, vid) } // PlayRecord doc // @Summary 今日热门视频列表 // @Description 今日热门视频列表 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param videoID formData string true "视频id" // @Param beginTime formData string true "开始播放的时间" // @Param endTime formData string true "退出或者跳转到下个视频的时间" // @Param playWay formData integer true "通过什么途径获取视频的 0,免费 1付费 2.试看 " // @Param via formData integer true "视频来源,1.推荐 2.附近 3专题 4搜索 5分享 6热搜 7收藏 8热搜" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/vid/play [post] func PlayRecord(ctx *gin.Context) { uid := common.TryGetUID(ctx) param := vidmod.PlayReq{} if err := ctx.ShouldBind(¶m); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } code, data := vidser.PlayRecord(uid, param) common.ServeJSON(ctx, code, data) } // HotList doc // @Summary 今日最热视频列表 // @Description 今日最热视频列表 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param pageNumber query int true "当前页" // @Param pageSize query int true "每页条数" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /vid/hot/list [get] func HotList(c *gin.Context) { var arg struct { commod.Page } if err := c.ShouldBind(&arg); err != nil { common.ServeJSON(c, stderr.ErrParamError, "vid HotList arg error "+err.Error()) return } uid, err := common.GetUID(c) if err != nil { common.ServeJSON(c, stderr.ErrAccessForbid, err) return } skip := int64((arg.PageNumber - 1) * arg.PageSize) limit := int64(arg.PageSize) list, hasNext, err := vidser.GetHotList(uid, skip, limit) if err != nil { common.ServeJSON(c, stderr.Failure, err) return } common.ServeJSON(c, stderr.Success, gin.H{ "list": list, "hasNext": hasNext, "updatedAt": time.Now().Format("2006-01-02 15:04"), }) } // HotKWList doc // @Summary 热点视频列表 // @Description 热点视频列表 通过搜索量排名高的多个关键字,查询视屏列表 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param pageNumber query int true "当前页" // @Param pageSize query int true "每页条数" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /vid/hotkw/list [get] func HotKWList(c *gin.Context) { var arg struct { commod.Page } if err := c.ShouldBind(&arg); err != nil { common.ServeJSON(c, stderr.ErrParamError, "vid HotKWList arg error "+err.Error()) return } uid, err := common.GetUID(c) if err != nil { common.ServeJSON(c, stderr.ErrAccessForbid, err) return } //热搜视屏代替 skip := int64((arg.PageNumber - 1) * arg.PageSize) limit := int64(arg.PageSize) list, hasNext, err := vidser.GetHotKWList(uid, skip, limit) if err != nil { common.ServeJSON(c, stderr.Failure, err) return } common.ServeJSON(c, stderr.Success, gin.H{ "list": list, "hasNext": hasNext, }) } // GetLocation doc // @Summary 根据id获取location信息 // @Description 根据id获取location信息 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param id formData string true "地址信息id" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/vid/location/info [get] func GetLocation(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } param := vidmod.LocReq{} if err = ctx.ShouldBind(¶m); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } code, data := vidser.GetLocation(uid, param.ID) common.ServeJSON(ctx, code, data) } // GetWatchCount doc // @Summary 根据id获取用户观看次数 // @Description 根据id获取用户观看次数 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param vid formData string false "视频ID" // @Success 200 {object} vidmod.WatchCountResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/user/count [get] func GetWatchCount(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } var p struct { Vid string `form:"vid"` First string `form:"first"` } if err = ctx.ShouldBind(&p); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } if p.Vid == "" { u, err := usermod.FindUserByUID(uid) if err != nil || u == nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, "FindUserByUID error") return } watchCount := vidser.FreshCount(u.UID) watch := watchCount > 0 totalWatchCount := vidser.TotalFreeWatchCount() log.Info("GetWatchCount", log.Any("uid", uid), log.Any("isCan", watch), log.Any("watchCount", watchCount), log.Any("totalWatchCount", totalWatchCount)) common.ServeJSON(ctx, stderr.Success, vidmod.WatchCountResp{ IsCan: watch, WatchCount: watchCount, TotalWatchCount: totalWatchCount, }) return } oid, err := primitive.ObjectIDFromHex(p.Vid) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, "get watch count arg error "+err.Error()) return } watch, watchCount := vidser.GetWatchCount(uid, oid, p.First) log.Info("GetWatchCount", log.Any("uid", uid), log.Any("vid", p.Vid), log.Any("isCan", watch)) common.ServeJSON(ctx, stderr.Success, vidmod.WatchCountResp{ IsCan: watch, WatchCount: watchCount, TotalWatchCount: vidser.TotalFreeWatchCount(), }) } // ConsumeWatchCount doc // @Summary 消费用户免费观看视频次数 // @Description 同一用户同一视频每天最多消费一次 // @Tags vid // @Accept json // @Produce json // @Param request body vidmod.WatchConsumeReq true "视频ID" // @Success 200 {object} vidmod.WatchConsumeResp // @Failure 400 {string} json // @Router /api/app/vid/play/consume [post] func ConsumeWatchCount(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } var req vidmod.WatchConsumeReq if err = ctx.ShouldBindJSON(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } videoID := req.GetVideoID() oid, err := primitive.ObjectIDFromHex(videoID) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } resp, err := vidser.ConsumeFreeWatch(uid, oid) if err != nil { log.Error("ConsumeWatchCount failed", log.Any("uid", uid), log.Any("videoID", videoID), log.E(err)) common.ServeJSON(ctx, stderr.ErrDbUpdateError, nil) return } common.ServeJSON(ctx, stderr.Success, resp) } // DeleteManyByTTL doc // @Summary 删除自己的视频 // @Description 删除自己的视频 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param id formData string true "地址信息id" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/vid/remove/ [delete] func RemoveMyVideos(ctx *gin.Context) { //20220222接口屏蔽start common.ServeJSON(ctx, stderr.ErrParamError, nil) } // ModuleVideoList doc // @Summary 获取模块下各个专题视频 // @Description 获取模块下各个专题所有视频 // @Tags 首页模块 // @Accept mpfd,json // @Produce json,html // @Param subModuleID path string true "亚模块" // @Param tagid query string true "标签id" // @Param pageNumber query integer true "模块下视频页码" // @Param pageSize query integer true "模式下视频数量" // @Param moduleSort query integer true " 视频排序 1、最新,2、最热/最多喜欢,3、最多播放,4、十分钟以上视频, 5、精华/精选,6、视频 7-最多收藏 8、解锁次数" // @Success 200 {object} vidser.VideoUnderSubModuleResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/module/:subModuleID [get] func ModuleVideoList(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil && !errors.Is(err, common.ErrUserNotExist) { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } subModuleIDStr := ctx.Param("subModuleID") if subModuleIDStr == "" { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } subModuleID, err := primitive.ObjectIDFromHex(subModuleIDStr) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } req := vidser.VideoUnderSubModuleReq{} if err := ctx.ShouldBindQuery(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, err) return } res, err := vidser.GetVideosUnderSubModuleNew(subModuleID, uid, req) if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } // 首页模块下各专题视频:对 m3u8 播放地址签发 H5 防盗链票据 m3u8ticket.Sign(ctx, res) common.ServeJSON(ctx, stderr.Success, res) } // RefreshModuleVideos 从亚模块热门候选池中随机返回视频。 func RefreshModuleVideos(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil && !errors.Is(err, common.ErrUserNotExist) { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } subModuleID, err := primitive.ObjectIDFromHex(ctx.Param("subModuleID")) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } req := vidser.RefreshModuleVideosReq{} if err = ctx.ShouldBindQuery(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, err.Error()) return } req.RefreshToken = strings.TrimSpace(req.RefreshToken) if req.RefreshToken == "" { common.ServeJSON(ctx, stderr.ErrParamError, "refreshToken is required") return } res, err := vidser.RefreshModuleVideos(uid, subModuleID, req) if err != nil { if errors.Is(err, vidser.ErrRandomRefreshUnsupported) { common.ServeJSON(ctx, stderr.ErrParamError, err.Error()) return } common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } // 随机刷新列表:对 sourceURL、h265Url 签发播放防盗链票据。 m3u8ticket.Sign(ctx, res.AllVideoInfo) common.ServeJSON(ctx, stderr.Success, res) } // SectionVideoList doc // @Summary 获取一个专题下的视频列表 // @Description 获取一个专题下的视频列表,如“撩吧--推荐”模块下“XX”专题下的视频列表 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param sectionID path string true "专题ID" // @Param pageSize query integer true "页码大小" // @Param pageNumber query integer true "专题页码" // @Param sortType query string true "watch:最多播放,new:最新,collect: 收藏" // @Success 200 {object} vidser.VideoUnderSectionResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/section/:sectionID [get] func SectionVideoList(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil && !errors.Is(err, common.ErrUserNotExist) { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } req := vidser.VideoUnderSectionReq{} if err = ctx.ShouldBindUri(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } if err = ctx.ShouldBind(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } var sectionID primitive.ObjectID //var bloggerID int sectionID, err = primitive.ObjectIDFromHex(req.SectionID) //bloggerID, err2 := strconv.Atoi(req.SectionID) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } page := commod.Page{} if err = ctx.ShouldBind(&page); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } resp := vidser.VideoUnderSectionResp{} if !sectionID.IsZero() { resp, err = vidser.GetSectionVideos(uid, sectionID, page, req.SortType, req.PlayTimeType) if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } } //if bloggerID != 0 { // resp, err = vidser.GetBloggerVideos(uid, uint64(bloggerID), page) // if err != nil { // serveVid(ctx, stderr.ErrDbQueryError, nil) // return // } //} common.Go(func() { if err := vidser.IncSectionHits(ctx, sectionID); err != nil { log.ErrorX(ctx, "vidser.IncSectionHits failed", log.Any("sectionID", sectionID), log.E(err)) } }) common.ServeJSON(ctx, stderr.Success, resp) } // AllVideosOfModule doc // @Summary 获取模块下所有视频 // @Description 获取模块下所有视频 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param subModuleID path string true "亚模块" // @Param pageSize query integer true "页码大小,一个专题下视频数量" // @Param sectionSize query integer true "专题数量" // @Param sectionPage query integer true "专题页码" // @Success 200 {object} vidser.VideoUnderSubModuleResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/module/moduleVideo [get] func AllVideosOfModule(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil && !errors.Is(err, common.ErrUserNotExist) { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } req := vidser.AllVideosOfModuleReq{} if err := ctx.ShouldBindQuery(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } subModuleID, err := primitive.ObjectIDFromHex(req.SubModuleID) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } res, err := vidser.AllVideosOfModule(subModuleID, uid, req) if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } common.ServeJSON(ctx, stderr.Success, res) } func Sections(ctx *gin.Context) { if _, err := common.GetUID(ctx); err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } sections, err := vidser.GetValidSections() if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } common.ServeJSON(ctx, stderr.Success, struct { Sections []vidser.SectionResp `json:"sections"` }{ Sections: sections, }) } // 视频播放页的推荐视频列表 func VidPlayRecommand(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } var vrr vidser.VidRecommandReq if err := ctx.ShouldBind(&vrr); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } vid, err := primitive.ObjectIDFromHex(vrr.ID) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } if vid.IsZero() { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } resp, err := vidser.GetVidPlayRecommand(uid, vid) if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } common.ServeJSON(ctx, stderr.Success, resp) } // 搜索页面的视频播放列表 func SearchRecommand(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } resp, err := vidser.GetSearchRecommand(uid) if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } common.ServeJSON(ctx, stderr.Success, resp) } // DiscountVidList doc // @Summary 获取折扣专区下视频 // @Description 获取折扣专区下视频 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param discountId query string true "折扣专区id" // @Param pageSize query integer true "页码大小,一个专题下视频数量" // @Param pageNumber query integer true "页码数" // @Param sortType query integer true "排序类型 0-默认 1-最新 2-最热" // @Success 200 {object} vidser.DiscountVideoResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/discount/list [get] func DiscountVidList(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil && !errors.Is(err, common.ErrUserNotExist) { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } req := vidser.DiscountVideoReq{} if err := ctx.ShouldBindQuery(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, err) return } resp, err := vidser.GetDiscountAreaVideos(uid, &req) if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } // 通过折扣专区id获取折扣视频 common.ServeJSON(ctx, stderr.Success, resp) } // DiscountArea doc // @Summary 获取vip折扣专区 // @Description 获取vip折扣专区 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Success 200 {object} vidser.DiscountAreaResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/discount/area [get] func DiscountArea(ctx *gin.Context) { list, err := vidser.GetDiscountArea() if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } if len(list) == 0 { list = []discount_area_mod.DiscountArea{} } common.ServeJSON(ctx, stderr.Success, &vidser.DiscountAreaResp{ List: list, }) } // CommunityRecommend doc // @Summary 获取社区下黄油和图集的推荐 // @Description 获取社区下黄油和图集的推荐 // @Tags 社区模块 // @Accept mpfd,json // @Produce json,html // @Param q query vidser.CommunityRecommendReq false "请求参数" // @Success 200 {object} vidser.VideoUnderSubModuleResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/community/recommend [get] func CommunityRecommend(ctx *gin.Context) { req := vidser.CommunityRecommendReq{} if err := ctx.ShouldBindQuery(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, err) return } res, err := vidser.GetCommunityRecommend(req) if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } common.ServeJSON(ctx, stderr.Success, res) } // Ranking doc // @Summary 视频/帖子/图集排行榜 // @Description 视频/帖子/图集排行榜 // @Tags 移动端-视频/帖子/图集排行榜 // @Accept mpfd,json // @Produce json // @Param q query vidser.RankingReq false "请求参数" // @Success 200 object vidser.RankingResp "成功" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/ranking [get] func Ranking(ctx *gin.Context) { p := &vidser.RankingReq{} if err := ctx.ShouldBind(&p); err != nil { log.Error(fmt.Sprintf("Rank param err:%v", err)) common.ServeJSON(ctx, stderr.ErrParamError, nil) return } p.UID, _ = common.GetUID(ctx) res, err := p.List() if err != nil { log.Error(fmt.Sprintf("Get Ranking List err:%v", err)) common.ServeJSON(ctx, stderr.Failure, nil) return } common.ServeJSON(ctx, stderr.Success, res) } // SectionList doc // @Summary 获取一个模块下的专题 // @Description 获取一个模块下的专题 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param mid path string true "模块id" // @Param pageSize query integer true "页码大小" // @Param pageNumber query integer true "专题页码" // @Success 200 object vidser.SectionListResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/section/list [get] func SectionList(ctx *gin.Context) { req := vidser.SectionListReq{} if err := ctx.ShouldBind(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } resp, err := req.GetList() if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } common.ServeJSON(ctx, stderr.Success, resp) } // RecommendList doc // @Summary 推荐视频列表 // @Description 推荐视频列表 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param tagId query string true "标签id" // @Param newsType query string true "帖子类型 SP-视频 SHORT-短视频 COVER-帖子 PIC-图集 SEED_LINK-种子帖" // @Param pageNumber query int true "当前页" // @Param pageSize query int true "每页条数" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/recommend/list [get] func RecommendList(c *gin.Context) { var arg struct { commod.Page TagId string `json:"tagId" form:"tagId"` // 标签 NewsType string `json:"newsType" form:"newsType"` // 视频/帖子类型 } if err := c.ShouldBind(&arg); err != nil { common.ServeJSON(c, stderr.ErrParamError, "vid HotList arg error "+err.Error()) return } uid, err := common.GetUID(c) if err != nil { common.ServeJSON(c, stderr.ErrAccessForbid, err) return } list, hasNext, err := vidser.GetRecommendList(uid, arg.TagId, arg.NewsType, arg.Page) if err != nil { common.ServeJSON(c, stderr.Failure, err) return } common.ServeJSON(c, stderr.Success, gin.H{ "list": list, "hasNext": hasNext, "updatedAt": time.Now().Format("2006-01-02 15:04"), }) } // SubModuleAllVideoList doc // @Summary 获取模块下视频列表(猜你喜欢) // @Description 获取模块下视频列表,不区分专题(猜你喜欢) // @Tags 首页模块 // @Accept mpfd,json // @Produce json,html // @Param subModuleID path string true "亚模块" // @Param q query vidser.SubModuleAllVideoListReq false "请求参数" // @Success 200 {object} vidser.VideoUnderSubModuleResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/module/all/:subModuleID [get] func SubModuleAllVideoList(ctx *gin.Context) { uid, _ := common.GetUID(ctx) subModuleIDStr := ctx.Param("subModuleID") if subModuleIDStr == "" { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } subModuleID, err := primitive.ObjectIDFromHex(subModuleIDStr) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } req := vidser.SubModuleAllVideoListReq{} if err := ctx.ShouldBindQuery(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, err) return } res, err := vidser.SubModuleAllVideoList(uid, subModuleID, req) if err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } common.ServeJSON(ctx, stderr.Success, res) } // Library doc // // @Summary 获取首页片库接口 // @Description 获取首页片库详情 // @Tags 移动端-主页模块 // @Accept mpfd,json // @Produce json // @Success 200 object vidmod.LibraryData "成功" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/library [get] func Library(c *gin.Context) { uid, err := common.GetUID(c) if err != nil { common.ServeJSON(c, stderr.ErrNoToken, nil) return } data, err := vidser.GetLibrary(uid) if err != nil { common.ServeJSON(c, stderr.Failure, nil) return } common.ServeJSON(c, stderr.Success, data) } // LibrarySearch doc // // @Summary 片库-搜索视频 // @Description 片库-搜索视频 // @Tags 移动端-主页模块 // @Accept mpfd,json // @Produce json,html // @Param q query vidser.LibraryElasticSearchRequest false "请求参数" // @Success 200 object vidser.AppElasticSearchLibraryResponse "成功" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/library/search [post] func LibrarySearch(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } in := vidser.LibraryElasticSearchRequest{} if err := ctx.ShouldBind(&in); err != nil { log.Error(fmt.Sprintf("video librarySearch param err:%v", err)) common.ServeJSON(ctx, stderr.ErrParamError, err) return } in.UID = uid data, err := in.CheckSearchType() if err != nil { log.Error(fmt.Sprintf("video librarySearch err:%v", err)) common.ServeJSON(ctx, stderr.Failure, err) return } common.ServeJSON(ctx, stderr.Success, data) } // RecommendShortVideos doc // @Summary 获取模块下随机短视频 // @Description 获取模块下随机视频 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param pageNumber query integer true "每页数量" // @Param pageSize query integer true "页码大小" // @Param X-Request-ID header string false "重试幂等ID;同一次请求重试保持不变" // @Success 200 {object} vidser.VideoUnderSubModuleResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/module/short/all [get] func RecommendShortVideos(ctx *gin.Context) { uid, _ := common.GetUID(ctx) //if err != nil && !errors.Is(err, common.ErrUserNotExist) { // serveVid(ctx, stderr.ErrNoToken, nil) // return //} req := vidser.HandleShortVideoUnderSubModuleReq{} req.UID = uid req.Context = ctx.Request.Context() req.RequestID, _ = requestid.FromClient(ctx) if err := ctx.ShouldBindQuery(&req); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } res := req.Do() if req.Err != nil { common.ServeJSON(ctx, stderr.ErrDbQueryError, nil) return } //if err != nil { // serveVid(ctx, stderr.ErrDbQueryError, nil) // return //} common.ServeJSON(ctx, stderr.Success, res) } // ChangeSectionVideoList doc // @Summary 获取专题下的换一批视频列表 // @Description 专题下的视频列表-换一批 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param sectionID path string true "专题ID" // @Success 200 {object} vidser.VideoUnderSectionResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /app/vid/section/changeVideo/:sectionID [get] func ChangeSectionVideoList(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil && !errors.Is(err, common.ErrUserNotExist) { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } in := vidmod.ChangeVideoSectionReq{} if err = ctx.ShouldBindUri(&in); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } if err = ctx.ShouldBind(&in); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } data, err := vidser.GetChangeVideos(&in, uid) if err != nil { common.ServeJSON(ctx, stderr.Failure, nil) return } common.ServeJSON(ctx, stderr.Success, data) } // ChangeSectionMediaList doc // @Summary 获取专题下的换一批动漫/漫画列表 // @Description 专题下的acg列表-换一批 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param sectionID path string true "专题ID" // @Success 200 {object} vidser.VideoUnderSectionResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /app/vid/section/changeMedia/:sectionID [get] func ChangeSectionMediaList(ctx *gin.Context) { uid, err := common.GetUID(ctx) if err != nil && !errors.Is(err, common.ErrUserNotExist) { common.ServeJSON(ctx, stderr.ErrNoToken, nil) return } in := vidmod.ChangeVideoSectionReq{} if err = ctx.ShouldBindUri(&in); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } if err = ctx.ShouldBind(&in); err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } data, err := vidser.GetChangeMedias(&in, uid) if err != nil { common.ServeJSON(ctx, stderr.Failure, nil) return } common.ServeJSON(ctx, stderr.Success, data) } // HomeMostNewModuleVideoList doc // @Summary 首页固定的最新模块下视频数据列表 // @Description 首页固定的最新模块下视频数据列表 // @Tags vid // @Accept mpfd,json // @Produce json,html // @Param q query vidmod.HomeMostNewModuleVideoListReq true "req" // @Success 200 {object} vidser.VideoUnderSectionResp // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/vid/home/new/list [get] func HomeMostNewModuleVideoList(ctx *gin.Context) { in := vidmod.HomeMostNewModuleVideoListReq{} err := ctx.ShouldBindQuery(&in) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } err = ctx.ShouldBind(&in) if err != nil { common.ServeJSON(ctx, stderr.ErrParamError, nil) return } ua, _ := common.GetUA(ctx) // 兼容线上参数错误 if ua.SysType == "android" && in.SortType == 4 { in.SortType = 3 } else if in.SortType == 5 { in.SortType = 4 } uid, _ := common.GetUID(ctx) data, err := vidser.MostNewModuleVideoList(uid, in) if err != nil { common.ServeJSON(ctx, stderr.Failure, nil) return } common.ServeJSON(ctx, stderr.Success, data) }