mirror of
https://github.com/ProudMuBai/GoFilm.git
synced 2026-02-04 06:54:41 +08:00
collect failed manage
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
<span>采集管理</span>
|
||||
</template>
|
||||
<el-menu-item index="/manage/collect/index">影视采集</el-menu-item>
|
||||
<el-menu-item index="/manage/collect/record">失效记录</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="/manage/cron">
|
||||
<template #title>
|
||||
|
||||
@@ -27,6 +27,7 @@ import FilmAdd from "../views/manage/film/FilmAdd.vue";
|
||||
import CustomPlay from "../views/index/CustomPlay.vue";
|
||||
import Banners from "../views/manage/system/Banners.vue";
|
||||
import FilmHistory from "../views/index/FilmHistory.vue";
|
||||
import FailureRecord from "../views/manage/collect/FailureRecord.vue";
|
||||
|
||||
|
||||
// 2. 定义一个路由
|
||||
@@ -54,6 +55,7 @@ const routes = [
|
||||
children: [
|
||||
{path: 'index', component: ManageIndex},
|
||||
{path: 'collect/index', component: CollectManage},
|
||||
{path: 'collect/record', component: FailureRecord},
|
||||
{path: 'system/webSite', component: SiteConfig},
|
||||
{path: 'system/banners', component: Banners},
|
||||
{path: 'cron/index', component: CronManage},
|
||||
|
||||
180
client/src/views/manage/collect/FailureRecord.vue
Normal file
180
client/src/views/manage/collect/FailureRecord.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
|
||||
<div class="content">
|
||||
<el-table
|
||||
:data="data.records" style="width: 100%" border size="default"
|
||||
table-layout="auto" max-height="calc(68vh - 20px)"
|
||||
row-key="id" fit
|
||||
:row-class-name="'cus-tr'">
|
||||
<el-table-column type="index" align="left" min-width="35px" label="序列">
|
||||
<template #default="scope">
|
||||
<span style="color: #8b40ff">{{ scope.row.ID }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="originId" align="center" label="采集站">
|
||||
<template #default="scope">
|
||||
<el-tag type="primary" disable-transitions>{{ scope.row.originName }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="originId" align="center" min-width="100px" label="采集源ID">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" disable-transitions>{{ scope.row.originId }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="collectType" align="center" label="采集类型" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag type="success" disable-transitions>{{ scope.row.collectType == 0 ? '影片详情' : '未知' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="pageNumber" align="center" label="分页页码">
|
||||
<template #default="scope">
|
||||
<el-tag type="warning" disable-transitions>{{ scope.row.pageNumber }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="hour" align="center" label="采集时长">
|
||||
<template #default="scope">
|
||||
<el-tag type="warning" disable-transitions>{{ scope.row.hour }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="cause" align="center" label="失败原因" min-width="150px" >
|
||||
<template #default="scope">
|
||||
<el-tag type="danger" disable-transitions>{{ scope.row.cause }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" align="center" label="状态">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status == 1" type="warning">待重试</el-tag>
|
||||
<el-tag v-else type="success">已处理</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="UpdatedAt" align="center" label="执行时间" min-width="100px" >
|
||||
<template #default="scope">
|
||||
<el-tag :type="`${scope.row.status == 1 ? 'warning':'success' }`" disable-transitions>{{ scope.row.timeFormat }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" min-width="100px">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="采集重试" placement="top"><el-button type="success" :icon="RefreshRight" @click="collectRecover(scope.row.ID)" plain circle/></el-tooltip>
|
||||
<el-tooltip content="删除记录" placement="top"><el-button type="danger" :icon="Delete" @click="delRecord(scope.row.ID)" plain circle/></el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pagination">
|
||||
<el-pagination :page-sizes="[10, 20, 50, 100, 500]" background layout="prev, pager, next, sizes, total, jumper"
|
||||
:total="data.page.total" v-model:page-size="data.page.pageSize"
|
||||
v-model:current-page="data.page.current"
|
||||
@change="getRecords" hide-on-single-page/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {Aim, Delete, Edit, RefreshRight} from "@element-plus/icons-vue";
|
||||
import {fmt} from "../../../utils/format";
|
||||
import {onMounted, reactive} from "vue";
|
||||
import {ApiGet} from "../../../utils/request";
|
||||
import {ElMessage} from "element-plus";
|
||||
|
||||
|
||||
const data = reactive({
|
||||
records: [],
|
||||
page: {current: 1, pageCount: 0, pageSize: 10, total: 0},
|
||||
params: {},
|
||||
})
|
||||
|
||||
|
||||
// 获取影片分页信息
|
||||
const getRecords = () => {
|
||||
let {current, pageSize} = data.page
|
||||
let params = data.params
|
||||
ApiGet(`/manage/collect/record/list`, {...params, current, pageSize}).then((resp: any) => {
|
||||
if (resp.code === 0) {
|
||||
resp.data.list.map((item: any) => {
|
||||
// 对数据进行格式化处理
|
||||
item.timeFormat = fmt.dateFormat(new Date(item.UpdatedAt).getTime())
|
||||
return item
|
||||
})
|
||||
data.records = resp.data.list
|
||||
data.page = resp.data.params.paging
|
||||
} else {
|
||||
ElMessage.error({message: resp.msg})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 恢复采集, 对已采集失败的记录进行重试操作
|
||||
const collectRecover = (id:number)=>{
|
||||
ApiGet(`/manage/collect/record/retry`, {id:id}).then((resp: any) => {
|
||||
if(resp.code === 0){
|
||||
ElMessage.success({message: resp.msg})
|
||||
} else{
|
||||
ElMessage.error({message: resp.msg})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 删除当前记录, 貌似不合理
|
||||
const delRecord = (id:number)=>{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 清除所有失败采集记录
|
||||
const clearAllRecord = ()=>{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
// 获取分页数据
|
||||
getRecords()
|
||||
console.log(data)
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.content {
|
||||
border: 1px solid #9b49e733;
|
||||
background: var(--bg-light);
|
||||
--el-color-primary: var(--paging-parmary-color);
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin: 20px auto;
|
||||
max-width: 100%;
|
||||
text-align: center;
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
:deep(.el-pagination) {
|
||||
width: 100% !important;
|
||||
justify-content: end;
|
||||
--el-color-primary: var(--paging-parmary-color);
|
||||
}
|
||||
|
||||
:deep(.el-pager li) {
|
||||
--el-pagination-button-bg-color: var(--btn-bg-linght);
|
||||
border: 1px solid var(--border-gray-color);
|
||||
}
|
||||
|
||||
:deep(.el-pagination button) {
|
||||
--el-disabled-bg-color: var(--btn-bg-linght);
|
||||
--el-pagination-button-bg-color: var(--btn-bg-linght);
|
||||
border: 1px solid var(--border-gray-color);
|
||||
}
|
||||
</style>
|
||||
@@ -51,7 +51,7 @@
|
||||
table-layout="auto" max-height="calc(68vh - 20px)"
|
||||
row-key="id"
|
||||
:row-class-name="'cus-tr'">
|
||||
<el-table-column type="index" min-width="50px" align="left" label="序号">
|
||||
<el-table-column type="index" min-width="40px" align="left" label="序号">
|
||||
<template #default="scope">
|
||||
<span style="color: #8b40ff">{{ serialNum(scope.$index) }}</span>
|
||||
</template>
|
||||
|
||||
@@ -71,11 +71,6 @@ const (
|
||||
DefaultUpdateSpec = "0 */20 * * * ?"
|
||||
// DefaultUpdateTime 每次采集最近 3 小时内更新的影片
|
||||
DefaultUpdateTime = 3
|
||||
|
||||
// FailureAllCollectKey 失败采集记录-全量采集记录
|
||||
FailureAllCollectKey = "CollectRecord:Fail:%s"
|
||||
// FailureUpdateCollectKey 失败采集记录-更新失败记录
|
||||
FailureUpdateCollectKey = "CollectRecord:Fail:%s"
|
||||
)
|
||||
|
||||
// -------------------------Web API相关redis key-----------------------------------
|
||||
|
||||
238
server/controller/CollectController.go
Normal file
238
server/controller/CollectController.go
Normal file
@@ -0,0 +1,238 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"server/logic"
|
||||
"server/model/system"
|
||||
"server/plugin/spider"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// ------------------------------------------------------ 影视采集 ------------------------------------------------------
|
||||
|
||||
// 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"))
|
||||
|
||||
// 分页参数
|
||||
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
|
||||
}
|
||||
|
||||
// 获取满足条件的分页数据
|
||||
list := logic.CollectL.GetRecordList(params)
|
||||
system.Success(gin.H{"params": params, "list": list}, "影片分页信息获取成功", 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)
|
||||
}
|
||||
@@ -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 网站基本配置
|
||||
|
||||
71
server/logic/CollectLogic.go
Normal file
71
server/logic/CollectLogic.go
Normal file
@@ -0,0 +1,71 @@
|
||||
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)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
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"` // 页码
|
||||
@@ -43,14 +44,27 @@ func SaveFailureRecord(fl FailureRecord) {
|
||||
}
|
||||
|
||||
// FailureRecordList 获取所有的采集失效记录
|
||||
func FailureRecordList(page *Page) []FailureRecord {
|
||||
var count int64
|
||||
db.Mdb.Model(&FailureRecord{}).Count(&count)
|
||||
page.Total = int(count)
|
||||
page.PageCount = int((page.Total + page.PageSize - 1) / page.PageSize)
|
||||
func FailureRecordList(vo RecordRequestVo) []FailureRecord {
|
||||
// 通过RecordRequestVo,生成查询条件
|
||||
qw := db.Mdb.Model(&FailureRecord{})
|
||||
if vo.OriginId != "" {
|
||||
qw.Where("origin_id = ?", vo.OriginId)
|
||||
}
|
||||
//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 := db.Mdb.Limit(page.PageSize).Offset((page.Current - 1) * page.PageSize).Find(&list).Error; err != nil {
|
||||
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
|
||||
}
|
||||
@@ -62,10 +76,23 @@ func FindRecordById(id uint) *FailureRecord {
|
||||
var fr FailureRecord
|
||||
fr.ID = id
|
||||
// 通过ID查询对应的数据
|
||||
db.Mdb.First(fr)
|
||||
db.Mdb.First(&fr)
|
||||
return &fr
|
||||
}
|
||||
|
||||
// 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对应的失败记录
|
||||
|
||||
@@ -109,7 +109,16 @@ 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"` // 状态
|
||||
Paging *Page `json:"paging"` // 分页参数
|
||||
}
|
||||
|
||||
@@ -27,14 +27,12 @@ func FilmSourceInit() {
|
||||
{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(YZ)", Uri: `https://api.1080zyku.com/inc/apijson.php`, ResultModel: system.JsonResult, Grade: system.SlaveCollect, SyncPictures: false, CollectType: system.CollectVideo, State: false},
|
||||
{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: 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(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(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(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(bfApp)", Uri: `http://app.bfzyapi.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://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(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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"net/url"
|
||||
"server/config"
|
||||
"server/model/collect"
|
||||
@@ -140,7 +141,7 @@ func collectFilm(s *system.FilmSource, h, pg int) {
|
||||
list, err := spiderCore.GetFilmDetail(r)
|
||||
if err != nil || len(list) <= 0 {
|
||||
// 添加采集失败记录
|
||||
fr := system.FailureRecord{OriginId: s.Id, Uri: s.Uri, CollectType: system.CollectVideo, PageNumber: pg, Hour: h, Cause: err.Error(), Status: 1}
|
||||
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
|
||||
@@ -294,6 +295,33 @@ func CollectSingleFilm(ids string) {
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================= 采集拓展内容 =======================================================
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ======================================================= 公共方法 =======================================================
|
||||
|
||||
// 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
|
||||
}
|
||||
// 序列化详情数据
|
||||
|
||||
@@ -72,6 +72,9 @@ 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)
|
||||
}
|
||||
|
||||
// 定时任务相关
|
||||
|
||||
Reference in New Issue
Block a user