Files

181 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 `gcron`6 段 cron 表达式,含秒)
- **前端:** Vue 3 + Element Plus + TypeScriptVite 构建),旧 LayUI 兼容层已移除
- **远程执行:** SSH (`golang.org/x/crypto/ssh`)Telnet/Agent 模式待实现
- **通知:** 邮件 (`net/smtp`) 已实现,钉钉/微信/短信待补充
## Build & Run
```bash
# 一键构建(前端 + 后端)
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
```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 # 配置(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`):
```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+