fix default playSource and update upload manage

This commit is contained in:
mubai
2024-01-04 00:47:29 +08:00
parent 615cdf6d02
commit 31955638a5
34 changed files with 504 additions and 318 deletions

View File

@@ -15,20 +15,6 @@ const (
// MAXGoroutine max goroutine, 执行spider中对协程的数量限制
MAXGoroutine = 10
// CornMovieUpdate 影片更新定时任务间隔
CornMovieUpdate = "0 0/20 * * * ?"
// UpdateInterval 获取最近几小时更新的影片 (h 小时) 默认3小时
UpdateInterval = "3"
// CornUpdateAll 每月28执行一次清库更新
CornUpdateAll = "0 0 2 28 * ?"
// SpiderCipher 设置Spider触发指令的验证
SpiderCipher = "Life in a different world from zero"
// ImgCacheFlag 是否开启将主站影片图片放入本地进行存储
ImgCacheFlag = false
//ImageDir = "./resource/static/images"
FilmPictureUploadDir = "./static/upload/gallery"
FilmPictureUrlPath = "/upload/pic/poster/"
FilmPictureAccess = "/api/upload/pic/poster/"
@@ -62,15 +48,6 @@ const (
VirtualPictureKey = "VirtualPicture"
// MaxScanCount redis Scan 操作每次扫描的数据量, 每次最多扫描300条数据
MaxScanCount = 300
// SearchCount Search scan 识别范围
SearchCount = 3000
// SearchKeys Search Key Hash
SearchKeys = "SearchKeys"
// SearchScoreListKey 根据评分检索的key
SearchScoreListKey = "Search:SearchScoreList"
SearchTimeListKey = "Search:SearchTimeList"
SearchHeatListKey = "Search:SearchHeatList"
)
const (
@@ -106,7 +83,7 @@ const (
SearchTableName = "search"
UserTableName = "users"
UserIdInitialVal = 10000
PictureTableName = "picture"
FileTableName = "files"
//mysql服务配置信息 root:root 设置mysql账户的用户名和密码

View File

@@ -8,6 +8,7 @@ import (
"server/logic"
"server/model/system"
"server/plugin/common/util"
"strconv"
)
// SingleUpload 单文件上传, 暂定为图片上传
@@ -24,13 +25,6 @@ func SingleUpload(c *gin.Context) {
system.Failed(err.Error(), c)
return
}
// 创建文件保存路径, 如果不存在则创建
//if _, err = os.Stat(config.ImageDir); os.IsNotExist(err) {
// err = os.MkdirAll(config.ImageDir, os.ModePerm)
// if err != nil {
// return
// }
//}
// 生成文件名, 保存文件到服务器
fileName := fmt.Sprintf("%s/%s%s", config.FilmPictureUploadDir, util.RandomString(8), filepath.Ext(file.Filename))
@@ -48,12 +42,68 @@ func SingleUpload(c *gin.Context) {
}
// MultipleUpload 批量文件上传
func MultipleUpload(c *gin.Context) {
// 获取执行操作的用户信息
v, ok := c.Get(config.AuthUserClaims)
if !ok {
system.Failed("上传失败, 当前用户信息异常", c)
return
}
// 解析表单数据
form, err := c.MultipartForm()
if err != nil {
system.Failed(err.Error(), c)
return
}
// 获取文件列表
files := form.File["files"]
// 解析当前登录的用户信息
uc := v.(*system.UserClaims)
// 遍历文件列表
var fileNames []string
for _, file := range files {
// 生成文件名, 保存文件到服务器
fileName := fmt.Sprintf("%s/%s%s", config.FilmPictureUploadDir, util.RandomString(8), filepath.Ext(file.Filename))
err = c.SaveUploadedFile(file, fileName)
if err != nil {
system.Failed(err.Error(), c)
return
}
// 记录图片信息到系统表中, 并获取返回的图片访问路径
fileNames = append(fileNames, logic.FileL.SingleFileUpload(fileName, int(uc.UserID)))
}
// 返回图片访问地址以及成功的响应
system.Success(fileNames, "上传成功", c)
}
// DelFile 删除文件
func DelFile(c *gin.Context) {
id, err := strconv.ParseUint(c.DefaultQuery("id", ""), 10, 64)
if err != nil {
system.Failed("操作失败, 未获取到需删除的文件标识信息", c)
return
}
if e := logic.FileL.RemoveFileById(uint(id)); e != nil {
system.Failed(fmt.Sprint("删除失败", e.Error()), c)
return
}
system.SuccessOnlyMsg("文件已删除", c)
}
// PhotoWall 照片墙数据
func PhotoWall(c *gin.Context) {
current, err := strconv.Atoi(c.DefaultQuery("current", "1"))
if err != nil {
system.Failed("图片分页数据获取失败, 分页参数异常", c)
return
}
// 获取系统保存的文件的图片分页数据
page := system.Page{PageSize: 10, Current: 1}
page := system.Page{PageSize: 39, Current: current}
// 获取分页数据
pl := logic.FileL.GetPhotoPage(&page)
system.Success(pl, "图片分页数据获取成功", c)
system.Success(gin.H{"list": pl, "page": page}, "图片分页数据获取成功", c)
}

View File

@@ -70,6 +70,11 @@ func FilmPlayInfo(c *gin.Context) {
}
// 获取影片详情信息
detail := logic.IL.GetFilmDetail(id)
// 如果 playFrom 为空, 则设置默认播放源和默认影片数据
if len(playFrom) <= 1 && len(detail.List) > 0 {
playFrom = detail.List[0].Id
}
// 获取当前影片播放信息
var currentPlay system.MovieUrlInfo
for _, v := range detail.List {

View File

@@ -5,6 +5,7 @@ import (
"path/filepath"
"server/config"
"server/model/system"
"server/plugin/common/util"
"strings"
)
@@ -15,15 +16,31 @@ var FileL FileLogic
func (fl *FileLogic) SingleFileUpload(fileName string, uid int) string {
// 生成图片信息
var p = system.Picture{Link: fmt.Sprint(config.FilmPictureAccess, filepath.Base(fileName)), Uid: uid, PicType: 0}
p.PicUid = strings.TrimSuffix(filepath.Base(fileName), filepath.Ext(fileName))
var f = system.FileInfo{Link: fmt.Sprint(config.FilmPictureAccess, filepath.Base(fileName)), Uid: uid, Type: 0}
f.Fid = strings.TrimSuffix(filepath.Base(fileName), filepath.Ext(fileName))
f.FileType = strings.TrimPrefix(filepath.Ext(fileName), ".")
// 记录图片信息到系统表中
system.SaveGallery(p)
return p.Link
system.SaveGallery(f)
return f.Link
}
// GetPhotoPage 获取系统内的图片分页信息
func (fl *FileLogic) GetPhotoPage(page *system.Page) []system.Picture {
return system.GetPicturePage(page)
func (fl *FileLogic) GetPhotoPage(page *system.Page) []system.FileInfo {
// 设置必要参数
var tl = []string{"jpeg", "jpg", "png", "webp"}
return system.GetFileInfoPage(tl, page)
}
// RemoveFileById 删除文件信息
func (fl *FileLogic) RemoveFileById(id uint) error {
// 首先获取对应图片信息
f := system.GetFileInfoById(id)
// 通过f删除本地图片
err := util.RemoveFile(f.StoragePath())
if err != nil {
return err
}
// 删除图片的关联信息
system.DelFileInfo(id)
return err
}

View File

@@ -22,8 +22,6 @@ var IL *IndexLogic
// IndexPage 首页数据处理
func (i *IndexLogic) IndexPage() map[string]interface{} {
//声明返回值
//Info := make(map[string]interface{})
// 首页请求时长较高, 采用redis进行缓存, 在定时任务更新影片时清除对应缓存
// 判断是否存在缓存数据, 存在则直接将数据返回
Info := system.GetCacheData(config.IndexCacheKey)
@@ -34,21 +32,14 @@ func (i *IndexLogic) IndexPage() map[string]interface{} {
// 1. 首页分类数据处理 导航分类数据处理, 只提供 电影 电视剧 综艺 动漫 四大顶级分类和其子分类
tree := system.CategoryTree{Category: &system.Category{Id: 0, Name: "分类信息"}}
sysTree := system.GetCategoryTree()
// 由于采集源数据格式不一,因此采用名称匹配
//for _, c := range sysTree.Children {
// switch c.Category.Name {
// case "电影", "电影片", "连续剧", "电视剧", "综艺", "综艺片", "动漫", "动漫片":
// tree.Children = append(tree.Children, c)
// }
//}
// 只展示show=true的分页影片信息
for _, c := range sysTree.Children {
// 只针对一级分类进行处理
if c.Show {
tree.Children = append(tree.Children, c)
}
}
// 返回分类信息
Info["category"] = tree
// 2. 提供用于首页展示的顶级分类影片信息, 每分类 14条数据
var list []map[string]interface{}
@@ -62,7 +53,7 @@ func (i *IndexLogic) IndexPage() map[string]interface{} {
}
Info["content"] = list
// 不存在首页数据缓存时将查询数据缓存到redis中
//system.DataCache(config.IndexCacheKey, Info)
system.DataCache(config.IndexCacheKey, Info)
return Info
}

View File

@@ -6,21 +6,24 @@ import (
"github.com/redis/go-redis/v9"
"gorm.io/gorm"
"log"
"path/filepath"
"regexp"
"server/config"
"server/plugin/common/util"
"server/plugin/db"
"strings"
)
// Picture 图片信息对象
type Picture struct {
// FileInfo 图片信息对象
type FileInfo struct {
gorm.Model
Link string `json:"link"` // 图片链接
Uid int `json:"uid"` // 上传人ID
RelevanceId int64 `json:"relevanceId"` // 关联资源ID
PicType int `json:"picType"` // 图片类型 (0 影片封面, 1 用户头像)
PicUid string `json:"picUid"` // 图片唯一标识, 通常为文件名
//Size int `json:"size"` // 图片大小
Type int `json:"type"` // 文件类型 (0 影片封面, 1 用户头像)
Fid string `json:"fid"` // 图片唯一标识, 通常为文件名
FileType string `json:"fileType"` // 文件类型, txt, png, jpg
//Size int `json:"size"` // 文件大小
}
// VirtualPicture 采集入站,待同步的图片信息
@@ -32,57 +35,80 @@ type VirtualPicture struct {
//------------------------------------------------本地图库------------------------------------------------
// TableName 设置图片存储表的表名
func (p *Picture) TableName() string {
return config.PictureTableName
func (f *FileInfo) TableName() string {
return config.FileTableName
}
// CreatePictureTable 创建图片关联信息存储表
func CreatePictureTable() {
// StoragePath 获取文件的保存路径
func (f *FileInfo) StoragePath() string {
var storage string
switch f.FileType {
case "jpeg", "jpg", "png", "webp":
storage = strings.Replace(f.Link, config.FilmPictureAccess, fmt.Sprint(config.FilmPictureUploadDir, "/"), 1)
default:
}
return storage
}
// CreateFileTable 创建图片关联信息存储表
func CreateFileTable() {
// 如果不存在则创建表 并设置自增ID初始值为10000
if !ExistPictureTable() {
err := db.Mdb.AutoMigrate(&Picture{})
if !ExistFileTable() {
err := db.Mdb.AutoMigrate(&FileInfo{})
if err != nil {
log.Println("Create Table Picture Failed: ", err)
log.Println("Create Table FileInfo Failed: ", err)
}
}
}
// ExistPictureTable 是否存在Picture表
func ExistPictureTable() bool {
// ExistFileTable 是否存在Picture表
func ExistFileTable() bool {
// 1. 判断表中是否存在当前表
return db.Mdb.Migrator().HasTable(&Picture{})
return db.Mdb.Migrator().HasTable(&FileInfo{})
}
// SaveGallery 保存图片关联信息
func SaveGallery(p Picture) {
db.Mdb.Create(&p)
func SaveGallery(f FileInfo) {
db.Mdb.Create(&f)
}
// ExistPictureByRid 查找图片信息是否存在
func ExistPictureByRid(rid int64) bool {
// ExistFileInfoByRid 查找图片信息是否存在
func ExistFileInfoByRid(rid int64) bool {
var count int64
db.Mdb.Model(&Picture{}).Where("relevance_id = ?", rid).Count(&count)
db.Mdb.Model(&FileInfo{}).Where("relevance_id = ?", rid).Count(&count)
return count > 0
}
// GetPictureByRid 通过关联的资源id获取对应的图片信息
func GetPictureByRid(rid int64) Picture {
var p Picture
db.Mdb.Where("relevance_id = ?", rid).First(&p)
return p
// GetFileInfoByRid 通过关联的资源id获取对应的图片信息
func GetFileInfoByRid(rid int64) FileInfo {
var f FileInfo
db.Mdb.Where("relevance_id = ?", rid).First(&f)
return f
}
func GetPicturePage(page *Page) []Picture {
var pl []Picture
query := db.Mdb.Model(&Picture{})
// GetFileInfoById 通过ID获取对应的图片信息
func GetFileInfoById(id uint) FileInfo {
var f = FileInfo{}
db.Mdb.First(&f, id)
return f
}
// GetFileInfoPage 获取文件关联信息分页数据
func GetFileInfoPage(tl []string, page *Page) []FileInfo {
var fl []FileInfo
query := db.Mdb.Model(&FileInfo{}).Where("file_type IN ?", tl).Order("id DESC")
// 获取分页相关参数
GetPage(query, page)
// 获取分页数据
if err := query.Limit(page.PageSize).Offset((page.Current - 1) * page.PageSize).Find(&pl).Error; err != nil {
if err := query.Limit(page.PageSize).Offset((page.Current - 1) * page.PageSize).Find(&fl).Error; err != nil {
log.Println(err)
return nil
}
return pl
return fl
}
func DelFileInfo(id uint) {
db.Mdb.Unscoped().Delete(&FileInfo{}, id)
}
//------------------------------------------------图片同步------------------------------------------------
@@ -123,7 +149,7 @@ func SyncFilmPicture() {
vp := VirtualPicture{}
_ = json.Unmarshal([]byte(s.Member.(string)), &vp)
// 判断当前影片是否已经同步过图片, 如果已经同步则直接跳过后续逻辑
if ExistPictureByRid(vp.Id) {
if ExistFileInfoByRid(vp.Id) {
continue
}
// 将图片同步到服务器中
@@ -132,12 +158,13 @@ func SyncFilmPicture() {
continue
}
// 完成同步后将图片信息保存到 Gallery 中
SaveGallery(Picture{
SaveGallery(FileInfo{
Link: fmt.Sprint(config.FilmPictureAccess, fileName),
Uid: config.UserIdInitialVal,
RelevanceId: vp.Id,
PicType: 0,
PicUid: regexp.MustCompile(`\.[^.]+$`).ReplaceAllString(fileName, ""),
Type: 0,
Fid: regexp.MustCompile(`\.[^.]+$`).ReplaceAllString(fileName, ""),
FileType: strings.TrimPrefix(filepath.Ext(fileName), "."),
})
}
// 递归执行直到图片暂存信息为空
@@ -147,21 +174,21 @@ func SyncFilmPicture() {
// ReplaceDetailPic 将影片详情中的图片地址替换为自己的
func ReplaceDetailPic(d *MovieDetail) {
// 查询影片对应的本地图片信息
if ExistPictureByRid(d.Id) {
if ExistFileInfoByRid(d.Id) {
// 如果存在关联的本地图片, 则查询对应的图片信息
p := GetPictureByRid(d.Id)
f := GetFileInfoByRid(d.Id)
// 替换采集站的图片链接为本地链接
d.Picture = p.Link
d.Picture = f.Link
}
}
// ReplaceBasicDetailPic 替换影片基本数据中的封面图为本地图片
func ReplaceBasicDetailPic(d *MovieBasicInfo) {
// 查询影片对应的本地图片信息
if ExistPictureByRid(d.Id) {
if ExistFileInfoByRid(d.Id) {
// 如果存在关联的本地图片, 则查询对应的图片信息
p := GetPictureByRid(d.Id)
f := GetFileInfoByRid(d.Id)
// 替换采集站的图片链接为本地链接
d.Picture = p.Link
d.Picture = f.Link
}
}

View File

@@ -640,10 +640,10 @@ func GetSearchInfosByTags(st SearchTagsVO, page *Page) []SearchInfo {
qw = qw.Where("class_tag LIKE ?", fmt.Sprintf("%%%v%%", value))
case "sort":
if strings.EqualFold(value.(string), "release_stamp") {
qw.Order(fmt.Sprintf("year DESC ,%v Desc", value))
qw.Order(fmt.Sprintf("year DESC ,%v DESC", value))
break
}
qw.Order(fmt.Sprintf("%v Desc", value))
qw.Order(fmt.Sprintf("%v DESC", value))
default:
break
}

View File

@@ -11,5 +11,5 @@ func TableInIt() {
// 创建 Search Table
system.CreateSearchTable()
// 创建图片信息管理表
system.CreatePictureTable()
system.CreateFileTable()
}

View File

@@ -22,8 +22,8 @@ func FilmSourceInit() {
}
var l []system.FilmSource = []system.FilmSource{
{Id: util.GenerateSalt(), Name: "HD(lzBk)", Uri: `https://cj.lzcaiji.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
{Id: util.GenerateSalt(), Name: "HD(sn)", Uri: `https://suoniapi.com/api.php/provide/vod/from/snm3u8/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
{Id: util.GenerateSalt(), Name: "HD(bf)", Uri: `https://bfzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true, Interval: 1600},
{Id: util.GenerateSalt(), Name: "HD(sn)", Uri: `https://suoniapi.com/api.php/provide/vod/from/snm3u8/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true, Interval: 2000},
{Id: util.GenerateSalt(), Name: "HD(bf)", Uri: `https://bfzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true, Interval: 2500},
{Id: util.GenerateSalt(), Name: "HD(ff)", Uri: `http://cj.ffzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
{Id: util.GenerateSalt(), Name: "HD(kk)", Uri: `https://kuaikan-api.com/api.php/provide/vod/from/kuaikan/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
//{Id: util.GenerateSalt(), Name: "HD(lz)", Uri: `https://cj.lziapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},

View File

@@ -51,3 +51,8 @@ func CreateBaseDir() error {
}
return nil
}
func RemoveFile(path string) error {
err := os.Remove(path)
return err
}

View File

@@ -201,10 +201,17 @@ func BatchCollect(h int, ids ...string) {
for _, id := range ids {
// 如果查询到对应Id的资源站信息, 且资源站处于启用状态
if fs := system.FindCollectSourceById(id); fs != nil && fs.State {
// 采用协程并发执行, 每个站点单独开启一个协程执行
go func() {
err := HandleCollect(fs.Id, h)
if err != nil {
log.Println(err)
}
}()
// 执行当前站点的采集任务
if err := HandleCollect(fs.Id, h); err != nil {
log.Println(err)
}
//if err := HandleCollect(fs.Id, h); err != nil {
// log.Println(err)
//}
}
}
}

View File

@@ -95,6 +95,8 @@ func SetupRouter() *gin.Engine {
fileRoute := manageRoute.Group(`/file`)
{
fileRoute.POST(`/upload`, controller.SingleUpload)
fileRoute.GET(`/upload/multiple`, controller.MultipleUpload)
fileRoute.GET(`/del`, controller.DelFile)
fileRoute.GET(`/list`, controller.PhotoWall)
}