Files
huangguo_server/web/service/mediaresourceser/media.go
T
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

216 lines
6.5 KiB
Go

package mediaresourceser
import (
"91porn-server/common"
"91porn-server/common/log"
mediaService "91porn-server/common/media"
"91porn-server/common/mediaCenter"
"91porn-server/web/webg"
"errors"
"go.mongodb.org/mongo-driver/bson/primitive"
"strings"
"sync"
)
type MediaListReq struct {
MediaType int `json:"media_type" form:"media_type"` // 1-动画 2-漫画 3-文本小说 4-有声小说 5-短剧
MediaCenterId *uint `json:"media_center_id" form:"media_center_id"` // 媒资中心的中资源唯一id
VloggerId *uint `json:"vlogger_id" form:"vlogger_id"` // up主id
IsUp *int `json:"is_up" form:"is_up"` // 是否是up主 0-不是 1-是 不传则是所有
Title *string `json:"title" form:"title"` // 标题
Tag *string `json:"tag" form:"tag"` // 标签
TerminalCdo *string `json:"terminal_cdo" form:"terminal_cdo"` // 上传者
SyncType int `json:"sync_type" form:"sync_type"` // 同步类型 1-全量同步 2-增量同步
Page uint `json:"page" form:"page"`
Size uint `json:"size" form:"size"`
}
type MediaListResp struct {
List []*mediaCenter.Media `json:"list"`
Total uint `json:"total"`
}
func (p *MediaListReq) Validate() error {
if p.MediaType < 1 || p.MediaType > 5 {
return errors.New("media_type只支持1到5")
}
if p.Page < 1 || p.Size < 1 || p.Size > 100 {
return errors.New("page必须大于0且size必须在1到100之间")
}
return nil
}
func (p *MediaListReq) GetList() (res MediaListResp, err error) {
ms := mediaCenter.NewMediaCenterService(mediaCenter.Config{
Url: webg.Conf.MediaResourceDBCfg.BaseUrl,
ProId: webg.Conf.MediaResourceDBCfg.Merchat,
Secret: webg.Conf.MediaResourceDBCfg.Secret,
})
data, err := ms.MediaList(&mediaCenter.MediaListReq{
MediaType: p.MediaType,
Id: p.MediaCenterId,
VloggerId: p.VloggerId,
IsUp: p.IsUp,
Title: p.Title,
Tag: p.Tag,
TerminalCdo: p.TerminalCdo,
SyncType: p.SyncType,
Page: p.Page,
Size: p.Size,
})
if err != nil {
return
}
res.List = data.Data
res.Total = data.Pagination.Count
return
}
type MediaContentListReq struct {
MediaId int `json:"media_id" form:"media_id"`
Page uint `json:"page" form:"page"`
Size uint `json:"size" form:"size"`
}
type MediaContentListResp struct {
List []*mediaCenter.MediaContent `json:"list"`
Total uint `json:"total"`
}
func (p *MediaContentListReq) Validate() error {
if p.MediaId <= 0 {
return errors.New("media_id必须大于0")
}
if p.Page < 1 || p.Size < 1 || p.Size > 100 {
return errors.New("page必须大于0且size必须在1到100之间")
}
return nil
}
func (p *MediaContentListReq) GetList() (res MediaContentListResp, err error) {
ms := mediaCenter.NewMediaCenterService(mediaCenter.Config{
Url: webg.Conf.MediaResourceDBCfg.BaseUrl,
ProId: webg.Conf.MediaResourceDBCfg.Merchat,
Secret: webg.Conf.MediaResourceDBCfg.Secret,
})
data, err := ms.MediaContentList(&mediaCenter.MediaContentListReq{
MediaId: p.MediaId,
Page: p.Page,
Size: p.Size,
})
if err != nil {
return
}
res.List = data.Data
res.Total = data.Pagination.Count
return
}
type MediaUseReq struct {
Ids []uint `json:"ids" form:"ids"`
Kind int `json:"kind" form:"kind" binding:"required"` //种类(1、哩番,2、3D,3、同人动画,4、单行本,5、连载漫画,6、韩漫 7、小说 8剧场
Type int `json:"type" form:"type" binding:"required"` //维度筛选 1-动漫 2-漫画
Dimension string `json:"dimension" form:"dimension" binding:"required"` //维度
SectionId primitive.ObjectID `json:"section_id" form:"section_id"` //专题id
}
func (p *MediaUseReq) Validate() error {
if len(p.Ids) == 0 || len(p.Ids) > 100 {
return errors.New("ids数量必须在1到100之间")
}
if strings.EqualFold(strings.TrimSpace(p.Dimension), "drama") {
if p.Kind != 8 || p.Type != 1 {
return errors.New("短剧导入时kind必须为8且type必须为1")
}
}
return nil
}
func (p *MediaUseReq) Use(admin string) (err error) {
if err = p.Validate(); err != nil {
return err
}
workerCount := 5
if len(p.Ids) < workerCount {
workerCount = len(p.Ids)
}
jobs := make(chan uint)
errs := make(chan error, len(p.Ids))
var wg sync.WaitGroup
for i := 0; i < workerCount; i++ {
wg.Add(1)
common.Go(func() {
defer wg.Done()
for id := range jobs {
if useErr := use(id, admin, p.Dimension, p.Type, p.Kind, p.SectionId); useErr != nil {
log.Error("MediaUse Fail", log.Any("id", id), log.E(useErr))
errs <- useErr
}
}
})
}
for _, id := range p.Ids {
jobs <- id
}
close(jobs)
wg.Wait()
close(errs)
for useErr := range errs {
if useErr != nil {
return useErr
}
}
return
}
func use(id uint, admin string, dimension string, dimensionType, kind int, sectionId primitive.ObjectID) (err error) {
mediaService := mediaService.NewMediaSync(webg.Redis, mediaCenter.NewMediaCenterService(mediaCenter.Config{
Url: webg.Conf.MediaResourceDBCfg.BaseUrl,
ProId: webg.Conf.MediaResourceDBCfg.Merchat,
Secret: webg.Conf.MediaResourceDBCfg.Secret,
}))
// 调用use接口,在媒资库打上标记,避免还出现在增量数据里
err = mediaService.Ms.MediaUse(&mediaCenter.MediaUseReq{
Ids: []uint{id},
})
if err != nil {
return
}
// 因为需要同步的东西特别多,所以需要异步处理
mediaService.Worker.Exec(func() {
mediaService.UseMediaData(admin, id, dimension, dimensionType, kind, sectionId)
})
return
}
type MediaIgnoreReq struct {
Ids []uint `json:"ids" form:"ids"`
}
func (p *MediaIgnoreReq) Ignore() (err error) {
ms := mediaCenter.NewMediaCenterService(mediaCenter.Config{
Url: webg.Conf.MediaResourceDBCfg.BaseUrl,
ProId: webg.Conf.MediaResourceDBCfg.Merchat,
Secret: webg.Conf.MediaResourceDBCfg.Secret,
})
// 在媒资库打上标记,避免还出现在增量数据里
return ms.MediaIgnore(&mediaCenter.MediaIgnoreReq{
Ids: p.Ids,
})
}
type MediaSyncReq struct {
}
// 执行同步的请求
func (p *MediaSyncReq) Sync(admin string) {
common.Go(func() {
mediaService := mediaService.NewMediaSync(webg.Redis, mediaCenter.NewMediaCenterService(mediaCenter.Config{
Url: webg.Conf.MediaResourceDBCfg.BaseUrl,
ProId: webg.Conf.MediaResourceDBCfg.Merchat,
Secret: webg.Conf.MediaResourceDBCfg.Secret,
}))
mediaService.SyncAll(admin)
})
}