update docker deploy

This commit is contained in:
mubai
2023-07-13 23:49:08 +08:00
parent c4ecdde7f6
commit e111963ffd
37 changed files with 968 additions and 419 deletions

View File

@@ -113,56 +113,7 @@ func SearchFilm(c *gin.Context) {
})
}
// FilmCategory 获取指定分类的影片分页数据,
func FilmCategory(c *gin.Context) {
// 1.1 首先获取Cid 二级分类id是否存在
cidStr := c.DefaultQuery("cid", "")
// 1.2 如果pid也不存在直接返回错误信息
pidStr := c.DefaultQuery("pid", "")
if pidStr == "" {
c.JSON(http.StatusOK, gin.H{
"status": StatusFailed,
"message": "缺少分类信息",
})
return
}
// 1.3 获取pid对应的分类信息
pid, _ := strconv.ParseInt(pidStr, 10, 64)
category := logic.IL.GetPidCategory(pid)
// 2 设置分页信息
currentStr := c.DefaultQuery("current", "1")
current, _ := strconv.Atoi(currentStr)
page := model.Page{PageSize: 49, Current: current}
// 2.1 如果不存在cid则根据Pid进行查询
if cidStr == "" {
// 2.2 如果存在pid则根据pid进行查找
c.JSON(http.StatusOK, gin.H{
"status": StatusOk,
"data": gin.H{
"list": logic.IL.GetFilmCategory(pid, "pid", &page),
"category": category,
"search": logic.IL.SearchTags(pid),
},
"page": page,
})
return
}
// 2.2 如果存在cid 则根据具体的cid去查询数据
cid, _ := strconv.ParseInt(cidStr, 10, 64)
c.JSON(http.StatusOK, gin.H{
"status": StatusOk,
"data": gin.H{
"list": logic.IL.GetFilmCategory(cid, "cid", &page),
"category": category,
"search": logic.IL.SearchTags(pid),
},
"page": page,
})
// 获取请求参数
}
// FilmTagSearch 通过tag获取满足条件的对应影片
func FilmTagSearch(c *gin.Context) {
params := model.SearchTagsVO{}
pidStr := c.DefaultQuery("Pid", "")
@@ -235,3 +186,53 @@ func FilmClassify(c *gin.Context) {
"page": page,
})
}
// FilmCategory 获取指定分类的影片分页数据,(已弃用)
func FilmCategory(c *gin.Context) {
// 1.1 首先获取Cid 二级分类id是否存在
cidStr := c.DefaultQuery("cid", "")
// 1.2 如果pid也不存在直接返回错误信息
pidStr := c.DefaultQuery("pid", "")
if pidStr == "" {
c.JSON(http.StatusOK, gin.H{
"status": StatusFailed,
"message": "缺少分类信息",
})
return
}
// 1.3 获取pid对应的分类信息
pid, _ := strconv.ParseInt(pidStr, 10, 64)
category := logic.IL.GetPidCategory(pid)
// 2 设置分页信息
currentStr := c.DefaultQuery("current", "1")
current, _ := strconv.Atoi(currentStr)
page := model.Page{PageSize: 49, Current: current}
// 2.1 如果不存在cid则根据Pid进行查询
if cidStr == "" {
// 2.2 如果存在pid则根据pid进行查找
c.JSON(http.StatusOK, gin.H{
"status": StatusOk,
"data": gin.H{
"list": logic.IL.GetFilmCategory(pid, "pid", &page),
"category": category,
"search": logic.IL.SearchTags(pid),
},
"page": page,
})
return
}
// 2.2 如果存在cid 则根据具体的cid去查询数据
cid, _ := strconv.ParseInt(cidStr, 10, 64)
c.JSON(http.StatusOK, gin.H{
"status": StatusOk,
"data": gin.H{
"list": logic.IL.GetFilmCategory(cid, "cid", &page),
"category": category,
"search": logic.IL.SearchTags(pid),
},
"page": page,
})
// 获取请求参数
}

View File

