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

356 lines
10 KiB
Go

package moduleser
import (
"91porn-server/common/log"
"91porn-server/models/v/tagmod"
"errors"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
"strings"
"time"
sli "91porn-server/common/slice"
"91porn-server/common/stderr"
"91porn-server/models/commod"
"91porn-server/models/v/moduleconfmod"
"91porn-server/models/v/modulesectionmod"
"91porn-server/models/v/modulevidmod"
"91porn-server/models/v/usermod"
"91porn-server/models/v/vidmod"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// AddModule 添加模块专题配置
func AddModule(mconf moduleconfmod.ModuleConf) error {
if err := validateDramaModuleName(mconf.Type, mconf.ModuleName); err != nil {
return err
}
return moduleconfmod.InsertOne(&mconf)
}
func validateDramaModuleName(moduleType int, moduleName string) error {
if moduleType != moduleconfmod.Drama {
return nil
}
name := strings.TrimSpace(moduleName)
lowerName := strings.ToLower(name)
if strings.Contains(lowerName, "ai") || strings.Contains(name, "热门") || strings.Contains(lowerName, "hot") {
return nil
}
return errors.New("短剧模块名称必须包含AI、热门或hot")
}
func AddSection(section modulesectionmod.Section) error {
return modulesectionmod.InsertOne(section)
}
// UpdateModule 更新模块专题配置
func UpdateModule(editSelector moduleconfmod.EditSelector) error {
current, err := moduleconfmod.GetByID(editSelector.ID)
if err != nil {
return err
}
moduleType := current.Type
moduleName := current.ModuleName
if editSelector.Type != nil {
moduleType = *editSelector.Type
}
if editSelector.ModuleName != nil {
moduleName = *editSelector.ModuleName
}
if err = validateDramaModuleName(moduleType, moduleName); err != nil {
return err
}
return moduleconfmod.UpdateOne(editSelector)
}
func UpdateSection(editSelector modulesectionmod.EditSelector) error {
var tagIds []primitive.ObjectID
if editSelector.Tags != nil && len(*editSelector.Tags) > 0 {
tags, err := tagmod.FindOneTagByNames(*editSelector.Tags)
if err != nil {
return err
}
if len(tags) <= 0 {
return errors.New("tag is null")
}
for _, t := range tags {
tagIds = append(tagIds, t.ID)
}
}
editSelector.TagIds = tagIds
return modulesectionmod.UpdateOne(editSelector)
}
func DeleteSection(id primitive.ObjectID) error {
return modulesectionmod.DeleteById(id)
}
// GetModuleList 获取专题下视频列表
func GetModuleList(query modulevidmod.QuerySelector, page commod.Page) (resp ModuleVideoList, err error) {
list, hasNext, total, err := modulevidmod.Search(&query, page)
if err != nil {
return
}
listLen := len(list)
sectionIDs := make([]primitive.ObjectID, listLen)
videoIDs := make([]primitive.ObjectID, listLen)
for i, sec := range list {
sectionIDs[i] = sec.SectionID
videoIDs[i] = sec.VideoID
}
sections, err := modulesectionmod.GetByIDs(sli.RemoveRepObjectID(sectionIDs))
if err != nil {
return
}
sectionModuleMap := make(map[primitive.ObjectID]modulesectionmod.SectionModule)
for _, v := range sections {
sectionModuleMap[v.ID] = v
}
videos, err := vidmod.GetVideoListByIDsNoStatus(videoIDs)
if err != nil {
return
}
videoMap := make(map[primitive.ObjectID]vidmod.VideoModel)
for _, video := range videos {
videoMap[video.ID] = *video
}
resp.List = make([]ModuleVideo, listLen)
for i, sec := range list {
secVideo := ModuleVideo{
ID: sec.ID,
SectionID: sec.SectionID,
CreatedAt: sec.CreatedAt,
SortCode: sec.SortCode,
}
if module, ok := sectionModuleMap[sec.SectionID]; ok {
secVideo.SectionName = module.SectionName
if len(module.SectionModule) > 0 {
secVideo.ModuleName = module.SectionModule[0].ModuleName
secVideo.SubModuleName = module.SectionModule[0].SubModuleName
}
}
secVideo.VideoInfo = VideoInfo{
VideoID: videoMap[sec.VideoID].ID,
Title: videoMap[sec.VideoID].Title,
PublisherID: videoMap[sec.VideoID].PublisherID,
Cover: videoMap[sec.VideoID].Cover,
}
resp.List[i] = secVideo
}
resp.Total = total
resp.HasNext = hasNext
return
}
// AddVideoBatch 专题下批量添加视频
func AddVideoBatch(req AddVideoBatchReq) error {
section, err := modulesectionmod.GetBySectionByID(req.SectionID)
if err != nil {
return stderr.ErrDbQueryError
}
if section.ID.IsZero() {
return stderr.CodeEmptyData
}
mId := section.SubModuleID
videoIdStrs := strings.Split(req.VideoIDs, ",")
vids := make([]primitive.ObjectID, len(videoIdStrs))
for i, vidIDStr := range videoIdStrs {
videoID, err := primitive.ObjectIDFromHex(vidIDStr)
if err != nil {
return stderr.ErrParamError
}
vids[i] = videoID
}
list, err := vidmod.GetVideoListByIDs(vids)
if err != nil {
return stderr.ErrNetWorkBusy
}
records := make([]modulevidmod.SectionVideo, len(list))
var vIds []primitive.ObjectID
var ids []primitive.ObjectID
for i := range list {
records[i] = modulevidmod.SectionVideo{
SectionID: req.SectionID,
VideoID: list[i].ID,
VideoReviewedAt: list[i].ReviewAt,
}
vIds = append(vIds, list[i].ID)
}
sectionVideos, err := modulevidmod.GetSectionsByVideoIds(vIds)
if err != nil {
return err
}
if len(sectionVideos) > 0 {
for i := range sectionVideos {
ids = append(ids, sectionVideos[i].ID)
}
}
if len(ids) > 0 {
err := modulevidmod.DeleteManyVideo(ids)
if err != nil {
return err
}
}
// 批量更新视频信息
update := bson.M{}
update["mId"] = mId.Hex()
update["updatedAt"] = time.Now()
result, err := vidmod.UpdateManyVideo(vIds, update)
if err != nil {
return err
}
if result == 0 {
return errors.New("video update failed")
}
return modulevidmod.InsertMany(records)
}
// AddVideo 专题下添加一条视频
func AddVideo(sectionVid modulevidmod.SectionVideo) error {
videoID := sectionVid.VideoID
video, err := vidmod.GetVideoInfo(videoID.Hex())
if err != nil {
return err
}
sectionVid.VideoReviewedAt = video.ReviewAt
sectionVid.NewsType = video.NewsType
return modulevidmod.InsertOne(&sectionVid)
}
// AllSections 获取所有专题
func AllSections() (data []modulesectionmod.ModuleSection, err error) {
modules, err := moduleconfmod.GetAllModule()
if err != nil {
return
}
sections, err := modulesectionmod.AllSections()
if err != nil {
return
}
sectionMap := make(map[primitive.ObjectID][]modulesectionmod.Section)
for _, s := range sections {
sectionMap[s.SubModuleID] = append(sectionMap[s.SubModuleID], s)
}
data = make([]modulesectionmod.ModuleSection, len(modules))
for i, m := range modules {
data[i] = modulesectionmod.ModuleSection{
ModuleConf: m,
Sections: sectionMap[m.ID],
}
}
return
}
func SectionSearch(q modulesectionmod.QuerySelector, p commod.Page) (resp modulesectionmod.ListResp, err error) {
sections, hasNext, total, err := modulesectionmod.Search(q, p)
if err != nil {
return
}
resp.HasNext = hasNext
resp.Total = total
sectionsLen := len(sections)
originalUserIDs := make([]uint64, 0, sectionsLen)
subModuleIDs := make([]primitive.ObjectID, 0, sectionsLen)
for _, section := range sections {
if section.OriginalUserID != nil && *section.OriginalUserID != 0 {
originalUserIDs = append(originalUserIDs, *section.OriginalUserID)
}
if !section.SubModuleID.IsZero() {
subModuleIDs = append(subModuleIDs, section.SubModuleID)
}
}
users, err := usermod.FindUsersByUID(originalUserIDs)
if err != nil {
return
}
subModules, err := moduleconfmod.FindByIDs(subModuleIDs)
if err != nil {
return
}
originalBloggerInfo := make(map[uint64]usermod.User)
subModuleInfo := make(map[primitive.ObjectID]moduleconfmod.ModuleConf)
for _, user := range users {
originalBloggerInfo[user.UID] = *user
}
for _, module := range subModules {
subModuleInfo[module.ID] = module
}
resp.List = make([]modulesectionmod.SectionDetail, sectionsLen)
for i, section := range sections {
detail := modulesectionmod.SectionDetail{
Section: section,
}
if section.OriginalUserID != nil && *section.OriginalUserID != 0 {
detail.OriginalBloggerInfo = modulesectionmod.OriginalBloggerInfo{
Name: originalBloggerInfo[*section.OriginalUserID].Name,
Portrait: originalBloggerInfo[*section.OriginalUserID].Portrait,
OfficialCert: originalBloggerInfo[*section.OriginalUserID].OfficialCert,
}
}
if !section.SubModuleID.IsZero() {
detail.ModuleInfo = modulesectionmod.ModuleInfo{
ModuleName: subModuleInfo[section.SubModuleID].ModuleName,
SubModuleName: subModuleInfo[section.SubModuleID].SubModuleName,
SectionLimit: subModuleInfo[detail.SubModuleID].SectionLimit,
}
}
resp.List[i] = detail
}
return
}
// QueryAllCartoonList 查询动漫模块专题配置
func QueryAllCartoonList() ([]*modulesectionmod.AllSectionConf, error) {
var out []*modulesectionmod.AllSectionConf
filter := bson.M{"type": bson.M{"$in": []int{moduleconfmod.Novel, moduleconfmod.Comics, moduleconfmod.Cartoon}}, "status": 1, "deletedAt": bson.M{"$exists": false}}
op := options.Find().SetSort(bson.M{"sortNum": -1})
list, err := moduleconfmod.QueryAllList(filter, op)
if err != nil {
log.Error(fmt.Sprintf("moduleconfmod QueryAllList error:%+v:", err))
return nil, err
}
var subIds []primitive.ObjectID
if len(list) > 0 {
for _, m := range list {
subIds = append(subIds, m.ID)
}
}
sf := bson.M{"subModuleID": bson.M{"$in": subIds}, "status": 1, "deletedAt": bson.M{"$exists": false}}
sop := options.Find().SetSort(bson.M{"sort": -1})
sections, err := modulesectionmod.QueryAllList(sf, sop)
if err != nil {
log.Error(fmt.Sprintf("modulesectionmod QueryAllList error:%+v:", err))
return nil, err
}
if len(sections) > 0 {
for _, m := range list {
mes := &modulesectionmod.AllSectionConf{
ID: m.ID,
ModuleName: m.ModuleName,
}
var allSection []modulesectionmod.SectionConf
for _, s := range sections {
if s.SubModuleID.Hex() == m.ID.Hex() {
nes := modulesectionmod.SectionConf{
ID: s.ID,
SectionName: s.SectionName,
}
allSection = append(allSection, nes)
}
}
mes.AllSection = allSection
out = append(out, mes)
}
}
return out, nil
}