mirror of
https://github.com/ProudMuBai/GoFilm.git
synced 2026-06-06 01:03:09 +08:00
optimize updates
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -22,6 +22,8 @@ package-lock.json
|
||||
|
||||
.idea/
|
||||
.idea
|
||||
.vscode
|
||||
.vscode/
|
||||
# 文件保留路径
|
||||
static/
|
||||
|
||||
|
||||
33
README.md
33
README.md
@@ -16,6 +16,22 @@
|
||||
|
||||
|
||||
|
||||
## 项目部署
|
||||
|
||||
**部署方式**
|
||||
|
||||
- [Docker部署](https://github.com/ProudMuBai/GoFilm/blob/main/film/README.md)
|
||||
- [1Panel部署(可视化面板操作)](https://blog.mubai.link/2024/04/21/Docs/gofilm/)
|
||||
|
||||
**使用指南**
|
||||
|
||||
- 后端项目路径 `GoFilm/server`, 包含 项目结构说明, 后端程序源码, API接口说明, 本地启动注意事项 [查看](https://github.com/ProudMuBai/GoFilm/tree/main/server)
|
||||
- 前端项目路径 `GoFilm/client`, 包含 项目结构说明, 前端项目源码, 配置文件说明, 本地启动方式 [查看](https://github.com/ProudMuBai/GoFilm/tree/main/client)
|
||||
- 部署文件 `GoFilm/film`, 包含项目部署所需的所有文件以及相应的说明文件 [查看](https://github.com/ProudMuBai/GoFilm/tree/main/film)
|
||||
- 程序使用文档: 提供项目安装部署以及相应的初始化使用步骤说明 [点击前往](https://blog.mubai.link/2024/04/21/Docs/gofilm/)
|
||||
|
||||
|
||||
|
||||
## 新版本说明
|
||||
|
||||
**网站前台**
|
||||
@@ -24,7 +40,7 @@
|
||||
|
||||
- 前台部分对网站名称以及播放源等部分信息与后台数据进行关联, 可通过后台进行修改
|
||||
- 影片详情部分以及首页导航数据结构发生变化, 样式保持一致
|
||||
- 默认访问地址: `服务器IP:默认端口 [http://127.0.0.1:3600]`
|
||||
- 默认访问地址: `服务器IP:默认端口 [http://127.0.0.1/index]`
|
||||
|
||||
**管理后台**
|
||||
|
||||
@@ -41,14 +57,19 @@
|
||||
|
||||
>新增内容:
|
||||
>
|
||||
>- 新增详细部署说明文档, 以及 `1Panel部署方式` , [点击查看](https://blog.mubai.link/2024/04/21/Docs/gofilm/)
|
||||
>- 修复pc端历史记录异常问题, 新增移动端历史记录功能, 以及底部功能组(部分实现)
|
||||
>- 优化pc以及移动端的卡片内容展示效果
|
||||
>- 新增移动端观看历史
|
||||
>- 新增采集失败记录功能 && 基于失败的采集进行重新采集处理
|
||||
>- 默认定时任务新增定期处理失败采集功能
|
||||
>- 修复Banner首页轮播横幅参数修改提交异常问题
|
||||
>- 修复首页一级分类导航无数据问题
|
||||
>- 修复首页界面影片信息卡片异常显示问题
|
||||
>- 优化影片详情以及播放页的组件背景显示问题
|
||||
>
|
||||
>后续计划:
|
||||
>
|
||||
>- 优先针对手机端主页以及导航做修改
|
||||
>- 同步手机端历史记录功能
|
||||
>- 新增功能测试 && buf修复
|
||||
>- 完善历史观看界面功能 && 优化相应UI组件
|
||||
>- 针对播放器进行优化 OR 更换播放器组件
|
||||
>- 采集方式细节化, 实现定向采集以及单一影片的实时手动更新功能
|
||||
|
||||
## 目录结构
|
||||
|
||||
@@ -27,9 +27,8 @@
|
||||
<template v-if="item.nav.show">
|
||||
<el-row class="row-bg cus_nav" justify="space-between">
|
||||
<el-col :span="12" class="title">
|
||||
<span
|
||||
:class="`iconfont ${item.nav.name.search('电影') != -1?'icon-film':item.nav.name.search('剧') != -1?'icon-tv':item.nav.name.search('动漫')!= -1?'icon-cartoon':'icon-variety'}`"
|
||||
style="color: #79bbff;font-size: 32px;margin-right: 10px; line-height: 130%"/>
|
||||
<span :class="`iconfont ${item.nav.name.search('电影') != -1?'icon-film':item.nav.name.search('剧') != -1?'icon-tv':item.nav.name.search('动漫')!= -1?'icon-cartoon':'icon-variety'}`"
|
||||
style="color: #79bbff;font-size: 32px;margin-right: 10px; line-height: 130%"/>
|
||||
<a :href="`/filmClassify?Pid=${item.nav.id}`">{{ item.nav.name }}</a>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<el-dialog v-model="data.dialogV.addV" width="680px" title="添加海报">
|
||||
<el-form :model="data.banner">
|
||||
<el-form-item label="影片ID ">
|
||||
<el-input v-model="data.banner.mid" placeholder="影片唯一ID"/>
|
||||
<el-input v-model.number="data.banner.mid" placeholder="影片唯一ID"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="影片名称">
|
||||
<el-input v-model="data.banner.name" placeholder="影片名称"/>
|
||||
@@ -138,7 +138,7 @@
|
||||
<el-dialog v-model="data.dialogV.editV" width="680px" title="修改海报信息">
|
||||
<el-form :model="data.banner">
|
||||
<el-form-item label="影片ID ">
|
||||
<el-input v-model="data.banner.mid" placeholder="影片唯一ID"/>
|
||||
<el-input v-model.number="data.banner.mid" placeholder="影片唯一ID"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="影片名称">
|
||||
<el-input v-model="data.banner.name" placeholder="影片名称"/>
|
||||
|
||||
File diff suppressed because one or more lines are too long
128
film/data/nginx/html/assets/index-71fe0e9a.js
Normal file
128
film/data/nginx/html/assets/index-71fe0e9a.js
Normal file
File diff suppressed because one or more lines are too long
1
film/data/nginx/html/assets/index-b0d2aea4.css
Normal file
1
film/data/nginx/html/assets/index-b0d2aea4.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -11,8 +11,8 @@
|
||||
<meta charset="UTF-8"/>
|
||||
<title>(╥﹏╥)</title>
|
||||
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_3992367_d9xdu8zk04f.css">
|
||||
<script type="module" crossorigin src="/assets/index-c9db717b.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-55e1c426.css">
|
||||
<script type="module" crossorigin src="/assets/index-71fe0e9a.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-b0d2aea4.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -69,6 +69,8 @@ const (
|
||||
FilmCrontabKey = "Cron:Task:Film"
|
||||
// DefaultUpdateSpec 每20分钟执行一次
|
||||
DefaultUpdateSpec = "0 */20 * * * ?"
|
||||
// EveryWeekSpec 每周日凌晨4点更新一次
|
||||
EveryWeekSpec = "0 0 4 * * 0"
|
||||
// DefaultUpdateTime 每次采集最近 3 小时内更新的影片
|
||||
DefaultUpdateTime = 3
|
||||
)
|
||||
@@ -82,10 +84,11 @@ const (
|
||||
// -------------------------Database Connection Params-----------------------------------
|
||||
const (
|
||||
// SearchTableName 存放检索信息的数据表名
|
||||
SearchTableName = "search"
|
||||
UserTableName = "users"
|
||||
UserIdInitialVal = 10000
|
||||
FileTableName = "files"
|
||||
SearchTableName = "search"
|
||||
UserTableName = "users"
|
||||
UserIdInitialVal = 10000
|
||||
FileTableName = "files"
|
||||
FailureRecordTableName = "failure_records"
|
||||
|
||||
//mysql服务配置信息 root:root 设置mysql账户的用户名和密码
|
||||
|
||||
|
||||
283
film/server/controller/CollectController.go
Normal file
283
film/server/controller/CollectController.go
Normal file
@@ -0,0 +1,283 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"server/logic"
|
||||
"server/model/system"
|
||||
"server/plugin/spider"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ------------------------------------------------------ 影视采集 ------------------------------------------------------
|
||||
|
||||
// FilmSourceList 采集站点信息
|
||||
func FilmSourceList(c *gin.Context) {
|
||||
system.Success(logic.CollectL.GetFilmSourceList(), "影视源站点信息获取成功", c)
|
||||
return
|
||||
}
|
||||
|
||||
// FindFilmSource 通过ID返回对应的资源站数据
|
||||
func FindFilmSource(c *gin.Context) {
|
||||
id := c.Query("id")
|
||||
if id == "" {
|
||||
system.Failed("参数异常, 资源站标识不能为空", c)
|
||||
return
|
||||
}
|
||||
fs := logic.CollectL.GetFilmSource(id)
|
||||
if fs == nil {
|
||||
system.Failed("数据异常,资源站信息不存在", c)
|
||||
return
|
||||
}
|
||||
system.Success(fs, "原站点详情信息查找成功", c)
|
||||
}
|
||||
|
||||
// FilmSourceAdd 添加采集源
|
||||
func FilmSourceAdd(c *gin.Context) {
|
||||
var s = system.FilmSource{}
|
||||
// 获取请求参数
|
||||
if err := c.ShouldBindJSON(&s); err != nil {
|
||||
system.Failed("请求参数异常", c)
|
||||
return
|
||||
}
|
||||
// 校验必要参数
|
||||
if err := validFilmSource(s); err != nil {
|
||||
system.Failed(err.Error(), c)
|
||||
return
|
||||
}
|
||||
// 如果采集站开启图片同步, 且采集站为附属站点则返回错误提示
|
||||
if s.SyncPictures && (s.Grade == system.SlaveCollect) {
|
||||
system.Failed("附属站点无法开启图片同步功能", c)
|
||||
return
|
||||
}
|
||||
// 执行 spider
|
||||
if err := spider.CollectApiTest(s); err != nil {
|
||||
system.Failed("资源接口测试失败, 请确认接口有效再添加", c)
|
||||
return
|
||||
}
|
||||
// 测试通过后将资源站信息添加到list
|
||||
if err := logic.CollectL.SaveFilmSource(s); err != nil {
|
||||
system.Failed(fmt.Sprint("资源站添加失败: ", err.Error()), c)
|
||||
return
|
||||
}
|
||||
system.SuccessOnlyMsg("添加成功", c)
|
||||
}
|
||||
|
||||
// FilmSourceUpdate 采集站点信息更新
|
||||
func FilmSourceUpdate(c *gin.Context) {
|
||||
var s = system.FilmSource{}
|
||||
// 获取请求参数
|
||||
if err := c.ShouldBindJSON(&s); err != nil {
|
||||
system.Failed("请求参数异常", c)
|
||||
return
|
||||
}
|
||||
// 校验必要参数
|
||||
if err := validFilmSource(s); err != nil {
|
||||
system.Failed(err.Error(), c)
|
||||
return
|
||||
}
|
||||
// 如果采集站开启图片同步, 且采集站为附属站点则返回错误提示
|
||||
if s.SyncPictures && (s.Grade == system.SlaveCollect) {
|
||||
system.Failed("附属站点无法开启图片同步功能", c)
|
||||
return
|
||||
}
|
||||
// 校验Id信息是否为空
|
||||
if s.Id == "" {
|
||||
system.Failed("参数异常, 资源站标识不能为空", c)
|
||||
return
|
||||
}
|
||||
fs := logic.CollectL.GetFilmSource(s.Id)
|
||||
if fs == nil {
|
||||
system.Failed("数据异常,资源站信息不存在", c)
|
||||
return
|
||||
}
|
||||
// 如果 uri发生变更则执行spider测试
|
||||
if fs.Uri != s.Uri {
|
||||
// 执行 spider
|
||||
if err := spider.CollectApiTest(s); err != nil {
|
||||
system.Failed("资源接口测试失败, 请确认更新的数据接口是否有效", c)
|
||||
return
|
||||
}
|
||||
}
|
||||
// 更新资源站信息
|
||||
if err := logic.CollectL.UpdateFilmSource(s); err != nil {
|
||||
system.Failed(fmt.Sprint("资源站更新失败: ", err.Error()), c)
|
||||
return
|
||||
}
|
||||
system.SuccessOnlyMsg("更新成功", c)
|
||||
}
|
||||
|
||||
// FilmSourceChange 采集站点状态变更
|
||||
func FilmSourceChange(c *gin.Context) {
|
||||
var s = system.FilmSource{}
|
||||
// 获取请求参数
|
||||
if err := c.ShouldBindJSON(&s); err != nil {
|
||||
system.Failed("请求参数异常", c)
|
||||
return
|
||||
}
|
||||
if s.Id == "" {
|
||||
system.Failed("参数异常, 资源站标识不能为空", c)
|
||||
return
|
||||
}
|
||||
// 查找对应的资源站点信息
|
||||
fs := logic.CollectL.GetFilmSource(s.Id)
|
||||
if fs == nil {
|
||||
system.Failed("数据异常,资源站信息不存在", c)
|
||||
return
|
||||
}
|
||||
// 如果采集站开启图片同步, 且采集站为附属站点则返回错误提示
|
||||
if s.SyncPictures && (fs.Grade == system.SlaveCollect) {
|
||||
system.Failed("附属站点无法开启图片同步功能", c)
|
||||
return
|
||||
}
|
||||
if s.State != fs.State || s.SyncPictures != fs.SyncPictures {
|
||||
// 执行更新操作
|
||||
s := system.FilmSource{Id: fs.Id, Name: fs.Name, Uri: fs.Uri, ResultModel: fs.ResultModel,
|
||||
Grade: fs.Grade, SyncPictures: s.SyncPictures, CollectType: fs.CollectType, State: s.State}
|
||||
// 更新资源站信息
|
||||
if err := logic.CollectL.UpdateFilmSource(s); err != nil {
|
||||
system.Failed(fmt.Sprint("资源站更新失败: ", err.Error()), c)
|
||||
return
|
||||
}
|
||||
}
|
||||
system.SuccessOnlyMsg("更新成功", c)
|
||||
}
|
||||
|
||||
// FilmSourceDel 采集站点删除
|
||||
func FilmSourceDel(c *gin.Context) {
|
||||
id := c.Query("id")
|
||||
if len(id) <= 0 {
|
||||
system.Failed("资源站ID信息不能为空", c)
|
||||
return
|
||||
}
|
||||
if err := logic.CollectL.DelFilmSource(id); err != nil {
|
||||
system.Failed("删除资源站失败", c)
|
||||
return
|
||||
}
|
||||
system.SuccessOnlyMsg("删除成功", c)
|
||||
}
|
||||
|
||||
// FilmSourceTest 测试影视站点数据是否可用
|
||||
func FilmSourceTest(c *gin.Context) {
|
||||
var s = system.FilmSource{}
|
||||
// 获取请求参数
|
||||
if err := c.ShouldBindJSON(&s); err != nil {
|
||||
system.Failed("请求参数异常", c)
|
||||
return
|
||||
}
|
||||
// 校验必要参数
|
||||
if err := validFilmSource(s); err != nil {
|
||||
system.Failed(err.Error(), c)
|
||||
return
|
||||
}
|
||||
// 执行 spider
|
||||
if err := spider.CollectApiTest(s); err != nil {
|
||||
system.Failed(err.Error(), c)
|
||||
return
|
||||
}
|
||||
system.SuccessOnlyMsg("测试成功!!!", c)
|
||||
}
|
||||
|
||||
// GetNormalFilmSource 获取状态为启用的采集站信息
|
||||
func GetNormalFilmSource(c *gin.Context) {
|
||||
// 获取所有的采集站信息
|
||||
var l []system.FilmTaskOptions
|
||||
for _, v := range logic.CollectL.GetFilmSourceList() {
|
||||
if v.State {
|
||||
l = append(l, system.FilmTaskOptions{Id: v.Id, Name: v.Name})
|
||||
}
|
||||
}
|
||||
system.Success(l, "影视源信息获取成功", c)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------ 失败采集记录 ------------------------------------------------------
|
||||
|
||||
// FailureRecordList 失效采集记录分页数据
|
||||
func FailureRecordList(c *gin.Context) {
|
||||
// 数据返回对象
|
||||
var params = system.RecordRequestVo{Paging: &system.Page{}}
|
||||
var err error
|
||||
// 获取筛选条件
|
||||
params.OriginId = c.DefaultQuery("originId", "")
|
||||
//params.CollectType, err = strconv.Atoi(c.DefaultQuery("collectType", "-1"))
|
||||
params.Hour, err = strconv.Atoi(c.DefaultQuery("hour", "0"))
|
||||
params.Status, err = strconv.Atoi(c.DefaultQuery("status", "-1"))
|
||||
|
||||
// 处理时间参数
|
||||
begin := c.DefaultQuery("beginTime", "")
|
||||
if begin != "" {
|
||||
beginTime, e := time.ParseInLocation(time.DateTime, begin, time.Local)
|
||||
if e != nil {
|
||||
system.Failed("影片分页数据获取失败, 请求参数异常", c)
|
||||
return
|
||||
}
|
||||
params.BeginTime = beginTime
|
||||
}
|
||||
end := c.DefaultQuery("endTime", "")
|
||||
if end != "" {
|
||||
endTime, e := time.ParseInLocation(time.DateTime, end, time.Local)
|
||||
if e != nil {
|
||||
system.Failed("影片分页数据获取失败, 请求参数异常", c)
|
||||
return
|
||||
}
|
||||
params.EndTime = endTime
|
||||
}
|
||||
|
||||
// 分页参数
|
||||
params.Paging.Current, err = strconv.Atoi(c.DefaultQuery("current", "1"))
|
||||
params.Paging.PageSize, err = strconv.Atoi(c.DefaultQuery("pageSize", "10"))
|
||||
if err != nil {
|
||||
system.Failed("影片分页数据获取失败, 分页参数异常", c)
|
||||
return
|
||||
}
|
||||
// 如果分页数据超出指定范围则设置为默认值
|
||||
if params.Paging.PageSize <= 0 || params.Paging.PageSize > 500 {
|
||||
params.Paging.PageSize = 10
|
||||
}
|
||||
|
||||
// 条件筛选select选项参数
|
||||
options := logic.CollectL.GetRecordOptions()
|
||||
|
||||
// 获取满足条件的分页数据
|
||||
list := logic.CollectL.GetRecordList(params)
|
||||
system.Success(gin.H{"params": params, "list": list, "options": options}, "影片分页信息获取成功", c)
|
||||
}
|
||||
|
||||
// CollectRecover 对失败的采集进行处理
|
||||
func CollectRecover(c *gin.Context) {
|
||||
// 获取记录id
|
||||
id, err := strconv.Atoi(c.DefaultQuery("id", "0"))
|
||||
if err != nil && id != 0 {
|
||||
system.Failed("采集重试开启失败, 采集记录ID参数异常", c)
|
||||
return
|
||||
}
|
||||
// 通过记录id对失败的采集进行恢复重试操作
|
||||
err = logic.CollectL.CollectRecover(id)
|
||||
if err != nil {
|
||||
system.Failed(err.Error(), c)
|
||||
return
|
||||
}
|
||||
system.SuccessOnlyMsg("采集重试已开启, 请勿重复操作", c)
|
||||
}
|
||||
|
||||
// CollectRecoverAll 恢复采集-全量
|
||||
func CollectRecoverAll(c *gin.Context) {
|
||||
// 重新采集表中所有失败记录
|
||||
logic.CollectL.RecoverAll()
|
||||
system.SuccessOnlyMsg("恢复任务已成功开启!!!", c)
|
||||
}
|
||||
|
||||
// ClearDoneRecord 清理已处理的记录
|
||||
func ClearDoneRecord(c *gin.Context) {
|
||||
// 删除表中已处理完成的记录
|
||||
logic.CollectL.ClearDoneRecord()
|
||||
system.SuccessOnlyMsg("处理完成的记录信息已删除!!!", c)
|
||||
}
|
||||
|
||||
// ClearAllRecord 删除所有记录
|
||||
func ClearAllRecord(c *gin.Context) {
|
||||
// 截断失败采集记录表
|
||||
logic.CollectL.ClearAllRecord()
|
||||
system.SuccessOnlyMsg("采集异常记录信息已清空!!!", c)
|
||||
}
|
||||
@@ -140,17 +140,34 @@ func validTaskInfo(t system.FilmCollectTask) error {
|
||||
|
||||
// 任务添加参数校验
|
||||
func validTaskAddVo(vo system.FilmCronVo) error {
|
||||
if vo.Model != 0 && vo.Model != 1 {
|
||||
switch vo.Model {
|
||||
case 0:
|
||||
if vo.Time == 0 {
|
||||
return errors.New("参数校验失败, 采集时长不能为零值")
|
||||
}
|
||||
case 1:
|
||||
if vo.Time == 0 {
|
||||
return errors.New("参数校验失败, 采集时长不能为零值")
|
||||
}
|
||||
if vo.Ids == nil || len(vo.Ids) <= 0 {
|
||||
return errors.New("参数校验失败, 自定义更新未绑定任何资源站点")
|
||||
}
|
||||
case 2:
|
||||
break
|
||||
default:
|
||||
return errors.New("参数校验失败, 未定义的任务类型")
|
||||
}
|
||||
if vo.Time == 0 {
|
||||
return errors.New("参数校验失败, 采集时长不能为零值")
|
||||
}
|
||||
//if vo.Model != 0 && vo.Model != 1 && vo.Model != 2 {
|
||||
// return errors.New("参数校验失败, 未定义的任务类型")
|
||||
//}
|
||||
//if vo.Time == 0 {
|
||||
// return errors.New("参数校验失败, 采集时长不能为零值")
|
||||
//}
|
||||
if err := spider.ValidSpec(vo.Spec); err != nil {
|
||||
return errors.New(fmt.Sprint("参数校验失败 cron表达式校验失败: ", err.Error()))
|
||||
}
|
||||
if vo.Model == 1 && (vo.Ids == nil || len(vo.Ids) <= 0) {
|
||||
return errors.New("参数校验失败, 自定义更新未绑定任何资源站点")
|
||||
}
|
||||
//if vo.Model == 1 && (vo.Ids == nil || len(vo.Ids) <= 0) {
|
||||
// return errors.New("参数校验失败, 自定义更新未绑定任何资源站点")
|
||||
//}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"server/model/system"
|
||||
"server/plugin/SystemInit"
|
||||
"server/plugin/common/util"
|
||||
"server/plugin/spider"
|
||||
)
|
||||
|
||||
func ManageIndex(c *gin.Context) {
|
||||
@@ -16,184 +15,6 @@ func ManageIndex(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// ------------------------------------------------------ 影视采集 ------------------------------------------------------
|
||||
|
||||
// FilmSourceList 采集站点信息
|
||||
func FilmSourceList(c *gin.Context) {
|
||||
system.Success(logic.ML.GetFilmSourceList(), "影视源站点信息获取成功", c)
|
||||
return
|
||||
}
|
||||
|
||||
// FindFilmSource 通过ID返回对应的资源站数据
|
||||
func FindFilmSource(c *gin.Context) {
|
||||
id := c.Query("id")
|
||||
if id == "" {
|
||||
system.Failed("参数异常, 资源站标识不能为空", c)
|
||||
return
|
||||
}
|
||||
fs := logic.ML.GetFilmSource(id)
|
||||
if fs == nil {
|
||||
system.Failed("数据异常,资源站信息不存在", c)
|
||||
return
|
||||
}
|
||||
system.Success(fs, "原站点详情信息查找成功", c)
|
||||
}
|
||||
|
||||
// FilmSourceAdd 添加采集源
|
||||
func FilmSourceAdd(c *gin.Context) {
|
||||
var s = system.FilmSource{}
|
||||
// 获取请求参数
|
||||
if err := c.ShouldBindJSON(&s); err != nil {
|
||||
system.Failed("请求参数异常", c)
|
||||
return
|
||||
}
|
||||
// 校验必要参数
|
||||
if err := validFilmSource(s); err != nil {
|
||||
system.Failed(err.Error(), c)
|
||||
return
|
||||
}
|
||||
// 如果采集站开启图片同步, 且采集站为附属站点则返回错误提示
|
||||
if s.SyncPictures && (s.Grade == system.SlaveCollect) {
|
||||
system.Failed("附属站点无法开启图片同步功能", c)
|
||||
return
|
||||
}
|
||||
// 执行 spider
|
||||
if err := spider.CollectApiTest(s); err != nil {
|
||||
system.Failed("资源接口测试失败, 请确认接口有效再添加", c)
|
||||
return
|
||||
}
|
||||
// 测试通过后将资源站信息添加到list
|
||||
if err := logic.ML.SaveFilmSource(s); err != nil {
|
||||
system.Failed(fmt.Sprint("资源站添加失败: ", err.Error()), c)
|
||||
return
|
||||
}
|
||||
system.SuccessOnlyMsg("添加成功", c)
|
||||
}
|
||||
|
||||
func FilmSourceUpdate(c *gin.Context) {
|
||||
var s = system.FilmSource{}
|
||||
// 获取请求参数
|
||||
if err := c.ShouldBindJSON(&s); err != nil {
|
||||
system.Failed("请求参数异常", c)
|
||||
return
|
||||
}
|
||||
// 校验必要参数
|
||||
if err := validFilmSource(s); err != nil {
|
||||
system.Failed(err.Error(), c)
|
||||
return
|
||||
}
|
||||
// 如果采集站开启图片同步, 且采集站为附属站点则返回错误提示
|
||||
if s.SyncPictures && (s.Grade == system.SlaveCollect) {
|
||||
system.Failed("附属站点无法开启图片同步功能", c)
|
||||
return
|
||||
}
|
||||
// 校验Id信息是否为空
|
||||
if s.Id == "" {
|
||||
system.Failed("参数异常, 资源站标识不能为空", c)
|
||||
return
|
||||
}
|
||||
fs := logic.ML.GetFilmSource(s.Id)
|
||||
if fs == nil {
|
||||
system.Failed("数据异常,资源站信息不存在", c)
|
||||
return
|
||||
}
|
||||
// 如果 uri发生变更则执行spider测试
|
||||
if fs.Uri != s.Uri {
|
||||
// 执行 spider
|
||||
if err := spider.CollectApiTest(s); err != nil {
|
||||
system.Failed("资源接口测试失败, 请确认更新的数据接口是否有效", c)
|
||||
return
|
||||
}
|
||||
}
|
||||
// 更新资源站信息
|
||||
if err := logic.ML.UpdateFilmSource(s); err != nil {
|
||||
system.Failed(fmt.Sprint("资源站更新失败: ", err.Error()), c)
|
||||
return
|
||||
}
|
||||
system.SuccessOnlyMsg("更新成功", c)
|
||||
}
|
||||
|
||||
func FilmSourceChange(c *gin.Context) {
|
||||
var s = system.FilmSource{}
|
||||
// 获取请求参数
|
||||
if err := c.ShouldBindJSON(&s); err != nil {
|
||||
system.Failed("请求参数异常", c)
|
||||
return
|
||||
}
|
||||
if s.Id == "" {
|
||||
system.Failed("参数异常, 资源站标识不能为空", c)
|
||||
return
|
||||
}
|
||||
// 查找对应的资源站点信息
|
||||
fs := logic.ML.GetFilmSource(s.Id)
|
||||
if fs == nil {
|
||||
system.Failed("数据异常,资源站信息不存在", c)
|
||||
return
|
||||
}
|
||||
// 如果采集站开启图片同步, 且采集站为附属站点则返回错误提示
|
||||
if s.SyncPictures && (fs.Grade == system.SlaveCollect) {
|
||||
system.Failed("附属站点无法开启图片同步功能", c)
|
||||
return
|
||||
}
|
||||
if s.State != fs.State || s.SyncPictures != fs.SyncPictures {
|
||||
// 执行更新操作
|
||||
s := system.FilmSource{Id: fs.Id, Name: fs.Name, Uri: fs.Uri, ResultModel: fs.ResultModel,
|
||||
Grade: fs.Grade, SyncPictures: s.SyncPictures, CollectType: fs.CollectType, State: s.State}
|
||||
// 更新资源站信息
|
||||
if err := logic.ML.UpdateFilmSource(s); err != nil {
|
||||
system.Failed(fmt.Sprint("资源站更新失败: ", err.Error()), c)
|
||||
return
|
||||
}
|
||||
}
|
||||
system.SuccessOnlyMsg("更新成功", c)
|
||||
}
|
||||
|
||||
func FilmSourceDel(c *gin.Context) {
|
||||
id := c.Query("id")
|
||||
if len(id) <= 0 {
|
||||
system.Failed("资源站ID信息不能为空", c)
|
||||
return
|
||||
}
|
||||
if err := logic.ML.DelFilmSource(id); err != nil {
|
||||
system.Failed("删除资源站失败", c)
|
||||
return
|
||||
}
|
||||
system.SuccessOnlyMsg("删除成功", c)
|
||||
}
|
||||
|
||||
// FilmSourceTest 测试影视站点数据是否可用
|
||||
func FilmSourceTest(c *gin.Context) {
|
||||
var s = system.FilmSource{}
|
||||
// 获取请求参数
|
||||
if err := c.ShouldBindJSON(&s); err != nil {
|
||||
system.Failed("请求参数异常", c)
|
||||
return
|
||||
}
|
||||
// 校验必要参数
|
||||
if err := validFilmSource(s); err != nil {
|
||||
system.Failed(err.Error(), c)
|
||||
return
|
||||
}
|
||||
// 执行 spider
|
||||
if err := spider.CollectApiTest(s); err != nil {
|
||||
system.Failed(err.Error(), c)
|
||||
return
|
||||
}
|
||||
system.SuccessOnlyMsg("测试成功!!!", c)
|
||||
}
|
||||
|
||||
// GetNormalFilmSource 获取状态为启用的采集站信息
|
||||
func GetNormalFilmSource(c *gin.Context) {
|
||||
// 获取所有的采集站信息
|
||||
var l []system.FilmTaskOptions
|
||||
for _, v := range logic.ML.GetFilmSourceList() {
|
||||
if v.State {
|
||||
l = append(l, system.FilmTaskOptions{Id: v.Id, Name: v.Name})
|
||||
}
|
||||
}
|
||||
system.Success(l, "影视源信息获取成功", c)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------ 站点基本配置 ------------------------------------------------------
|
||||
|
||||
// SiteBasicConfig 网站基本配置
|
||||
|
||||
@@ -111,12 +111,14 @@ func DirectedSpider(c *gin.Context) {
|
||||
// SingleUpdateSpider 单一影片更新采集
|
||||
func SingleUpdateSpider(c *gin.Context) {
|
||||
// 获取影片对应的唯一标识
|
||||
id := c.Query("id")
|
||||
if id == "" {
|
||||
system.Failed("参数异常, 资源站标识不能为空", c)
|
||||
ids := c.Query("ids")
|
||||
if ids == "" {
|
||||
system.Failed("参数异常, 资源标识ID信息缺失", c)
|
||||
return
|
||||
}
|
||||
// 通过ID对指定影片进行同步更新
|
||||
logic.SL.SyncCollect(ids)
|
||||
system.SuccessOnlyMsg("影片更新任务已成功开启!!!", c)
|
||||
}
|
||||
|
||||
// 校验密码有效性
|
||||
|
||||
@@ -46,8 +46,7 @@ github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
|
||||
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA=
|
||||
github.com/gocolly/colly/v2 v2.1.0 h1:k0DuZkDoCsx51bKpRJNEmcxcp+W5N8ziuwGaSDuFoGs=
|
||||
@@ -205,8 +204,6 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.4.7 h1:rY46lkCspzGHn7+IYsNpSfEv9tA+SU4SkkB+GFX125Y=
|
||||
gorm.io/driver/mysql v1.4.7/go.mod h1:SxzItlnT1cb6e1e4ZRpgJN2VYtcqJgqnHxWr4wsP8oc=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.24.6 h1:wy98aq9oFEetsc4CAbKD2SoBCdMzsbSIvSUUFJuHi5s=
|
||||
gorm.io/gorm v1.24.6/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
|
||||
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
106
film/server/logic/CollectLogic.go
Normal file
106
film/server/logic/CollectLogic.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"server/model/system"
|
||||
"server/plugin/spider"
|
||||
)
|
||||
|
||||
type CollectLogic struct {
|
||||
}
|
||||
|
||||
var CollectL *CollectLogic
|
||||
|
||||
// ------------------------------------------------------ 采集站点管理 ------------------------------------------------------
|
||||
|
||||
// GetFilmSourceList 获取采集站列表数据
|
||||
func (cl *CollectLogic) GetFilmSourceList() []system.FilmSource {
|
||||
// 返回当前已添加的采集站列表信息
|
||||
return system.GetCollectSourceList()
|
||||
}
|
||||
|
||||
// GetFilmSource 获取ID对应的采集源信息
|
||||
func (cl *CollectLogic) GetFilmSource(id string) *system.FilmSource {
|
||||
return system.FindCollectSourceById(id)
|
||||
}
|
||||
|
||||
// UpdateFilmSource 更新采集源信息
|
||||
func (cl *CollectLogic) UpdateFilmSource(s system.FilmSource) error {
|
||||
return system.UpdateCollectSource(s)
|
||||
}
|
||||
|
||||
// SaveFilmSource 保存采集源信息
|
||||
func (cl *CollectLogic) SaveFilmSource(s system.FilmSource) error {
|
||||
return system.AddCollectSource(s)
|
||||
}
|
||||
|
||||
// DelFilmSource 删除采集源信息
|
||||
func (cl *CollectLogic) DelFilmSource(id string) error {
|
||||
// 先查找是否存在对应ID的站点信息
|
||||
s := system.FindCollectSourceById(id)
|
||||
if s == nil {
|
||||
return errors.New("当前资源站信息不存在, 请勿重复操作")
|
||||
}
|
||||
// 如果是主站点则返回提示禁止直接删除
|
||||
if s.Grade == system.MasterCollect {
|
||||
return errors.New("主站点无法直接删除, 请先降级为附属站点再进行删除")
|
||||
}
|
||||
system.DelCollectResource(id)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ------------------------------------------------------ 采集记录管理 ------------------------------------------------------
|
||||
|
||||
// GetRecordList 获取采集记录列表
|
||||
func (cl *CollectLogic) GetRecordList(params system.RecordRequestVo) []system.FailureRecord {
|
||||
return system.FailureRecordList(params)
|
||||
}
|
||||
|
||||
// GetRecordOptions 获取采集记录筛选参数
|
||||
func (cl *CollectLogic) GetRecordOptions() system.OptionGroup {
|
||||
var options = make(system.OptionGroup)
|
||||
// 获取筛选参数, 采集源(ID:name) | 采集类型 | 状态
|
||||
options["collectType"] = []system.Option{{"全部", -1}, {"影片详情", 0}, {"文章", 1}, {"演员", 2}, {"角色", 3}, {"网站", 4}}
|
||||
options["status"] = []system.Option{{"全部", -1}, {"待重试", 1}, {"已处理", 0}}
|
||||
// 获取全部采集站
|
||||
var originOptions = []system.Option{{"全部", ""}}
|
||||
for _, v := range system.GetCollectSourceList() {
|
||||
originOptions = append(originOptions, system.Option{Name: v.Name, Value: v.Id})
|
||||
}
|
||||
options["origin"] = originOptions
|
||||
return options
|
||||
}
|
||||
|
||||
// CollectRecover 恢复采集
|
||||
func (cl *CollectLogic) CollectRecover(id int) error {
|
||||
// 通过ID获取完整的失败记录信息
|
||||
fr := system.FindRecordById(uint(id))
|
||||
// 如果获取失败记录信息为空, 则不进行后续操作
|
||||
if fr == nil {
|
||||
return errors.New("采集重试执行失败: 失败记录信息获取异常")
|
||||
}
|
||||
// 执行恢复采集, 恢复对应的采集数据
|
||||
go spider.SingleRecoverSpider(fr)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RecoverAll 恢复重新对所有失效记录进行重新采集处理
|
||||
func (cl *CollectLogic) RecoverAll() {
|
||||
// 是否进行身份验证, 暂定无需处理
|
||||
|
||||
// 对数据表中的所有待处理记录进行恢复采集
|
||||
go spider.FullRecoverSpider()
|
||||
}
|
||||
|
||||
// ClearDoneRecord 清除已处理完成的记录信息 (将记录表中已经完成处理的记录删除)
|
||||
func (cl *CollectLogic) ClearDoneRecord() {
|
||||
// <逻辑删除 or 真实删除> 为避免ID中断暂定逻辑删除
|
||||
system.DelDoneRecord()
|
||||
}
|
||||
|
||||
// ClearAllRecord 清除所有记录信息 (直接对记录表直接进行截断处理)
|
||||
func (cl *CollectLogic) ClearAllRecord() {
|
||||
// 重置记录表状态, 删除所有数据并将自增ID归零
|
||||
system.TruncateRecordTable()
|
||||
}
|
||||
@@ -40,6 +40,14 @@ func (cl *CronLogic) AddFilmCrontab(cv system.FilmCronVo) error {
|
||||
}
|
||||
// 将定时任务Id记录到Task中
|
||||
task.Cid = cid
|
||||
case 2:
|
||||
cid, err := spider.AddFilmRecoverCron(task.Spec)
|
||||
// 如果任务添加失败则直接返回错误信息
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprint("失败采集处理定时任务添加失败: ", err.Error()))
|
||||
}
|
||||
// 将定时任务Id记录到Task中
|
||||
task.Cid = cid
|
||||
}
|
||||
// 如果没有异常则将当前定时任务信息记录到redis中
|
||||
system.SaveFilmTask(task)
|
||||
|
||||
@@ -45,11 +45,26 @@ func (i *IndexLogic) IndexPage() map[string]interface{} {
|
||||
// 2. 提供用于首页展示的顶级分类影片信息, 每分类 14条数据
|
||||
var list []map[string]interface{}
|
||||
for _, c := range tree.Children {
|
||||
// 生成分页参数
|
||||
page := system.Page{PageSize: 14, Current: 1}
|
||||
movies := system.GetMovieListByPid(c.Id, &page)
|
||||
// 获取当前分类的本月热门影片
|
||||
HotMovies := system.GetHotMovieByPid(c.Id, &page)
|
||||
item := map[string]interface{}{"nav": c, "movies": movies, "hot": HotMovies}
|
||||
// 获取最近上映影片和本月热门影片
|
||||
var movies []system.MovieBasicInfo
|
||||
var hotMovies []system.SearchInfo
|
||||
if c.Children != nil {
|
||||
// 如果有子分类, 则通过Pid获取对应影片
|
||||
// 获取当前分类的最新上映影片
|
||||
movies = system.GetMovieListByPid(c.Id, &page)
|
||||
// 获取当前分类的本月热门影片
|
||||
hotMovies = system.GetHotMovieByPid(c.Id, &page)
|
||||
} else {
|
||||
// 如果当前分类为一级分类且没有子分类,则通过Cid获取对应数据
|
||||
// 获取当前分类的最新上映影片
|
||||
movies = system.GetMovieListByCid(c.Id, &page)
|
||||
// 获取当前分类的本月热门影片
|
||||
hotMovies = system.GetHotMovieByCid(c.Id, &page)
|
||||
}
|
||||
|
||||
item := map[string]interface{}{"nav": c, "movies": movies, "hot": hotMovies}
|
||||
list = append(list, item)
|
||||
}
|
||||
Info["content"] = list
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"server/model/system"
|
||||
)
|
||||
|
||||
@@ -10,42 +9,6 @@ type ManageLogic struct {
|
||||
|
||||
var ML *ManageLogic
|
||||
|
||||
// GetFilmSourceList 获取采集站列表数据
|
||||
func (ml *ManageLogic) GetFilmSourceList() []system.FilmSource {
|
||||
// 返回当前已添加的采集站列表信息
|
||||
return system.GetCollectSourceList()
|
||||
}
|
||||
|
||||
// GetFilmSource 获取ID对应的采集源信息
|
||||
func (ml *ManageLogic) GetFilmSource(id string) *system.FilmSource {
|
||||
return system.FindCollectSourceById(id)
|
||||
}
|
||||
|
||||
// UpdateFilmSource 更新采集源信息
|
||||
func (ml *ManageLogic) UpdateFilmSource(s system.FilmSource) error {
|
||||
return system.UpdateCollectSource(s)
|
||||
}
|
||||
|
||||
// SaveFilmSource 保存采集源信息
|
||||
func (ml *ManageLogic) SaveFilmSource(s system.FilmSource) error {
|
||||
return system.AddCollectSource(s)
|
||||
}
|
||||
|
||||
// DelFilmSource 删除采集源信息
|
||||
func (ml *ManageLogic) DelFilmSource(id string) error {
|
||||
// 先查找是否存在对应ID的站点信息
|
||||
s := system.FindCollectSourceById(id)
|
||||
if s == nil {
|
||||
return errors.New("当前资源站信息不存在, 请勿重复操作")
|
||||
}
|
||||
// 如果是主站点则返回提示禁止直接删除
|
||||
if s.Grade == system.MasterCollect {
|
||||
return errors.New("主站点无法直接删除, 请先降级为附属站点再进行删除")
|
||||
}
|
||||
system.DelCollectResource(id)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSiteBasicConfig 获取网站基本配置信息
|
||||
func (ml *ManageLogic) GetSiteBasicConfig() system.BasicConfig {
|
||||
return system.GetSiteBasic()
|
||||
|
||||
@@ -48,6 +48,11 @@ func (sl *SpiderLogic) ZeroCollect(time int) {
|
||||
go spider.StarZero(time)
|
||||
}
|
||||
|
||||
// SyncCollect 同步采集
|
||||
func (sl *SpiderLogic) SyncCollect(ids string) {
|
||||
go spider.CollectSingleFilm(ids)
|
||||
}
|
||||
|
||||
// FilmClassCollect 影视分类采集, 直接覆盖当前分类数据
|
||||
func (sl *SpiderLogic) FilmClassCollect() error {
|
||||
l := system.GetCollectSourceListByGrade(system.MasterCollect)
|
||||
|
||||
146
film/server/model/system/CollectRecord.go
Normal file
146
film/server/model/system/CollectRecord.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gorm.io/gorm"
|
||||
"log"
|
||||
"server/config"
|
||||
"server/plugin/db"
|
||||
)
|
||||
|
||||
// FailureRecord 失败采集记录信息机构体
|
||||
type FailureRecord struct {
|
||||
gorm.Model
|
||||
OriginId string `json:"originId"` // 采集站唯一ID
|
||||
OriginName string `json:"originName"` // 采集站唯一ID
|
||||
Uri string `json:"uri"` // 采集源链接
|
||||
CollectType ResourceType `json:"collectType"` // 采集类型
|
||||
PageNumber int `json:"pageNumber"` // 页码
|
||||
Hour int `json:"hour"` // 采集参数 h 时长
|
||||
Cause string `json:"cause"` // 失败原因
|
||||
Status int `json:"status"` // 重试状态
|
||||
}
|
||||
|
||||
// TableName 采集失败记录表表名
|
||||
func (fr FailureRecord) TableName() string {
|
||||
return config.FailureRecordTableName
|
||||
}
|
||||
|
||||
// CreateFailureRecordTable 创建失效记录表
|
||||
func CreateFailureRecordTable() {
|
||||
var fl = &FailureRecord{}
|
||||
// 不存在则创建FailureRecord表
|
||||
if !db.Mdb.Migrator().HasTable(fl) {
|
||||
if err := db.Mdb.AutoMigrate(fl); err != nil {
|
||||
log.Println("Create Table failure_record failed:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SaveFailureRecord 添加采集失效记录
|
||||
func SaveFailureRecord(fl FailureRecord) {
|
||||
// 数据量不多但存在并发问题, 开启事务
|
||||
err := db.Mdb.Transaction(func(tx *gorm.DB) error {
|
||||
// 将采集失败信息存储到record表中
|
||||
if err := tx.Create(&fl).Error; err != nil {
|
||||
log.Println("Add failure record failed:", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
// 如果事务提交失败, 则输出相应信息, (存一份数据到Redis??)
|
||||
if err != nil {
|
||||
log.Println("Save failure record affairs failed:", err)
|
||||
}
|
||||
}
|
||||
|
||||
// FailureRecordList 获取所有的采集失效记录
|
||||
func FailureRecordList(vo RecordRequestVo) []FailureRecord {
|
||||
// 通过RecordRequestVo,生成查询条件
|
||||
qw := db.Mdb.Model(&FailureRecord{})
|
||||
if vo.OriginId != "" {
|
||||
qw.Where("origin_id = ?", vo.OriginId)
|
||||
}
|
||||
if !vo.BeginTime.IsZero() && !vo.EndTime.IsZero() {
|
||||
qw.Where("created_at BETWEEN ? AND ? ", vo.BeginTime, vo.EndTime)
|
||||
}
|
||||
//if vo.CollectType >= 0 {
|
||||
// qw.Where("collect_type = ?", vo.CollectType)
|
||||
//}
|
||||
//if vo.Hour != 0 {
|
||||
// qw.Where("hour = ?", vo.Hour)
|
||||
//}
|
||||
if vo.Status >= 0 {
|
||||
qw.Where("status = ?", vo.Status)
|
||||
}
|
||||
|
||||
// 获取分页数据
|
||||
GetPage(qw, vo.Paging)
|
||||
// 获取分页查询的数据
|
||||
var list []FailureRecord
|
||||
if err := qw.Limit(vo.Paging.PageSize).Offset((vo.Paging.Current - 1) * vo.Paging.PageSize).Order("updated_at DESC").Find(&list).Error; err != nil {
|
||||
log.Println(err)
|
||||
return nil
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// FindRecordById 获取id对应的失效记录
|
||||
func FindRecordById(id uint) *FailureRecord {
|
||||
var fr FailureRecord
|
||||
fr.ID = id
|
||||
// 通过ID查询对应的数据
|
||||
db.Mdb.First(&fr)
|
||||
return &fr
|
||||
}
|
||||
|
||||
// PendingRecord 查询所有待处理的记录信息
|
||||
func PendingRecord() []FailureRecord {
|
||||
var list []FailureRecord
|
||||
// 1. 获取 hour > 4320 || hour < 0 && status = 1 的影片信息
|
||||
db.Mdb.Where("(hour > 4320 OR hour < 0) AND status = 1").Find(&list)
|
||||
// 2. 获取 hour > 0 && hour < 4320 && status = 1 的影片信息(只获取最早的一条记录)
|
||||
var fr FailureRecord
|
||||
db.Mdb.Where("hour > 0 AND hour < 4320 AND status = 1").Order("hour DESC, created_at ASC").First(&fr)
|
||||
// 3. 将 fr 添加到 list中
|
||||
list = append(list, fr)
|
||||
return list
|
||||
}
|
||||
|
||||
// ChangeRecord 修改已完成二次采集的记录状态
|
||||
func ChangeRecord(fr *FailureRecord, status int) {
|
||||
switch {
|
||||
case fr.Hour > 168 && fr.Hour < 360:
|
||||
db.Mdb.Model(&FailureRecord{}).Where("hour > 168 AND hour < 360 AND created_at >= ?", fr.CreatedAt).Update("status", status)
|
||||
case fr.Hour < 0, fr.Hour > 4320:
|
||||
db.Mdb.Model(&FailureRecord{}).Where("id = ?", fr.ID).Update("status", status)
|
||||
default:
|
||||
// 其余范围,暂不处理
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// RetryRecord 修改重试采集成功的记录
|
||||
func RetryRecord(id uint, status int64) error {
|
||||
// 查询id对应的失败记录
|
||||
fr := FindRecordById(id)
|
||||
// 将本次更新成功的记录数据状态修改为成功 0
|
||||
return db.Mdb.Model(&FailureRecord{}).Where("update_at > ?", fr.UpdatedAt).Update("status", 0).Error
|
||||
|
||||
}
|
||||
|
||||
// DelDoneRecord 删除已处理的记录信息 -- 逻辑删除
|
||||
func DelDoneRecord() {
|
||||
if err := db.Mdb.Where("status = ?", 0).Delete(&FailureRecord{}).Error; err != nil {
|
||||
log.Println("Delete failure record failed:", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TruncateRecordTable 截断 record table
|
||||
func TruncateRecordTable() {
|
||||
var s FailureRecord
|
||||
err := db.Mdb.Exec(fmt.Sprintf("TRUNCATE Table %s", s.TableName())).Error
|
||||
if err != nil {
|
||||
log.Println("TRUNCATE TABLE Error: ", err)
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ type FilmCollectTask struct {
|
||||
Cid cron.EntryID `json:"cid"` // 定时任务Id
|
||||
Time int `json:"time"` // 采集时长, 最新x小时更新的内容
|
||||
Spec string `json:"spec"` // 执行周期 cron表达式
|
||||
Model int `json:"model"` // 任务类型, 0 - 自动更新已启用站点 || 1 - 更新Ids中的资源站数据
|
||||
Model int `json:"model"` // 任务类型, 0 - 自动更新已启用站点 || 1 - 更新Ids中的资源站数据 || 2 - 定期清理失败采集记录
|
||||
State bool `json:"state"` // 状态 开启 | 禁用
|
||||
Remark string `json:"remark"` // 任务备注信息
|
||||
}
|
||||
|
||||
@@ -73,19 +73,19 @@ func FilmZero() {
|
||||
db.Rdb.Del(db.Cxt, db.Rdb.Keys(db.Cxt, "OriginalResource*").Val()...)
|
||||
db.Rdb.Del(db.Cxt, db.Rdb.Keys(db.Cxt, "Search*").Val()...)
|
||||
// 删除mysql中留存的检索表
|
||||
var s *SearchInfo
|
||||
var s SearchInfo
|
||||
//db.Mdb.Exec(fmt.Sprintf(`drop table if exists %s`, s.TableName()))
|
||||
// 截断数据表 truncate table users
|
||||
if ExistSearchTable() {
|
||||
db.Mdb.Exec(fmt.Sprintf(`TRUNCATE table %s`, s.TableName()))
|
||||
db.Mdb.Exec(fmt.Sprintf("TRUNCATE table %s", s.TableName()))
|
||||
}
|
||||
}
|
||||
|
||||
// ResetSearchTable 重置Search表
|
||||
func ResetSearchTable() {
|
||||
// 删除 Search 表
|
||||
var s *SearchInfo
|
||||
db.Mdb.Exec(fmt.Sprintf(`drop table if exists %s`, s.TableName()))
|
||||
var s SearchInfo
|
||||
db.Mdb.Exec(fmt.Sprintf("drop table if exists %s", s.TableName()))
|
||||
// 重新创建 Search 表
|
||||
CreateSearchTable()
|
||||
}
|
||||
@@ -112,7 +112,7 @@ func SaveSearchTag(search SearchInfo) {
|
||||
// 获取redis中的searchMap
|
||||
key := fmt.Sprintf(config.SearchTitle, search.Pid)
|
||||
searchMap := db.Rdb.HGetAll(db.Cxt, key).Val()
|
||||
// 是否存储对应分类的map, 如果不存在则缓存一份
|
||||
// 是否存在对应分类的map, 如果不存在则缓存一份
|
||||
if len(searchMap) == 0 {
|
||||
searchMap = make(map[string]string)
|
||||
searchMap["Category"] = "类型"
|
||||
@@ -230,6 +230,7 @@ func CreateSearchTable() {
|
||||
}
|
||||
}
|
||||
|
||||
// ExistSearchTable 是否存在Search Table
|
||||
func ExistSearchTable() bool {
|
||||
// 1. 判断表中是否存在当前表
|
||||
return db.Mdb.Migrator().HasTable(&SearchInfo{})
|
||||
@@ -237,7 +238,7 @@ func ExistSearchTable() bool {
|
||||
|
||||
// AddSearchIndex search表中数据保存完毕后 将常用字段添加索引提高查询效率
|
||||
func AddSearchIndex() {
|
||||
var s *SearchInfo
|
||||
var s SearchInfo
|
||||
tableName := s.TableName()
|
||||
// 添加索引
|
||||
db.Mdb.Exec(fmt.Sprintf("CREATE UNIQUE INDEX idx_mid ON %s (mid)", tableName))
|
||||
@@ -331,8 +332,8 @@ func ExistSearchInfo(mid int64) bool {
|
||||
|
||||
// TunCateSearchTable 截断SearchInfo数据表
|
||||
func TunCateSearchTable() {
|
||||
var searchInfo *SearchInfo
|
||||
err := db.Mdb.Exec(fmt.Sprint("TRUNCATE TABLE ", searchInfo.TableName())).Error
|
||||
var searchInfo SearchInfo
|
||||
err := db.Mdb.Exec(fmt.Sprintf("TRUNCATE TABLE %s", searchInfo.TableName())).Error
|
||||
if err != nil {
|
||||
log.Println("TRUNCATE TABLE Error: ", err)
|
||||
}
|
||||
@@ -434,7 +435,7 @@ func GetMovieListByCid(cid int64, page *Page) []MovieBasicInfo {
|
||||
return list
|
||||
}
|
||||
|
||||
// GetHotMovieByPid 获取指定类别的热门影片
|
||||
// GetHotMovieByPid 获取Pid指定类别的热门影片
|
||||
func GetHotMovieByPid(pid int64, page *Page) []SearchInfo {
|
||||
// 返回分页参数
|
||||
//var count int64
|
||||
@@ -452,6 +453,24 @@ func GetHotMovieByPid(pid int64, page *Page) []SearchInfo {
|
||||
return s
|
||||
}
|
||||
|
||||
// GetHotMovieByCid 获取当前分类下的热门影片
|
||||
func GetHotMovieByCid(cid int64, page *Page) []SearchInfo {
|
||||
// 返回分页参数
|
||||
//var count int64
|
||||
//db.Mdb.Model(&SearchInfo{}).Where("pid", pid).Count(&count)
|
||||
//page.Total = int(count)
|
||||
//page.PageCount = int((page.Total + page.PageSize - 1) / page.PageSize)
|
||||
// 进行具体的信息查询
|
||||
var s []SearchInfo
|
||||
// 当前时间偏移一个月
|
||||
t := time.Now().AddDate(0, -1, 0).Unix()
|
||||
if err := db.Mdb.Limit(page.PageSize).Offset((page.Current-1)*page.PageSize).Where("cid=? AND update_stamp > ?", cid, t).Order(" year DESC, hits DESC").Find(&s).Error; err != nil {
|
||||
log.Println(err)
|
||||
return nil
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// SearchFilmKeyword 通过关键字搜索库存中满足条件的影片名
|
||||
func SearchFilmKeyword(keyword string, page *Page) []SearchInfo {
|
||||
var searchList []SearchInfo
|
||||
|
||||
@@ -36,7 +36,7 @@ func CreateUserTable() {
|
||||
// 如果不存在则创建表 并设置自增ID初始值为10000
|
||||
if !ExistUserTable() {
|
||||
err := db.Mdb.AutoMigrate(u)
|
||||
db.Mdb.Exec(fmt.Sprintf("alter table %s auto_Increment=%d", u.TableName(), config.UserIdInitialVal))
|
||||
db.Mdb.Exec(fmt.Sprintf("alter table %s auto_Increment = %d", u.TableName(), config.UserIdInitialVal))
|
||||
if err != nil {
|
||||
log.Println("Create Table SearchInfo Failed: ", err)
|
||||
}
|
||||
@@ -81,6 +81,7 @@ func GetUserByNameOrEmail(userName string) *User {
|
||||
return u
|
||||
}
|
||||
|
||||
// GetUserById 通过id获取对应的用户信息
|
||||
func GetUserById(id uint) User {
|
||||
var user = User{Model: gorm.Model{ID: id}}
|
||||
db.Mdb.First(&user)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package system
|
||||
|
||||
import "time"
|
||||
|
||||
// SearchTagsVO 搜索标签请求参数
|
||||
type SearchTagsVO struct {
|
||||
Pid int64 `json:"pid"`
|
||||
@@ -34,6 +36,12 @@ type FilmTaskOptions struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Option struct {
|
||||
Name string `json:"name"`
|
||||
Value any `json:"value"`
|
||||
}
|
||||
type OptionGroup map[string][]Option
|
||||
|
||||
// CollectParams 数据采集所需要的参数
|
||||
type CollectParams struct {
|
||||
Id string `json:"id"` // 资源站id
|
||||
@@ -109,7 +117,18 @@ type PlayLinkVo struct {
|
||||
LinkList []MovieUrlInfo `json:"linkList"`
|
||||
}
|
||||
|
||||
// MovieDetailVo 影片详情数据, 播放源合并版
|
||||
type MovieDetailVo struct {
|
||||
MovieDetail
|
||||
List []PlayLinkVo `json:"list"`
|
||||
}
|
||||
|
||||
type RecordRequestVo struct {
|
||||
OriginId string `json:"originId"` // 源站点ID
|
||||
CollectType int `json:"collectType"` // 采集类型
|
||||
Hour int `json:"hour"` // 采集时长
|
||||
Status int `json:"status"` // 状态
|
||||
BeginTime time.Time `json:"beginTime"` // 起始时间
|
||||
EndTime time.Time `json:"endTime"` // 结束时间
|
||||
Paging *Page `json:"paging"` // 分页参数
|
||||
}
|
||||
|
||||
@@ -12,4 +12,6 @@ func TableInIt() {
|
||||
system.CreateSearchTable()
|
||||
// 创建图片信息管理表
|
||||
system.CreateFileTable()
|
||||
// 创建采集失效记录表
|
||||
system.CreateFailureRecordTable()
|
||||
}
|
||||
|
||||
@@ -21,20 +21,21 @@ func FilmSourceInit() {
|
||||
return
|
||||
}
|
||||
var l []system.FilmSource = []system.FilmSource{
|
||||
{Id: util.GenerateSalt(), Name: "HD(LZ)", 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(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(OK)", Uri: `https://okzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
|
||||
{Id: util.GenerateSalt(), Name: "HD(HM)", Uri: `https://json.heimuer.xyz/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
|
||||
{Id: util.GenerateSalt(), Name: "HD(LY)", Uri: `https://360zy.com/api.php/provide/vod/at/json`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
|
||||
{Id: util.GenerateSalt(), Name: "HD(YZ)", Uri: `https://api.1080zyku.com/inc/apijson.php`, 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(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(LZ)", Uri: `https://cj.lziapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
|
||||
//{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(fs)", Uri: `https://www.feisuzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
|
||||
//{Id: util.GenerateSalt(), Name: "HD(bfApp)", Uri: `http://app.bfzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: true},
|
||||
//Id: util.GenerateSalt(), {Name: "HD(bfBk)", Uri: `http://by.bfzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false,CollectType:system.CollectVideo, State: false},
|
||||
{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: false},
|
||||
{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: false, 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: false},
|
||||
{Id: util.GenerateSalt(), Name: "HD(OK)", Uri: `https://okzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
{Id: util.GenerateSalt(), Name: "HD(HM)", Uri: `https://json.heimuer.xyz/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
{Id: util.GenerateSalt(), Name: "HD(LY)", Uri: `https://360zy.com/api.php/provide/vod/at/json`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
{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: false, Interval: 2000},
|
||||
{Id: util.GenerateSalt(), Name: "HD(DB)", Uri: `https://caiji.dbzy.tv/api.php/provide/vod/from/dbm3u8/at/josn/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
{Id: util.GenerateSalt(), Name: "HD(IK)", Uri: `https://ikunzyapi.com/api.php/provide/vod/at/json`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
//{Id: util.GenerateSalt(), Name: "WX(T2)", Uri: `https://api.wuxianzy.net/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
//{Id: util.GenerateSalt(), Name: "OK(BK)", Uri: `https://api.okzy.org/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
//{Id: util.GenerateSalt(), Name: "HD(HW)", Uri: `https://cjhwba.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false, Interval: 3000},
|
||||
//{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: false},
|
||||
//{Id: util.GenerateSalt(), Name: "HD(fs)", Uri: `https://www.feisuzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
//{Id: util.GenerateSalt(), Name: "HD(bfBk)", Uri: `http://app.bfzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
}
|
||||
err := system.SaveCollectSourceList(l)
|
||||
if err != nil {
|
||||
@@ -67,16 +68,28 @@ func CollectCrontabInit() {
|
||||
}
|
||||
// 将定时任务Id记录到Task中
|
||||
task.Cid = cid
|
||||
case 2:
|
||||
cid, err := spider.AddFilmRecoverCron(task.Spec)
|
||||
// 如果任务添加失败则直接返回错误信息
|
||||
if err != nil {
|
||||
log.Println("自动清理失败采集记录定时任务添加失败: ", err.Error())
|
||||
continue
|
||||
}
|
||||
// 将定时任务Id记录到Task中
|
||||
task.Cid = cid
|
||||
}
|
||||
system.UpdateFilmTask(task)
|
||||
}
|
||||
} else {
|
||||
// 如果系统中不存在任何定时任务信息, 则添加默认的定时任务
|
||||
// 1. 添加一条默认任务, 定时更新所有已启用站点的影片信息
|
||||
// 生成任务信息
|
||||
/*
|
||||
如果系统中不存在任何定时任务信息, 则添加默认的定时任务
|
||||
1. 添加一条默认任务, 定时更新所有已启用站点的影片信息
|
||||
2. 添加一条默认任务, 定时处理采集失败的记录
|
||||
3.生成任务信息
|
||||
*/
|
||||
task := system.FilmCollectTask{Id: util.GenerateSalt(), Time: config.DefaultUpdateTime, Spec: config.DefaultUpdateSpec,
|
||||
Model: 0, State: false, Remark: "每20分钟执行一次已启用站点数据的自动更新"}
|
||||
// 添加一条定时任务
|
||||
// 添加一条定时任务-影片定时更新
|
||||
cid, err := spider.AddAutoUpdateCron(task.Id, task.Spec)
|
||||
// 如果任务添加失败则直接返回错误信息
|
||||
if err != nil {
|
||||
@@ -87,6 +100,21 @@ func CollectCrontabInit() {
|
||||
task.Cid = cid
|
||||
// 如果没有异常则将当前定时任务信息记录到redis中
|
||||
system.SaveFilmTask(task)
|
||||
|
||||
// 添加一条定时任务-定期处理失败请求
|
||||
recoverTask := system.FilmCollectTask{Id: util.GenerateSalt(), Time: 0, Spec: config.EveryWeekSpec,
|
||||
Model: 2, State: false, Remark: "每周日凌晨4点清理一次采集失败的采集记录"}
|
||||
// 添加一条定时任务-影片定时更新
|
||||
cid, err = spider.AddFilmRecoverCron(recoverTask.Spec)
|
||||
// 如果任务添加失败则直接返回错误信息
|
||||
if err != nil {
|
||||
log.Println("失败采集恢复定时任务添加失败: ", err.Error())
|
||||
return
|
||||
}
|
||||
// 将定时任务Id记录到Task中
|
||||
recoverTask.Cid = cid
|
||||
// 如果没有异常则将当前定时任务信息记录到redis中
|
||||
system.SaveFilmTask(recoverTask)
|
||||
}
|
||||
|
||||
// 完成初始化后启动 Cron
|
||||
|
||||
@@ -26,6 +26,7 @@ type RequestInfo struct {
|
||||
Params url.Values `json:"param"` // 请求参数
|
||||
Header http.Header `json:"header"` // 请求头数据
|
||||
Resp []byte `json:"resp"` // 响应结果数据
|
||||
Err string `json:"err"` // 错误信息
|
||||
}
|
||||
|
||||
// RefererUrl 记录上次请求的url
|
||||
@@ -95,6 +96,7 @@ func ApiGet(r *RequestInfo) {
|
||||
// 处理请求参数
|
||||
err := Client.Visit(fmt.Sprintf("%s?%s", r.Uri, r.Params.Encode()))
|
||||
if err != nil {
|
||||
r.Err = err.Error()
|
||||
log.Println("获取数据失败: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package db
|
||||
import (
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/schema"
|
||||
"server/config"
|
||||
)
|
||||
@@ -24,7 +25,7 @@ func InitMysql() (err error) {
|
||||
SingularTable: true, //是否使用 结构体名称作为表名 (关闭自动变复数)
|
||||
//NameReplacer: strings.NewReplacer("spider_", ""), // 替表名和字段中的 Me 为 空
|
||||
},
|
||||
//Logger: logger.Default.LogMode(logger.Info), //设置日志级别为Info
|
||||
Logger: logger.Default.LogMode(logger.Info), //设置日志级别为Info
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"net/url"
|
||||
"server/config"
|
||||
"server/model/collect"
|
||||
@@ -126,7 +127,7 @@ func CollectCategory(s *system.FilmSource) {
|
||||
}
|
||||
}
|
||||
|
||||
// 影视详情采集
|
||||
// collectFilm 影视详情采集 (单一源分页全采集)
|
||||
func collectFilm(s *system.FilmSource, h, pg int) {
|
||||
// 生成请求参数
|
||||
r := util.RequestInfo{Uri: s.Uri, Params: url.Values{}}
|
||||
@@ -139,6 +140,9 @@ func collectFilm(s *system.FilmSource, h, pg int) {
|
||||
// 执行采集方法 获取影片详情list
|
||||
list, err := spiderCore.GetFilmDetail(r)
|
||||
if err != nil || len(list) <= 0 {
|
||||
// 添加采集失败记录
|
||||
fr := system.FailureRecord{OriginId: s.Id, OriginName: s.Name, Uri: s.Uri, CollectType: system.CollectVideo, PageNumber: pg, Hour: h, Cause: fmt.Sprintln(err), Status: 1}
|
||||
system.SaveFailureRecord(fr)
|
||||
log.Println("GetMovieDetail Error: ", err)
|
||||
return
|
||||
}
|
||||
@@ -163,6 +167,41 @@ func collectFilm(s *system.FilmSource, h, pg int) {
|
||||
}
|
||||
}
|
||||
|
||||
// collectFilmById 采集指定ID的影片信息
|
||||
func collectFilmById(ids string, s *system.FilmSource) {
|
||||
// 生成请求参数
|
||||
r := util.RequestInfo{Uri: s.Uri, Params: url.Values{}}
|
||||
// 设置分页页数
|
||||
r.Params.Set("pg", "1")
|
||||
// 设置影片IDS参数信息
|
||||
r.Params.Set("ids", ids)
|
||||
// 执行采集方法 获取影片详情list
|
||||
list, err := spiderCore.GetFilmDetail(r)
|
||||
if err != nil || len(list) <= 0 {
|
||||
log.Println("GetMovieDetail Error: ", err)
|
||||
return
|
||||
}
|
||||
// 通过采集站 Grade 类型, 执行不同的存储逻辑
|
||||
switch s.Grade {
|
||||
case system.MasterCollect:
|
||||
// 主站点 保存完整影片详情信息到 redis 和 mysql 中
|
||||
if err = system.SaveDetail(list[0]); err != nil {
|
||||
log.Println("SaveDetails Error: ", err)
|
||||
}
|
||||
// 如果主站点开启了图片同步, 则将图片url以及对应的mid存入ZSet集合中
|
||||
if s.SyncPictures {
|
||||
if err = system.SaveVirtualPic(conver.ConvertVirtualPicture(list)); err != nil {
|
||||
log.Println("SaveVirtualPic Error: ", err)
|
||||
}
|
||||
}
|
||||
case system.SlaveCollect:
|
||||
// 附属站点 仅保存影片播放信息到redis
|
||||
if err = system.SaveSitePlayList(s.Id, list); err != nil {
|
||||
log.Println("SaveDetails Error: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConcurrentPageSpider 并发分页采集, 不限类型
|
||||
func ConcurrentPageSpider(capacity int, s *system.FilmSource, h int, collectFunc func(s *system.FilmSource, hour, pageNumber int)) {
|
||||
// 开启协程并发执行
|
||||
@@ -191,7 +230,7 @@ func ConcurrentPageSpider(capacity int, s *system.FilmSource, h int, collectFunc
|
||||
}
|
||||
}()
|
||||
}
|
||||
for i := 0; i < config.MAXGoroutine; i++ {
|
||||
for i := 0; i < GoroutineNum; i++ {
|
||||
<-waitCh
|
||||
}
|
||||
}
|
||||
@@ -229,7 +268,7 @@ func AutoCollect(h int) {
|
||||
}
|
||||
}
|
||||
|
||||
// ClearSpider 删除已采集的影片信息
|
||||
// ClearSpider 删除所有已采集的影片信息
|
||||
func ClearSpider() {
|
||||
system.FilmZero()
|
||||
}
|
||||
@@ -242,6 +281,80 @@ func StarZero(h int) {
|
||||
AutoCollect(h)
|
||||
}
|
||||
|
||||
// CollectSingleFilm 通过影片唯一ID获取影片信息
|
||||
func CollectSingleFilm(ids string) {
|
||||
// 获取采集站列表信息
|
||||
fl := system.GetCollectSourceList()
|
||||
// 循环遍历所有采集站信息
|
||||
for _, f := range fl {
|
||||
// 目前仅对主站点进行处理
|
||||
if f.Grade == system.MasterCollect && f.State {
|
||||
collectFilmById(ids, &f)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================= 采集拓展内容 =======================================================
|
||||
|
||||
// SingleRecoverSpider 二次采集
|
||||
func SingleRecoverSpider(fr *system.FailureRecord) {
|
||||
// 通过采集时长范围执行不同的采集方式
|
||||
switch {
|
||||
case fr.Hour > 168 && fr.Hour < 360:
|
||||
// 将此记录之后的所有同类采集记录变更为已重试
|
||||
system.ChangeRecord(fr, 0)
|
||||
// 如果采集的内容是 7~15 天之内更新的内容,则采集此记录之后的所有更新内容
|
||||
// 获取采集参数h, 采集时长变更为 原采集时长 + 采集记录距现在的时长
|
||||
h := fr.Hour + int(math.Ceil(time.Since(fr.CreatedAt).Hours()))
|
||||
// 对当前所有已启用的站点 更新最新 h 小时的内容
|
||||
AutoCollect(h)
|
||||
case fr.Hour < 0, fr.Hour > 4320:
|
||||
// 将此记录状态修改为已重试
|
||||
system.ChangeRecord(fr, 0)
|
||||
// 如果采集的是 最近180天内更新的内容 或全部内容, 则只对当前一条记录进行二次采集
|
||||
s := system.FindCollectSourceById(fr.OriginId)
|
||||
collectFilm(s, fr.Hour, fr.PageNumber)
|
||||
default:
|
||||
// 其余范围,暂不处理
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// FullRecoverSpider 扫描记录表中的失败记录, 并进行处理 (用于定时任务定期处理失败采集)
|
||||
func FullRecoverSpider() {
|
||||
/*
|
||||
获取待处理的记录数据
|
||||
1. 采集时长 > 168h (一周,7天) 状态-1 待处理, | 只获取满足条件的最早的待处理记录
|
||||
2. 采集时长 > 4320h (半年,180天) 状态-1 待处理, | 获取满足条件的所有数据
|
||||
*/
|
||||
list := system.PendingRecord()
|
||||
|
||||
// 遍历记录信息切片, 针对不同时长进行不同处理
|
||||
for _, fr := range list {
|
||||
switch {
|
||||
case fr.Hour > 0 && fr.Hour < 4320:
|
||||
// 将此记录之后的所有同类采集记录变更为已重试
|
||||
system.ChangeRecord(&fr, 0)
|
||||
// 如果采集的内容是 0~180 天之内更新的内容,则采集此记录之后的所有更新内容
|
||||
// 获取采集参数h, 采集时长变更为 原采集时长 + 采集记录距现在的时长
|
||||
h := fr.Hour + int(math.Ceil(time.Since(fr.CreatedAt).Hours()))
|
||||
// 对当前所有已启用的站点 更新最新 h 小时的内容
|
||||
AutoCollect(h)
|
||||
case fr.Hour < 0, fr.Hour > 4320:
|
||||
// 将此记录状态修改为已重试
|
||||
system.ChangeRecord(&fr, 0)
|
||||
// 如果采集的是 180天之前更新的内容 或全部内容, 则只对当前一条记录进行二次采集
|
||||
s := system.FindCollectSourceById(fr.OriginId)
|
||||
collectFilm(s, fr.Hour, fr.PageNumber)
|
||||
default:
|
||||
// 其余范围,暂不处理
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ======================================================= 公共方法 =======================================================
|
||||
|
||||
// CollectApiTest 测试采集接口是否可用
|
||||
|
||||
@@ -93,7 +93,7 @@ func (jc *JsonCollect) GetFilmDetail(r util.RequestInfo) (list []system.MovieDet
|
||||
//details := system.DetailListInfo{}
|
||||
// 如果返回数据为空则直接结束本次循环
|
||||
if len(r.Resp) <= 0 {
|
||||
err = errors.New("response is empty")
|
||||
err = errors.New(r.Err)
|
||||
return
|
||||
}
|
||||
// 序列化详情数据
|
||||
@@ -132,6 +132,23 @@ func (jc *JsonCollect) GetSingleFilm(r util.RequestInfo, ids string) {
|
||||
//
|
||||
}
|
||||
|
||||
// FailureRecord 记录失败采集的相关信息, 用于后续采集重试操作
|
||||
func (jc *JsonCollect) FailureRecord(r util.RequestInfo) {
|
||||
// 记录采集失败时的采集参数
|
||||
|
||||
// 1. 采集站信息 (ID)
|
||||
|
||||
// 2. 采集参数, h 最新x小时影片, pg 页码
|
||||
|
||||
// 3. 将失败信息记录到redis ZSet集合中, score - time | member - data
|
||||
|
||||
}
|
||||
|
||||
// FilmDetailRetry 影片详情重试机制
|
||||
func (jc *JsonCollect) FilmDetailRetry(r util.RequestInfo) {
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------- XML Collect -------------------------------------------------
|
||||
|
||||
// XmlCollect 处理返回值为XML格式的采集数据
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"log"
|
||||
"server/config"
|
||||
"server/model/system"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -19,7 +18,7 @@ func CreateCron() *cron.Cron {
|
||||
return cron.New(cron.WithSeconds())
|
||||
}
|
||||
|
||||
// AddFilmUpdateCron 添加影片更新定时任务
|
||||
// AddFilmUpdateCron 添加 指定站点的影片更新定时任务
|
||||
func AddFilmUpdateCron(id, spec string) (cron.EntryID, error) {
|
||||
// 校验 spec 表达式的有效性
|
||||
if err := ValidSpec(spec); err != nil {
|
||||
@@ -41,7 +40,7 @@ func AddFilmUpdateCron(id, spec string) (cron.EntryID, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// AddAutoUpdateCron 自动更新定时任务
|
||||
// AddAutoUpdateCron 添加 所有已启用站点的影片更新定时任务
|
||||
func AddAutoUpdateCron(id, spec string) (cron.EntryID, error) {
|
||||
// 校验 spec 表达式的有效性
|
||||
if err := ValidSpec(spec); err != nil {
|
||||
@@ -61,6 +60,19 @@ func AddAutoUpdateCron(id, spec string) (cron.EntryID, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// AddFilmRecoverCron 失败采集记录处理
|
||||
func AddFilmRecoverCron(spec string) (cron.EntryID, error) {
|
||||
// 校验 spec 表达式的有效性
|
||||
if err := ValidSpec(spec); err != nil {
|
||||
return -99, errors.New(fmt.Sprint("定时任务添加失败,Cron表达式校验失败: ", err.Error()))
|
||||
}
|
||||
return CronCollect.AddFunc(spec, func() {
|
||||
// 执行失败采集记录恢复
|
||||
FullRecoverSpider()
|
||||
log.Println("执行一次失败采集恢复任务")
|
||||
})
|
||||
}
|
||||
|
||||
// RemoveCron 删除定时任务
|
||||
func RemoveCron(id cron.EntryID) {
|
||||
// 通过定时任务EntryID移出对应的定时任务
|
||||
@@ -69,8 +81,8 @@ func RemoveCron(id cron.EntryID) {
|
||||
|
||||
// GetEntryById 返回定时任务的相关时间信息
|
||||
func GetEntryById(id cron.EntryID) cron.Entry {
|
||||
log.Printf("%+v\n", CronCollect.Entries())
|
||||
log.Println("", CronCollect.Entry(id).Next.Format(time.DateTime))
|
||||
//log.Printf("CronInfo: %+v\n", CronCollect.Entries())
|
||||
//log.Println("Corn Next Execute Time:", CronCollect.Entry(id).Next.Format(time.DateTime))
|
||||
return CronCollect.Entry(id)
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,13 @@ func SetupRouter() *gin.Engine {
|
||||
//collect.GET(`/star`, controller.CollectFilm)
|
||||
collect.GET(`/del`, controller.FilmSourceDel)
|
||||
collect.GET(`/options`, controller.GetNormalFilmSource)
|
||||
|
||||
collect.GET(`/record/list`, controller.FailureRecordList)
|
||||
collect.GET(`/record/retry`, controller.CollectRecover)
|
||||
collect.GET(`/record/retry/all`, controller.CollectRecoverAll)
|
||||
collect.GET(`/record/clear/done`, controller.ClearDoneRecord)
|
||||
collect.GET(`/record/clear/all`, controller.ClearAllRecord)
|
||||
|
||||
}
|
||||
|
||||
// 定时任务相关
|
||||
@@ -91,6 +98,7 @@ func SetupRouter() *gin.Engine {
|
||||
spiderRoute.POST(`/start`, controller.StarSpider)
|
||||
spiderRoute.GET(`/zero`, controller.SpiderReset)
|
||||
spiderRoute.GET(`/clear`, controller.ClearAllFilm)
|
||||
spiderRoute.GET(`/update/single`, controller.SingleUpdateSpider)
|
||||
spiderRoute.GET(`/class/cover`, controller.CoverFilmClass)
|
||||
}
|
||||
// filmManage 影视管理
|
||||
|
||||
@@ -45,11 +45,26 @@ func (i *IndexLogic) IndexPage() map[string]interface{} {
|
||||
// 2. 提供用于首页展示的顶级分类影片信息, 每分类 14条数据
|
||||
var list []map[string]interface{}
|
||||
for _, c := range tree.Children {
|
||||
// 生成分页参数
|
||||
page := system.Page{PageSize: 14, Current: 1}
|
||||
movies := system.GetMovieListByPid(c.Id, &page)
|
||||
// 获取当前分类的本月热门影片
|
||||
HotMovies := system.GetHotMovieByPid(c.Id, &page)
|
||||
item := map[string]interface{}{"nav": c, "movies": movies, "hot": HotMovies}
|
||||
// 获取最近上映影片和本月热门影片
|
||||
var movies []system.MovieBasicInfo
|
||||
var hotMovies []system.SearchInfo
|
||||
if c.Children != nil {
|
||||
// 如果有子分类, 则通过Pid获取对应影片
|
||||
// 获取当前分类的最新上映影片
|
||||
movies = system.GetMovieListByPid(c.Id, &page)
|
||||
// 获取当前分类的本月热门影片
|
||||
hotMovies = system.GetHotMovieByPid(c.Id, &page)
|
||||
} else {
|
||||
// 如果当前分类为一级分类且没有子分类,则通过Cid获取对应数据
|
||||
// 获取当前分类的最新上映影片
|
||||
movies = system.GetMovieListByCid(c.Id, &page)
|
||||
// 获取当前分类的本月热门影片
|
||||
hotMovies = system.GetHotMovieByCid(c.Id, &page)
|
||||
}
|
||||
|
||||
item := map[string]interface{}{"nav": c, "movies": movies, "hot": hotMovies}
|
||||
list = append(list, item)
|
||||
}
|
||||
Info["content"] = list
|
||||
|
||||
@@ -7,11 +7,12 @@ import (
|
||||
"server/plugin/SystemInit"
|
||||
"server/plugin/db"
|
||||
"server/router"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 执行初始化前等待20s , 让mysql服务完成初始化指令
|
||||
//time.Sleep(time.Second * 20)
|
||||
time.Sleep(time.Second * 20)
|
||||
//初始化redis客户端
|
||||
err := db.InitRedisConn()
|
||||
if err != nil {
|
||||
|
||||
@@ -39,8 +39,18 @@ func CreateFailureRecordTable() {
|
||||
|
||||
// SaveFailureRecord 添加采集失效记录
|
||||
func SaveFailureRecord(fl FailureRecord) {
|
||||
if err := db.Mdb.Create(&fl).Error; err != nil {
|
||||
log.Println("Add failure record failed:", err)
|
||||
// 数据量不多但存在并发问题, 开启事务
|
||||
err := db.Mdb.Transaction(func(tx *gorm.DB) error {
|
||||
// 将采集失败信息存储到record表中
|
||||
if err := tx.Create(&fl).Error; err != nil {
|
||||
log.Println("Add failure record failed:", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
// 如果事务提交失败, 则输出相应信息, (存一份数据到Redis??)
|
||||
if err != nil {
|
||||
log.Println("Save failure record affairs failed:", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ func GetMovieListByCid(cid int64, page *Page) []MovieBasicInfo {
|
||||
return list
|
||||
}
|
||||
|
||||
// GetHotMovieByPid 获取指定类别的热门影片
|
||||
// GetHotMovieByPid 获取Pid指定类别的热门影片
|
||||
func GetHotMovieByPid(pid int64, page *Page) []SearchInfo {
|
||||
// 返回分页参数
|
||||
//var count int64
|
||||
@@ -453,6 +453,24 @@ func GetHotMovieByPid(pid int64, page *Page) []SearchInfo {
|
||||
return s
|
||||
}
|
||||
|
||||
// GetHotMovieByCid 获取当前分类下的热门影片
|
||||
func GetHotMovieByCid(cid int64, page *Page) []SearchInfo {
|
||||
// 返回分页参数
|
||||
//var count int64
|
||||
//db.Mdb.Model(&SearchInfo{}).Where("pid", pid).Count(&count)
|
||||
//page.Total = int(count)
|
||||
//page.PageCount = int((page.Total + page.PageSize - 1) / page.PageSize)
|
||||
// 进行具体的信息查询
|
||||
var s []SearchInfo
|
||||
// 当前时间偏移一个月
|
||||
t := time.Now().AddDate(0, -1, 0).Unix()
|
||||
if err := db.Mdb.Limit(page.PageSize).Offset((page.Current-1)*page.PageSize).Where("cid=? AND update_stamp > ?", cid, t).Order(" year DESC, hits DESC").Find(&s).Error; err != nil {
|
||||
log.Println(err)
|
||||
return nil
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// SearchFilmKeyword 通过关键字搜索库存中满足条件的影片名
|
||||
func SearchFilmKeyword(keyword string, page *Page) []SearchInfo {
|
||||
var searchList []SearchInfo
|
||||
|
||||
@@ -36,7 +36,7 @@ func CreateUserTable() {
|
||||
// 如果不存在则创建表 并设置自增ID初始值为10000
|
||||
if !ExistUserTable() {
|
||||
err := db.Mdb.AutoMigrate(u)
|
||||
db.Mdb.Exec(fmt.Sprintf("alter table %s auto_Increment = %s", u.TableName(), config.UserIdInitialVal))
|
||||
db.Mdb.Exec(fmt.Sprintf("alter table %s auto_Increment = %d", u.TableName(), config.UserIdInitialVal))
|
||||
if err != nil {
|
||||
log.Println("Create Table SearchInfo Failed: ", err)
|
||||
}
|
||||
@@ -81,6 +81,7 @@ func GetUserByNameOrEmail(userName string) *User {
|
||||
return u
|
||||
}
|
||||
|
||||
// GetUserById 通过id获取对应的用户信息
|
||||
func GetUserById(id uint) User {
|
||||
var user = User{Model: gorm.Model{ID: id}}
|
||||
db.Mdb.First(&user)
|
||||
|
||||
@@ -29,6 +29,9 @@ func FilmSourceInit() {
|
||||
{Id: util.GenerateSalt(), Name: "HD(LY)", Uri: `https://360zy.com/api.php/provide/vod/at/json`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
{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: false, Interval: 2000},
|
||||
{Id: util.GenerateSalt(), Name: "HD(DB)", Uri: `https://caiji.dbzy.tv/api.php/provide/vod/from/dbm3u8/at/josn/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
{Id: util.GenerateSalt(), Name: "HD(IK)", Uri: `https://ikunzyapi.com/api.php/provide/vod/at/json`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
//{Id: util.GenerateSalt(), Name: "WX(T2)", Uri: `https://api.wuxianzy.net/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
//{Id: util.GenerateSalt(), Name: "OK(BK)", Uri: `https://api.okzy.org/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
//{Id: util.GenerateSalt(), Name: "HD(HW)", Uri: `https://cjhwba.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false, Interval: 3000},
|
||||
//{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: false},
|
||||
//{Id: util.GenerateSalt(), Name: "HD(fs)", Uri: `https://www.feisuzyapi.com/api.php/provide/vod/`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
|
||||
@@ -3,6 +3,7 @@ package db
|
||||
import (
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/schema"
|
||||
"server/config"
|
||||
)
|
||||
@@ -24,7 +25,7 @@ func InitMysql() (err error) {
|
||||
SingularTable: true, //是否使用 结构体名称作为表名 (关闭自动变复数)
|
||||
//NameReplacer: strings.NewReplacer("spider_", ""), // 替表名和字段中的 Me 为 空
|
||||
},
|
||||
//Logger: logger.Default.LogMode(logger.Info), //设置日志级别为Info
|
||||
Logger: logger.Default.LogMode(logger.Info), //设置日志级别为Info
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user