@@ -5,11 +5,12 @@ import (
"server/plugin/db"
"server/plugin/spider"
"server/router"
"time"
)
func init() {
// 执行初始化前等待20s , 让mysql服务完成初始化指令
//time.Sleep(time.Second * 20)
time.Sleep(time.Second * 20)
//初始化redis客户端
err := db.InitRedisConn()
if err != nil {
@@ -23,7 +24,6 @@ func init() {
}
func main() {
start()
//spider.MtSiteSpider()
}
func start() {

View File

@@ -209,8 +209,8 @@ func ConvertSearchInfo(detail MovieDetail) SearchInfo {
UpdateStamp: stamp.Unix(),
State: detail.State,
Remarks: detail.Remarks,
// releaseDate 部分影片缺失该参数, 所以使用添加时间作为上映时间排序
ReleaseDate: detail.AddTime,
// ReleaseDate 部分影片缺失该参数, 所以使用添加时间作为上映时间排序
ReleaseStamp: detail.AddTime,
}
}

View File

@@ -19,23 +19,23 @@ import (
// SearchInfo 存储用于检索的信息
type SearchInfo struct {
gorm.Model
Mid int64 `json:"mid" gorm:"uniqueIndex:idx_mid"` //影片ID
Cid int64 `json:"cid"` //分类ID
Pid int64 `json:"pid"` //上级分类ID
Name string `json:"name"` // 片名
SubTitle string `json:"subTitle"` // 影片子标题
CName string `json:"CName"` // 分类名称
ClassTag string `json:"classTag"` //类型标签
Area string `json:"area"` // 地区
Language string `json:"language"` // 语言
Year int64 `json:"year"` // 年份
Initial string `json:"initial"` // 首字母
Score float64 `json:"score"` //评分
UpdateStamp int64 `json:"updateStamp"` // 更新时间
Hits int64 `json:"hits"` // 热度排行
State string `json:"state"` //状态 正片|预告
Remarks string `json:"remarks"` // 完结 | 更新至x集
ReleaseDate int64 `json:"releaseDate"` //上映时间 时间戳
Mid int64 `json:"mid"` //影片ID gorm:"uniqueIndex:idx_mid"
Cid int64 `json:"cid"` //分类ID
Pid int64 `json:"pid"` //上级分类ID
Name string `json:"name"` // 片名
SubTitle string `json:"subTitle"` // 影片子标题
CName string `json:"CName"` // 分类名称
ClassTag string `json:"classTag"` //类型标签
Area string `json:"area"` // 地区
Language string `json:"language"` // 语言
Year int64 `json:"year"` // 年份
Initial string `json:"initial"` // 首字母
Score float64 `json:"score"` //评分
UpdateStamp int64 `json:"updateStamp"` // 更新时间
Hits int64 `json:"hits"` // 热度排行
State string `json:"state"` //状态 正片|预告
Remarks string `json:"remarks"` // 完结 | 更新至x集
ReleaseStamp int64 `json:"releaseStamp"` //上映时间 时间戳
}
// Page 分页信息结构体
@@ -165,9 +165,10 @@ func SaveSearchTag(search SearchInfo) {
case "Sort":
if tagCount == 0 {
tags := []redis.Z{
{2, "时间排序:update_stamp"},
{1, "人气排序:hits"},
{0, "评分排序:score"},
{3, "时间排序:update_stamp"},
{2, "人气排序:hits"},
{1, "评分排序:score"},
{0, "最新上映:release_stamp"},
}
db.Rdb.ZAdd(db.Cxt, fmt.Sprintf(config.SearchTag, search.Pid, k), tags...)
}
@@ -236,6 +237,20 @@ func CreateSearchTable() {
}
}
// AddSearchIndex search表中数据保存完毕后 将常用字段添加索引提高查询效率
func AddSearchIndex() {
var s *SearchInfo
tableName := s.TableName()
// 添加索引
db.Mdb.Exec(fmt.Sprintf("CREATE UNIQUE INDEX idx_mid ON %s (mid)", tableName))
db.Mdb.Exec(fmt.Sprintf("CREATE INDEX idx_time ON %s (update_stamp DESC)", tableName))
db.Mdb.Exec(fmt.Sprintf("CREATE INDEX idx_hits ON %s (hits DESC)", tableName))
db.Mdb.Exec(fmt.Sprintf("CREATE INDEX idx_score ON %s (score DESC)", tableName))
db.Mdb.Exec(fmt.Sprintf("CREATE INDEX idx_release ON %s (release_stamp DESC)", tableName))
db.Mdb.Exec(fmt.Sprintf("CREATE INDEX idx_year ON %s (year DESC)", tableName))
}
// BatchSave 批量保存影片search信息
func BatchSave(list []SearchInfo) {
tx := db.Mdb.Begin()
@@ -266,7 +281,7 @@ func BatchSaveOrUpdate(list []SearchInfo) {
if count > 0 {
// 记录已经存在则执行更新部分内容
err := tx.Model(&SearchInfo{}).Where("mid", info.Mid).Updates(SearchInfo{UpdateStamp: info.UpdateStamp, Hits: info.Hits, State: info.State,
Remarks: info.Remarks, Score: info.Score, ReleaseDate: info.ReleaseDate}).Error
Remarks: info.Remarks, Score: info.Score, ReleaseStamp: info.ReleaseStamp}).Error
if err != nil {
tx.Rollback()
}
@@ -475,28 +490,8 @@ func GetSearchTag(pid int64) map[string]interface{} {
res["titles"] = titles
// 处理单一分类的数据格式
tagMap := make(map[string]interface{})
for k, _ := range titles {
// 通过 k 获取对应的 tag , 并以score进行排序
// 过滤分类tag
switch k {
case "Category":
tags := db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, k), 0, -1).Val()
tagMap[k] = HandleTagStr(k, tags...)
case "Plot":
tags := db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, k), 0, 10).Val()
tagMap[k] = HandleTagStr(k, tags...)
case "Area":
tags := db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, k), 0, 11).Val()
tagMap[k] = HandleTagStr(k, tags...)
case "Language":
tags := db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, k), 0, 6).Val()
tagMap[k] = HandleTagStr(k, tags...)
case "Year", "Initial", "Sort":
tags := db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, k), 0, -1).Val()
tagMap[k] = HandleTagStr(k, tags...)
default:
break
}
for t, _ := range titles {
tagMap[t] = HandleTagStr(t, GetTagsByTitle(pid, t)...)
}
res["tags"] = tagMap
// 分类列表展示的顺序
@@ -504,6 +499,28 @@ func GetSearchTag(pid int64) map[string]interface{} {
return res
}
// GetTagsByTitle 返回Pid和title对应的用于检索的tag
func GetTagsByTitle(pid int64, t string) []string {
// 通过 k 获取对应的 tag , 并以score进行排序
var tags []string
// 过滤分类tag
switch t {
case "Category":
tags = db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, t), 0, -1).Val()
case "Plot":
tags = db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, t), 0, 10).Val()
case "Area":
tags = db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, t), 0, 11).Val()
case "Language":
tags = db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, t), 0, 6).Val()
case "Year", "Initial", "Sort":
tags = db.Rdb.ZRevRange(db.Cxt, fmt.Sprintf(config.SearchTag, pid, t), 0, -1).Val()
default:
break
}
return tags
}
// HandleTagStr 处理tag数据格式
func HandleTagStr(title string, tags ...string) []map[string]string {
var r []map[string]string
@@ -521,7 +538,7 @@ func HandleTagStr(title string, tags ...string) []map[string]string {
})
}
}
if !strings.EqualFold(title, "Sort") && !strings.EqualFold(title, "Year") {
if !strings.EqualFold(title, "Sort") && !strings.EqualFold(title, "Year") && !strings.EqualFold(title, "Category") {
r = append(r, map[string]string{
"Name": "其它",
"Value": "其它",
@@ -541,21 +558,40 @@ func GetSearchInfosByTags(st SearchTagsVO, page *Page) []SearchInfo {
// 如果字段值不为空
value := v.Field(i).Interface()
if !param.IsEmpty(value) {
cName := strings.ToLower(t.Field(i).Name)
switch cName {
case "pid", "cid", "area", "language", "year":
qw = qw.Where(fmt.Sprintf("%s = ?", cName), value)
// 如果value是 其它 则进行特殊处理
var ts []string
if v, flag := value.(string); flag && strings.EqualFold(v, "其它") {
for _, s := range GetTagsByTitle(st.Pid, t.Field(i).Name) {
ts = append(ts, strings.Split(s, ":")[1])
}
}
k := strings.ToLower(t.Field(i).Name)
switch k {
case "pid", "cid", "year":
qw = qw.Where(fmt.Sprintf("%s = ?", k), value)
case "area", "language":
if strings.EqualFold(value.(string), "其它") {
qw = qw.Where(fmt.Sprintf("%s NOT IN ?", k), ts)
break
}
qw = qw.Where(fmt.Sprintf("%s = ?", k), value)
case "plot":
if strings.EqualFold(value.(string), "其它") {
for _, t := range ts {
qw = qw.Where("class_tag NOT LIKE ?", fmt.Sprintf("%%%v%%", t))
}
break
}
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))
break
}
qw.Order(fmt.Sprintf("%v Desc", value))
default:
break
}
//// 处理特殊条件
//if strings.EqualFold(cName, "sort") {
// qw.Order(fmt.Sprintf("year Desc, %v Desc", cName))
//}
}
}
@@ -579,7 +615,7 @@ func GetMovieListBySort(t int, pid int64, page *Page) []MovieBasicInfo {
switch t {
case 0:
// 最新上映 (上映时间)
qw.Order("year DESC, release_date DESC")
qw.Order("year DESC, release_stamp DESC")
case 1:
// 排行榜 (暂定为热度排行)
qw.Order("year DESC, hits DESC")

View File

@@ -1,7 +1,6 @@
package param
import (
"log"
"reflect"
)
@@ -13,7 +12,6 @@ import (
func IsEmpty(target any) bool {
switch target.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64:
log.Println(`target == 0`, target == 0)
return target == reflect.Zero(reflect.TypeOf(target)).Interface()
case string:
return target == ""

View File

@@ -29,8 +29,7 @@ import (
*/
const (
MainSite = "https://cj.lziapi.com/api.php/provide/vod/"
//MainSite = "https://cj.lzcaiji.com/api.php/provide/vod/"
MainSite = "https://cj.lzcaiji.com/api.php/provide/vod/"
)
type Site struct {
@@ -41,15 +40,16 @@ type Site struct {
// SiteList 播放源采集站
var SiteList = []Site{
// 备用采集站
//{"lz_bk", "https://cj.lzcaiji.com/api.php/provide/vod/"},
//{"fs", "https://www.feisuzyapi.com/api.php/provide/vod/"},
//{"su", "https://subocaiji.com/api.php/provide/vod/at/json"},
//{"bf", "https://bfzyapi.com/api.php/provide/vod/"},
//{"ff", "https://cj.ffzyapi.com/api.php/provide/vod/"},
//{"ff", "https://svip.ffzyapi8.com/api.php/provide/vod/"},
//{"lz", "https://cj.lziapi.com/api.php/provide/vod/"},
{"fs", "https://www.feisuzyapi.com/api.php/provide/vod/"},
{"bf", "http://by.bfzyapi.com/api.php/provide/vod/"},
{"kk", "https://kuaikan-api.com/api.php/provide/vod/from/kuaikan"},
{"bf", "http://by.bfzyapi.com/api.php/provide/vod/"},
{"ff", "https://cj.ffzyapi.com/api.php/provide/vod/"},
}
// StartSpider 执行多源spider
@@ -60,15 +60,16 @@ func StartSpider() {
// 爬取主站点数据
MainSiteSpider()
log.Println("MainSiteSpider 主站点影片信息保存完毕")
// 查找并创建search数据库
// 查找并创建search数据库, 保存search信息, 添加索引
time.Sleep(time.Second * 10)
model.CreateSearchTable()
SearchInfoToMdb()
model.AddSearchIndex()
log.Println("SearchInfoToMdb 影片检索信息保存完毕")
// 获取其他站点数据13
//go MtSiteSpider()
//log.Println("Spider End , 数据保存执行完成")
//time.Sleep(time.Second * 10)
//获取其他站点数据13
go MtSiteSpider()
log.Println("Spider End , 数据保存执行完成")
time.Sleep(time.Second * 10)
}
// CategoryList 获取分类数据

View File

@@ -18,9 +18,10 @@ func SetupRouter() *gin.Engine {
r.GET(`/filmDetail`, controller.FilmDetail)
r.GET(`/filmPlayInfo`, controller.FilmPlayInfo)
r.GET(`/searchFilm`, controller.SearchFilm)
r.GET(`/filmCategory`, controller.FilmCategory)
r.GET(`/filmClassify`, controller.FilmClassify)
r.GET(`/filmClassifySearch`, controller.FilmTagSearch)
// 弃用
//r.GET(`/filmCategory`, controller.FilmCategory)
// 触发spider
spiderRoute := r.Group(`/spider`)