Files

6.8 KiB
Raw Permalink Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project

PPGo_Job — 定时任务管理系统,已从 Beego v1 重构为 GoFrame v2。支持本机 Shell 执行、HTTP 请求任务和 SSH 远程执行。

  • 框架: GoFrame v2
  • 数据库: SQLite (modernc.org/sqlite,纯 Go,无 CGO)
  • 定时器: GoFrame gcron6 段 cron 表达式,含秒)
  • 前端: Vue 3 + Element Plus + TypeScriptVite 构建),旧 LayUI 兼容层已移除
  • 远程执行: SSH (golang.org/x/crypto/ssh)Telnet/Agent 模式待实现
  • 通知: 邮件 (net/smtp) 已实现,钉钉/微信/短信待补充

Build & Run

# 一键构建(前端 + 后端)
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 -> 重定向到 /app/Vue 前端)
# 默认账号 admin / 123456

Test

# 全部测试
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              # 配置(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。单例模式 var Xxx = new(xxxDao)
  • middleware: 认证、权限检查。

Route Structure

路由定义在 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):

// 等值查询
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

含义
-1 已删除
0 已暂停
1 运行中
2 待审核
3 审核失败

Known Limits

  • Telnet/Agent 远程执行 — SSH 已实现,其余待补充(参考 _old/jobs/job.go
  • 通知渠道 — 邮件已实现,钉钉/微信/短信待补充(参考 _old/notify/
  • Agent API — 路由已预留(/server/api_*, /task/api_*),Agent 二进制待实现
  • Go 版本 — 要求 go 1.26+