Files
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

241 lines
7.1 KiB
Go

package collectser
import (
"91porn-server/app/service/taskser"
"91porn-server/app/service/vidhelpser"
"91porn-server/common"
"91porn-server/common/constant"
"91porn-server/common/log"
"91porn-server/common/stderr"
"91porn-server/middleware/ua"
"91porn-server/models/cache/aiplazadata"
"91porn-server/models/commod"
"91porn-server/models/v/aiplazamod"
"91porn-server/models/v/collectmod"
"91porn-server/models/v/dailytaskmod"
"91porn-server/models/v/tagmod"
"91porn-server/models/v/usermod"
"91porn-server/models/v/vidmod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// DoCollect 收藏标签
func DoCollect(uid uint64, cType string, objID primitive.ObjectID, isCollect bool, ua ua.UA, ip string) (code stderr.Code, err error) {
coll, err := collectmod.CollFindOneByUidAndObjID(uid, objID)
if err != nil {
code = stderr.CollectErrGetDataFailed
log.Error("app service collect DoCollect CollFindOneByUidAndObjID err", log.Any("err", err))
return
}
if isCollect && !coll.ID.IsZero() {
code = stderr.CollectHasCollected
return
} else if !isCollect && coll.ID.IsZero() {
code = stderr.CollectHasNotCollected
return
}
cMod := collectmod.Collect{
ObjID: objID,
UID: uid,
Type: cType,
}
if isCollect {
if err = collectmod.CollInsertOne(&cMod); err != nil {
code = stderr.CollectErrCollectFailed
log.Error("app service collect DoCollect CollInsertOne err", log.Any("err", err))
return
}
if incErr := vidmod.IncrementRecommendInteraction(objID, vidmod.RecommendInteractionCollect); incErr != nil {
// 推荐累计失败不回滚已成功的收藏,记录后由监控补偿。
log.Error("increment recommend collect failed", log.E(incErr), log.Any("objID", objID))
}
} else {
if err = collectmod.CollDeleteOne(uid, cType, objID); err != nil {
code = stderr.CollectErrCancelFailed
log.Error("app service collect DoCollect CollDeleteOne err", log.Any("err", err))
return
}
}
inc := -1
if isCollect {
inc = 1
// 每日任务完成
taskser.CompleteDailyTask(nil, uid, dailytaskmod.DailyDoCollect)
}
switch cType {
case constant.CollectTypeAiPlaza:
err = aiplazamod.IncCollectCount(objID)
case constant.CollectTypeSP, constant.CollectTypeShort, constant.CollectTypeCover, constant.CollectTypePIC, constant.SEED_LINK:
err = vidmod.IncForwardCount(inc, objID)
case constant.CollectTypeTag:
err = tagmod.IncreaseTagCollectCount(inc, objID)
}
if err != nil {
code = stderr.CollectErrCollectFailed
log.Error("app service collect DoCollect IncreaseTagCollectCount err", log.Any("err", err))
return
}
reportVideoCollect(uid, cType, objID, !isCollect, ua, ip)
code = stderr.Success
return
}
// DoBatchCancelCollect 批量取消收藏
func DoBatchCancelCollect(uid uint64, cType string, objIds []primitive.ObjectID, ua ua.UA, ip string) (code stderr.Code, err error) {
colls, err := collectmod.CollFindOneByUidAndObjIds(uid, objIds)
if err != nil {
code = stderr.CollectErrGetDataFailed
log.Error("app service collect DoBatchCollect CollFindOneByUidAndObjIds err", log.Any("err", err))
return
}
var uniqueIds []string
var oids []primitive.ObjectID
for _, coll := range colls {
if !coll.ID.IsZero() {
oids = append(oids, coll.ObjID)
uniqueIds = append(uniqueIds, collectmod.Unique(uid, cType, coll.ObjID))
}
}
if len(uniqueIds) == 0 {
code = stderr.CollectHasNotCollected
return
}
if err = collectmod.CollDeleteMany(uniqueIds); err != nil {
code = stderr.CollectErrCancelFailed
log.Error("app service collect DoCollect CollDeleteMany err", log.Any("err", err))
return
}
switch cType {
case constant.CollectTypeSP, constant.CollectTypeShort, constant.CollectTypeCover, constant.CollectTypePIC, constant.CollectTypeSEED_LINK:
err = vidmod.IncForwardCount(-1, oids...)
case constant.CollectTypeTag:
err = tagmod.IncreaseTagCollectCount(-1, oids...)
}
if err != nil {
code = stderr.CollectErrCollectFailed
log.Error("app service collect DoCollect IncreaseTagCollectCount err", log.Any("err", err))
return
}
for _, oid := range oids {
reportVideoCollect(uid, cType, oid, true, ua, ip)
}
code = stderr.Success
return
}
func reportVideoCollect(uid uint64, cType string, objID primitive.ObjectID, cancel bool, uaInfo ua.UA, ip string) {
if !shouldReportVideoCollect(cType) || objID.IsZero() {
return
}
common.Go(func() {
user, err := usermod.FindUserByUID(uid)
if err != nil || user == nil {
return
}
video, err := vidmod.GetVideoInfo(objID.Hex())
if err != nil || video.ID.IsZero() {
return
}
})
}
func shouldReportVideoCollect(cType string) bool {
switch cType {
case constant.CollectTypeSP, constant.CollectTypeShort, constant.CollectTypeCover, constant.CollectTypePIC, constant.CollectTypeSEED_LINK:
return true
default:
return false
}
}
// GetInfoList 收藏详情列表
func GetInfoList(uid uint64, cType string, page commod.Page) (code stderr.Code, hasNext bool, data interface{}, err error) {
stdQuery := commod.StdQuery{Page: &commod.PageBy{Num: page.PageNumber, Size: page.PageSize + 1, CheckNext: true}, Order: &[]commod.OrderBy{}}
modList, err := collectmod.CollFindCollects(uid, cType, stdQuery)
if err != nil {
code = stderr.CollectErrGetDataFailed
log.Error("app service collect GetInfoList CollFindCollects err", log.Any("err", err))
return
}
cIDs := make([]primitive.ObjectID, len(modList)) // 收藏对象id
for i := range modList {
cIDs[i] = modList[i].ObjID
}
if len(cIDs) <= 0 {
code = stderr.Success
return
}
if len(cIDs) > int(page.PageSize) {
hasNext = true
cIDs = cIDs[:page.PageSize]
}
switch cType {
case constant.AiPlaza:
// 获取ai广场
// 获取ai广场帖子
list, err := aiplazamod.GetAll(bson.M{"_id": bson.M{"$in": cIDs}}, nil)
if err != nil {
log.Error("获取收藏的ai广场帖子失败", log.Any("uid", uid), log.E(err))
break
}
data = aiplazadata.FormatAppDataList(list)
case constant.CollectTypeShort, constant.CollectTypeSP, constant.CollectTypeCover, constant.CollectTypePIC, constant.CollectTypeSEED_LINK:
vidList := vidhelpser.GetVideosByIDsNoCache(uid, cIDs)
data = vidList
if len(vidList) > int(page.PageSize) {
hasNext = true
data = vidList[:page.PageSize]
}
break
case constant.CollectTypeTag:
tags, err := getTagsInfo(cIDs)
if err != nil {
code = stderr.CollectErrGetDataFailed
return code, hasNext, data, err
}
data = tags
if len(tags) > int(page.PageSize) {
hasNext = true
data = tags[:page.PageSize]
}
break
default:
}
code = stderr.Success
return
}
func getTagsInfo(ids []primitive.ObjectID) ([]tagmod.RespInfo, error) {
tList, err := tagmod.FindTagsByIDS(ids)
if err != nil {
log.Error("app service collect getTagsInfo FindTagsByIDS err", log.Any("err", err))
return nil, err
}
var tInfoList []tagmod.RespInfo
for _, v := range tList {
tTmp := tagmod.RespInfo{
ID: v.ID,
Name: v.TagName,
CoverImg: v.CoverImg,
Description: v.Description,
PlayCount: v.TPlayCount,
HasCollected: true,
VideoCount: v.VideoCount,
}
tInfoList = append(tInfoList, tTmp)
}
if tInfoList == nil || len(tInfoList) <= 0 {
tInfoList = []tagmod.RespInfo{}
}
return tInfoList, nil
}