修改为免登录,定时任务数据初始化

This commit is contained in:
lmk
2026-07-22 10:08:26 +08:00
parent 84ccf8e575
commit 25da7371d6
15 changed files with 593 additions and 619 deletions
+149 -69
View File
@@ -4,97 +4,177 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project
PPGo_Job — 定时任务管理系统,GoFrame v2 重构版
PPGo_Job — 定时任务管理系统,已从 Beego v1 重构为 **GoFrame v2**。支持本机 Shell 执行、HTTP 请求任务和 SSH 远程执行
**框架** GoFrame v2(原版基于 Beego v1
**数据库** SQLite(纯 Go 驱动 `modernc.org/sqlite`,无 CGO
**定时任务:** GoFrame `gcron`原版自定义 crons/ 包
- **框架:** GoFrame v2
- **数据库:** SQLite (`modernc.org/sqlite`纯 Go无 CGO)
- **定时器:** GoFrame `gcron`6 段 cron 表达式,含秒
- **前端:** Vue 3 + Element Plus + TypeScriptVite 构建),旧 LayUI 兼容层已移除
- **远程执行:** SSH (`golang.org/x/crypto/ssh`)Telnet/Agent 模式待实现
- **通知:** 邮件 (`net/smtp`) 已实现,钉钉/微信/短信待补充
## Build & Run
```bash
# 编译(纯 Go,不需要 gcc/MinGW
# 一键构建(前端 + 后端
build_frontend.cmd
# 分步构建
cd frontend && npm install && npm run build && cd ..
CGO_ENABLED=0 go build -o ppgo_job.exe .
# 运行
./ppgo_job.exe
# 访问 http://localhost:8082
# 访问 http://localhost:8082 -> 重定向到 /app/Vue 前端)
# 默认账号 admin / 123456
```
## Test
```bash
# 全部测试
CGO_ENABLED=0 go test -count=1 ./...
# 单元测试(无需启动服务器)
CGO_ENABLED=0 go test -count=1 ./libs/ ./consts/ ./dao/
# 集成测试(启动测试服务器 :18082)
CGO_ENABLED=0 go test -count=1 -timeout=120s -run "TestLogin|TestAuth|TestHome|TestTask|TestServer|TestGroup|TestBan|TestTemplate|TestStatic|TestDatabase|TestCORS" .
# 测试指定包
CGO_ENABLED=0 go test -v -count=1 ./libs/
```
> 集成测试使用端口 `:18082`,不会干扰开发实例。测试前确保 18082 端口未被占用。
## Architecture
```
main.go # GoFrame 启动入口
config.yml # YAML 配置
boot/ # 启动初始化
db.go # 数据库初始化
router.go # 路由注册
tplfunc.go # 自定义模板函数(urlfor/date/substr 等)
init.go # 启动后初始化(加载任务到调度器
controller/ # HTTP 层
base.go # display/ajaxMsg/ajaxList/parseFilters 辅助函数
login.go # 登录/登出
home.go # 首页/仪表盘/帮助
task.go # 任务 CRUD + 服务器/分组/日志/权限管理
service/ # 业务逻辑
scheduler/ # gcron 调度 + 任务执行引擎
dao/ # 数据访问层
model/entity/ # 数据库实体(含 Cols 字段常量)
middleware/ # 认证中间件(Cookie + RBAC 权限)
consts/ # 常量、表名定义
resource/
template/ # LayUI 模板(从原 views/ 迁移
static/ # 静态资源(layui/css/js
sql/schema.sql # 建表 DDL + 初始数据
_old/ # 原 Beego 旧代码(参考用)
agent/ # 远程执行器(独立二进制,后续迁移
config.yml # 配置server/database/jobs/site/notify/email/msg/dingtalk/wechat
boot/
db.go # SQLite 数据目录初始化
router.go # 路由注册(公开路由 / API 路由 / Agent API
init.go # 自动建表 + 种子数据 + 加载调度任务
controller/ # HTTP 层(flat package,按文件组织
base.go # display/ajaxMsg/ajaxList/parseSort 辅助函数
response.go # 统一 JSON 响应格式
api.go # Vue 前端专用 API
login.go # 登录/登出
home.go # 仪表盘
task.go # 任务 CRUD + 审核
admin.go # 服务器/分组/禁用命令/通知模板
system.go # 权限因子/角色/管理员/个人资料
service/
scheduler/
scheduler.go # gcron 调度器单例(AddTask/RemoveTask/UpdateTask/RunTaskNow
task_runner.go # 任务执行引擎(本地 Shell / SSH 远程 / HTTP 请求)
ssh.go # SSH 连接器(密码 + 密钥认证
notify.go # 邮件通知
dao/ # 数据访问层(单例模式 var Xxx = new(xxxDao)
common.go # InsertAndGetId/Update/GetById/buildFilters 通用方法
model/entity/ # 数据库实体(orm 标签 + Cols 字段常量
middleware/auth.go # 认证中间件(Cookie + JWT 双认证 + RBAC 权限)
libs/ # 工具函数(SHA256/JWT/加密)
consts/ # 常量定义(任务状态/通知类型/连接类型)
sql/schema.sql # 建表 DDL 参考
_old/ # Beego 旧代码参考(远程执行器 agent/ 等)
frontend/ # Vue 3 + TypeScript 前端
src/api/ # API 调用层(axios
src/router/ # Vue Router 路由
src/stores/ # Pinia 状态管理
src/views/ # 页面组件
src/layout/ # 布局组件
dist/ # 构建产物(Go 静态文件服务)
```
## Layer Rules
- **controller**参数解析 → 调用 Service/DAO → 渲染模板或返回 JSON。不含业务逻辑。
- **service**业务逻辑。不含 HTTP 概念。
- **dao**数据访问。纯 CRUD。
- **middleware**认证、权限检查。
- **controller**: 参数解析 → 调用 Service/DAO → 渲染模板或 JSON。不含业务逻辑。
- **service**: 业务逻辑。不含 HTTP 概念。
- **dao**: 数据访问。纯 CRUD。单例模式 `var Xxx = new(xxxDao)`
- **middleware**: 认证、权限检查。
## Key Packages
## Route Structure
| Package | Purpose |
路由定义在 `boot/router.go`,分三组:
| 组 | 认证 | 用途 |
|---|---|---|
| `/` 公开 | 无 | `/login_in` 登录、`/` 根路径重定向到 `/app/` |
| `/api/*` | JWT (Authorization Bearer) | Vue 前端所有 API |
| `/server/*`, `/task/*` | 无 (Agent API) | 远程 Agent 注册/状态/任务分发 |
中间件: `ghttp.MiddlewareCORS` 全局 CORS → `middleware.Auth` 双认证(Cookie 兼容旧模板 + JWT 新前端)。
Controller 响应约定:
- `ajaxMsg(r, msg, msgno)``{"status": msgno, "code": msgno, "message": msg}`
- `ajaxList(r, msg, msgno, count, data)``{"code": msgno, "msg": msg, "count": count, "data": data}` (LayUI table 格式)
- controller/response.go `Resp(r).Success(data)` / `Resp(r).Error(msg)``{"code": 0, "msg": "success", "data": ...}` (Vue 前端统一格式)
## Scheduler
- 单例 `service/scheduler.Scheduler`,启动时 `Init()` 加载所有启用任务到 `gcron`
- 使用 `gcron.AddSingleton` → 同一任务不会并发执行
- 任务命名: `task_{id}`
- 更新/删除: `RemoveTask` 后重新 `AddTask`
- 任务类型:
- `shell`: 本机执行(Windows: `CMD /C`, Linux: `sh -c`)或 SSH 远程
- `http`: 从调度器发 HTTP 请求,支持自定义 Method/Headers/Body,自动检测 JSON 响应中的业务错误(code/success/status/errno
## Cron 表达式格式
GoFrame gcron 使用 **6 段格式**(含秒),非标准 5 段:
```
秒 分 时 日 月 周
0 0 3 * * * 每天凌晨 3 点
0 */5 * * * * 每 5 分钟
```
`scheduler.go` 中的 `parseCronFields` 也兼容标准 5 段格式(自动补秒=0)和 `@every 30s` 语法。
## DAO 查询模式
DAO 层扩展了 GoFrame Model 的 `buildFilters` 机制(`dao/common.go`):
```go
// 等值查询
dao.Task.GetList(ctx, page, size, "status", 1)
// LIKE 查询
dao.Task.GetList(ctx, page, size, "task_name like", "%backup%")
// 排序
dao.Task.GetList(ctx, page, size, "@order", "id desc")
```
`parseSort(r)`controller/base.go)做字段名校验(仅字母/数字/下划线)防 SQL 注入。
## Key Config
`config.yml` 关键配置项:
| 路径 | 默认值 | 说明 |
|---|---|---|
| `server.address` | `:8082` | 监听端口 |
| `database.default.name` | `./data/ppgo_job.db` | SQLite 数据库路径 |
| `jobs.pool` | 1000 | 任务并发池大小 |
| `site.name` | 定时任务管理器 | 站点标题 |
| `notify.type` | 0 | 通知方式 (0=邮件, 1=短信, 2=钉钉, 3=微信) |
| `email.*` | — | SMTP 邮件配置 |
## Task Status Constants
| 值 | 含义 |
|---|---|
| `controller` | All HTTP handlers (flat package, organized by file) |
| `dao` | Database CRUD operations, singleton pattern (`var Xxx = new(xxxDao)`) |
| `model/entity` | DB structs with `orm` tags and Cols constants |
| `service/scheduler` | Cron job scheduling + task execution engine |
| `middleware` | Cookie auth + RBAC permission checking |
| `consts` | Table names, status constants, message codes |
| -1 | 已删除 |
| 0 | 已暂停 |
| 1 | 运行中 |
| 2 | 待审核 |
| 3 | 审核失败 |
## Template Convention
## Known Limits
LayUI 模板使用 `{{include "MainContent" .}}` 布局模式(layout.html 中定义)。
- `display(r, "page.html", data)` — 渲染带布局的页面
- `displayTpl(r, "page.html", data)` — 直接渲染模板
- `ajaxMsg(r, msg, code)` — JSON 消息响应
- `ajaxList(r, msg, code, count, data)` — LayUI table JSON 格式
## Database
SQLite 建表脚本:`sql/schema.sql`
首次启动自动创建 `./data/ppgo_job.db`
## Migration Status
| Phase | Status |
|-------|--------|
| 1 项目骨架 | ✅ |
| 2 数据访问层 | ✅ |
| 3 路由+控制器框架 | ✅ |
| 4 认证系统 | ✅ |
| 5 模板渲染 | ✅ |
| 6 任务调度器 | ✅ |
| 7 服务层 | ✅ |
| 8 清理 | ✅ |
待办:SSH/Telnet/Agent 远程执行器(参考 `_old/jobs/job.go`)、通知渠道(参考 `_old/notify/`
- **Telnet/Agent 远程执行** — SSH 已实现,其余待补充(参考 `_old/jobs/job.go`
- **通知渠道** — 邮件已实现,钉钉/微信/短信待补充(参考 `_old/notify/`
- **Agent API** — 路由已预留(`/server/api_*`, `/task/api_*`),Agent 二进制待实现
- **Go 版本** — 要求 go 1.26+
+113
View File
@@ -151,6 +151,9 @@ func autoInitDB(ctx context.Context) {
if authCount == 0 {
seedAuth(ctx)
}
// 种子数据:业务数据(任务分组 + 定时任务)
seedBusinessData(ctx)
}
func seedAuth(ctx context.Context) {
@@ -186,3 +189,113 @@ func seedAuth(ctx context.Context) {
)
}
}
// seedBusinessData 种子数据:业务数据(任务分组 + 定时任务)
func seedBusinessData(ctx context.Context) {
now := time.Now().Unix()
// ---- 任务分组 ----
var groupCount int
_ = g.DB().GetScan(ctx, &groupCount, "SELECT COUNT(*) FROM pp_task_group")
if groupCount == 0 {
g.DB().Exec(ctx,
`INSERT INTO pp_task_group(id, group_name, description, create_id, update_id, create_time, update_time, status)
VALUES(?,?,?,?,?,?,?,?)`,
1, "数据引擎", "Data Engine 定时同步任务", 1, 1, now, now, 1,
)
g.Log().Info(ctx, "已创建默认任务分组: 数据引擎")
}
// ---- 定时任务 ----
var taskCount int
_ = g.DB().GetScan(ctx, &taskCount, "SELECT COUNT(*) FROM pp_task")
if taskCount == 0 {
seedTasks(ctx, now)
}
}
// seedTasks 种子定时任务
func seedTasks(ctx context.Context, now int64) {
type taskSeed struct {
id int
group_id int
server_ids, task_name, description, cron_spec string
concurrent int
task_type, command, url, method, headers, body string
timeout, status int
}
rows := []taskSeed{
{46, 1, "", "数据引擎-补偿扫描", "",
"0 */5 * * * *", 0,
"http", "", "http://host.docker.internal:3013/sync/ctrl/compensate", "POST",
`{"Content-Type":"application/json"}`, "",
600, 0},
{48, 1, "", "腾讯广告-账户列表(account_relation)", "",
"0 0 */6 * * *", 0,
"http", "", "http://host.docker.internal:3013/sync/ctrl/trigger", "POST",
`{"Content-Type":"application/json"}`,
`{"platformCode":"tencent","interfaceCode":"account_relation","fullSync":false}`,
1800, 0},
{49, 1, "", "腾讯广告-图片素材(image)", "",
"0 0 * * * *", 0,
"http", "", "http://host.docker.internal:3013/sync/ctrl/trigger", "POST",
`{"Content-Type":"application/json"}`,
`{"platformCode":"tencent","interfaceCode":"image","fullSync":false}`,
3600, 0},
{50, 1, "", "腾讯广告-视频素材(video)", "",
"0 0 * * * *", 0,
"http", "", "http://host.docker.internal:3013/sync/ctrl/trigger", "POST",
`{"Content-Type":"application/json"}`,
`{"platformCode":"tencent","interfaceCode":"video","fullSync":false}`,
3600, 0},
{51, 1, "", "腾讯广告-音频素材(audio)", "",
"0 0 */6 * * *", 0,
"http", "", "http://host.docker.internal:3013/sync/ctrl/trigger", "POST",
`{"Content-Type":"application/json"}`,
`{"platformCode":"tencent","interfaceCode":"audio","fullSync":false}`,
1800, 0},
{52, 1, "", "腾讯广告-Token刷新", "",
"0 0 3 * * *", 0,
"http", "", "http://host.docker.internal:3013/sync/ctrl/refreshToken", "POST",
`{"Content-Type":"application/json"}`,
`{"platformCode":"tencent"}`,
0, 1},
{53, 1, "", "CID - 图片批量送检", "自动扫描待校验图片并提交到易盾检测",
"0/30 * * * * *", 0,
"http", "", "http://host.docker.internal:3001/material/verify/controller/batch-verify-image", "POST",
`{"Content-Type":"application/json"}`,
"{limit:10}",
120, 0},
{54, 1, "", "CID - 视频批量送检", "自动扫描待校验视频并提交到易盾检测",
"15/30 * * * * *", 0,
"http", "", "http://host.docker.internal:3001/material/verify/controller/batch-verify-video", "POST",
`{"Content-Type":"application/json"}`,
"{limit:10}",
120, 0},
{55, 1, "", "CID - 检测结果轮询", "自动查询易盾检测结果并更新到素材表",
"0 * * * * *", 0,
"http", "", "http://host.docker.internal:3001/yidun/callback/controller/poll-all-results", "POST",
"{}", "",
120, 1},
}
for _, r := range rows {
_, err := g.DB().Exec(ctx,
`INSERT INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES(?,?,?,0,?,?,?,?,?,?,?,?,?,?,?,0,0,?, 0,0,0,'', 1,1,?,?)`,
r.id, r.group_id, r.server_ids, r.task_name, r.description, r.cron_spec,
r.concurrent, r.task_type, r.command, r.url, r.method, r.headers, r.body,
r.timeout, r.status,
now, now,
)
if err != nil {
g.Log().Warningf(ctx, "种子任务插入失败 (id=%d): %v", r.id, err)
}
}
g.Log().Infof(ctx, "已创建 %d 个种子定时任务", len(rows))
}
+1 -1
View File
@@ -1,5 +1,5 @@
server:
address: ":8082"
address: ":8086"
name: "ppgo_job"
logPath: "resource/log/server"
logStdout: true
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -5,8 +5,8 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>定时任务管理器</title>
<script type="module" crossorigin src="/app/assets/index-B1r_eA9y.js"></script>
<link rel="stylesheet" crossorigin href="/app/assets/index-BVLzGyHU.css">
<script type="module" crossorigin src="/app/assets/index-BgU1CNJg.js"></script>
<link rel="stylesheet" crossorigin href="/app/assets/index-D_pQJcpD.css">
</head>
<body>
<div id="app"></div>
+20 -2
View File
@@ -86,10 +86,28 @@ const router = createRouter({
routes,
})
// 路由守卫
router.beforeEach((to, _from, next) => {
// 路由守卫 — 未登录时自动登录(免密进入)
router.beforeEach(async (to, _from, next) => {
const userStore = useUserStore()
if (to.meta.requiresAuth !== false && !userStore.isLoggedIn) {
// 尝试自动登录(内置账号)
try {
const resp = await fetch('/api/login_in', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ username: 'admin', password: '123456' }),
})
const res = await resp.json()
if (res.code === 0 && res.data) {
userStore.setToken(res.data.token)
userStore.setUser(res.data.userInfo)
// 继续进入目标页面
next()
return
}
} catch {
// 自动登录失败,走登录页
}
next('/login')
} else if (to.path === '/login' && userStore.isLoggedIn) {
next('/dashboard')
+63 -37
View File
@@ -2,49 +2,59 @@
<div class="login-page">
<div class="login-card">
<h2 class="login-title">PPGo_Job 管理后台</h2>
<el-form
ref="formRef"
:model="form"
:rules="rules"
size="large"
@keyup.enter="handleLogin"
>
<el-form-item prop="username">
<el-input
v-model="form.username"
placeholder="用户名"
:prefix-icon="User"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="form.password"
type="password"
placeholder="密码"
show-password
:prefix-icon="Lock"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
:loading="loading"
style="width: 100%"
@click="handleLogin"
>
登录
</el-button>
</el-form-item>
</el-form>
<p v-if="error" class="login-error">{{ error }}</p>
<!-- 自动登录中 -->
<div v-if="loading && !autoLoginDone" class="auto-login-hint">
<el-icon class="is-loading" :size="32"><Loading /></el-icon>
<p>正在自动登录...</p>
</div>
<!-- 自动登录失败时显示登录表单 -->
<template v-else-if="error || autoLoginDone">
<el-form
ref="formRef"
:model="form"
:rules="rules"
size="large"
@keyup.enter="handleLogin"
>
<el-form-item prop="username">
<el-input
v-model="form.username"
placeholder="用户名"
:prefix-icon="User"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="form.password"
type="password"
placeholder="密码"
show-password
:prefix-icon="Lock"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
:loading="loading"
style="width: 100%"
@click="handleLogin"
>
登录
</el-button>
</el-form-item>
</el-form>
<p v-if="error" class="login-error">{{ error }}</p>
</template>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ref, reactive, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { User, Lock } from '@element-plus/icons-vue'
import { User, Lock, Loading } from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'
import { login } from '@/api/login'
import type { FormInstance } from 'element-plus'
@@ -54,6 +64,7 @@ const userStore = useUserStore()
const formRef = ref<FormInstance>()
const loading = ref(false)
const error = ref('')
const autoLoginDone = ref(false)
const form = reactive({
username: 'admin',
@@ -87,8 +98,14 @@ async function handleLogin() {
error.value = e.message || '网络错误'
} finally {
loading.value = false
autoLoginDone.value = true
}
}
// 页面加载后自动登录
onMounted(() => {
handleLogin()
})
</script>
<style scoped>
@@ -118,4 +135,13 @@ async function handleLogin() {
margin-top: 10px;
font-size: 14px;
}
.auto-login-hint {
text-align: center;
padding: 20px 0;
color: #666;
}
.auto-login-hint p {
margin-top: 12px;
font-size: 14px;
}
</style>
+27 -2
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@@ -227,10 +228,15 @@ func (s *schedulerService) execHTTP(ctx context.Context, task *entity.Task) *Tas
req.Header.Set("Content-Type", "application/json")
}
g.Log().Infof(ctx, "HTTP请求 -> %s %s", method, task.Url)
g.Log().Infof(ctx, "HTTP请求 -> %s %s (超时=%ds)", method, task.Url, task.Timeout)
resp, err := client.Do(req)
if err != nil {
result.Error = "请求失败: " + err.Error()
if isTimeoutError(err) {
result.IsTimeout = true
result.Error = fmt.Sprintf("请求超时(%d秒): %s", task.Timeout, task.Url)
} else {
result.Error = "请求失败: " + err.Error()
}
return result
}
defer resp.Body.Close()
@@ -387,6 +393,25 @@ func extractMsg(data map[string]interface{}, keys ...string) string {
return ""
}
// isTimeoutError 判断是否为超时错误
func isTimeoutError(err error) bool {
if err == nil {
return false
}
// Go http.Client 超时返回 context.DeadlineExceeded
if errors.Is(err, context.DeadlineExceeded) {
return true
}
// 也检查 net.Error.Timeout()
var netErr interface{ Timeout() bool }
if errors.As(err, &netErr) && netErr.Timeout() {
return true
}
// 兜底:关键字匹配
msg := err.Error()
return strings.Contains(msg, "timeout") || strings.Contains(msg, "deadline exceeded")
}
// parseInt 简单字符串转整数
func parseInt(s string) int {
id := 0
+179
View File
@@ -0,0 +1,179 @@
-- ============================================================================
-- PPGo_Job 数据种子文件
-- 从 Docker 容器导出,用于新环境初始化
-- 生成时间: 2026-07-21
-- ============================================================================
-- 说明:
-- 1. 管理员和权限因子已由 boot/init.go 自动创建,此处不再重复
-- 2. 以下数据在 pp_task_group / pp_task 表为空时才会被 seed
-- ============================================================================
-- ============================================================================
-- 任务分组
-- ============================================================================
INSERT OR IGNORE INTO pp_task_group(id, group_name, description, create_id, update_id, create_time, update_time, status)
VALUES (1, '数据引擎', 'Data Engine 定时同步任务', 1, 1, unixepoch('now'), unixepoch('now'), 1);
-- ============================================================================
-- 定时任务(仅导出 status >= 0 的有效任务)
-- ============================================================================
-- 数据引擎 - 补偿扫描 (id=46, status=0 暂停中)
INSERT OR IGNORE INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES (
46, 1, '', 0, '数据引擎-补偿扫描', '',
'0 */5 * * * *', 0, 'http', '',
'http://host.docker.internal:3013/sync/ctrl/compensate', 'POST',
'{"Content-Type":"application/json"}', '',
600, 0, 0, 0,
0, 0, 0, '',
1, 1, unixepoch('now'), unixepoch('now')
);
-- 腾讯广告 - 账户列表 (id=48, status=0 暂停中)
INSERT OR IGNORE INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES (
48, 1, '', 0, '腾讯广告-账户列表(account_relation)', '',
'0 0 */6 * * *', 0, 'http', '',
'http://host.docker.internal:3013/sync/ctrl/trigger', 'POST',
'{"Content-Type":"application/json"}',
'{"platformCode":"tencent","interfaceCode":"account_relation","fullSync":false}',
1800, 0, 0, 0,
0, 0, 0, '',
1, 1, unixepoch('now'), unixepoch('now')
);
-- 腾讯广告 - 图片素材 (id=49, status=0 暂停中)
INSERT OR IGNORE INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES (
49, 1, '', 0, '腾讯广告-图片素材(image)', '',
'0 0 * * * *', 0, 'http', '',
'http://host.docker.internal:3013/sync/ctrl/trigger', 'POST',
'{"Content-Type":"application/json"}',
'{"platformCode":"tencent","interfaceCode":"image","fullSync":false}',
3600, 0, 0, 0,
0, 0, 0, '',
1, 1, unixepoch('now'), unixepoch('now')
);
-- 腾讯广告 - 视频素材 (id=50, status=0 暂停中)
INSERT OR IGNORE INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES (
50, 1, '', 0, '腾讯广告-视频素材(video)', '',
'0 0 * * * *', 0, 'http', '',
'http://host.docker.internal:3013/sync/ctrl/trigger', 'POST',
'{"Content-Type":"application/json"}',
'{"platformCode":"tencent","interfaceCode":"video","fullSync":false}',
3600, 0, 0, 0,
0, 0, 0, '',
1, 1, unixepoch('now'), unixepoch('now')
);
-- 腾讯广告 - 音频素材 (id=51, status=0 暂停中)
INSERT OR IGNORE INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES (
51, 1, '', 0, '腾讯广告-音频素材(audio)', '',
'0 0 */6 * * *', 0, 'http', '',
'http://host.docker.internal:3013/sync/ctrl/trigger', 'POST',
'{"Content-Type":"application/json"}',
'{"platformCode":"tencent","interfaceCode":"audio","fullSync":false}',
1800, 0, 0, 0,
0, 0, 0, '',
1, 1, unixepoch('now'), unixepoch('now')
);
-- 腾讯广告 - Token刷新 (id=52, status=1 运行中)
INSERT OR IGNORE INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES (
52, 1, '', 0, '腾讯广告-Token刷新', '',
'0 0 3 * * *', 0, 'http', '',
'http://host.docker.internal:3013/sync/ctrl/refreshToken', 'POST',
'{"Content-Type":"application/json"}',
'{"platformCode":"tencent"}',
0, 0, 0, 1,
0, 0, 0, '',
1, 1, unixepoch('now'), unixepoch('now')
);
-- CID - 图片批量送检 (id=53, status=0 暂停中)
INSERT OR IGNORE INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES (
53, 1, '', 0, 'CID - 图片批量送检', '自动扫描待校验图片并提交到易盾检测',
'0/30 * * * * *', 0, 'http', '',
'http://host.docker.internal:3001/material/verify/controller/batch-verify-image', 'POST',
'{"Content-Type":"application/json"}',
'{limit:10}',
120, 0, 0, 0,
0, 0, 0, '',
1, 1, unixepoch('now'), unixepoch('now')
);
-- CID - 视频批量送检 (id=54, status=0 暂停中)
INSERT OR IGNORE INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES (
54, 1, '', 0, 'CID - 视频批量送检', '自动扫描待校验视频并提交到易盾检测',
'15/30 * * * * *', 0, 'http', '',
'http://host.docker.internal:3001/material/verify/controller/batch-verify-video', 'POST',
'{"Content-Type":"application/json"}',
'{limit:10}',
120, 0, 0, 0,
0, 0, 0, '',
1, 1, unixepoch('now'), unixepoch('now')
);
-- CID - 检测结果轮询 (id=55, status=1 运行中)
INSERT OR IGNORE INTO pp_task(
id, group_id, server_ids, server_type, task_name, description, cron_spec,
concurrent, task_type, command, url, method, headers, body,
timeout, execute_times, prev_time, status,
is_notify, notify_type, notify_tpl_id, notify_user_ids,
create_id, update_id, create_time, update_time
) VALUES (
55, 1, '', 0, 'CID - 检测结果轮询', '自动查询易盾检测结果并更新到素材表',
'0 * * * * *', 0, 'http', '',
'http://host.docker.internal:3001/yidun/callback/controller/poll-all-results', 'POST',
'{}', '',
120, 0, 0, 1,
0, 0, 0, '',
1, 1, unixepoch('now'), unixepoch('now')
);