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) }) }