feat: 添加定时系统
- 实现定时任务
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package ckwk
|
||||
|
||||
import (
|
||||
"ckwk/internal/conf"
|
||||
"ckwk/pkg/common"
|
||||
"ckwk/pkg/log"
|
||||
"ckwk/pkg/request"
|
||||
@@ -97,7 +98,7 @@ func (wk *WK) Code() (string, error) {
|
||||
"png_fix": "false",
|
||||
}).
|
||||
SetResult(&result).
|
||||
Post("http://localhost:8000/ocr")
|
||||
Post(fmt.Sprintf("%s/ocr", conf.DdddOCR))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("获取验证码验证结果失败: %w", err)
|
||||
}
|
||||
|
||||
@@ -115,3 +115,44 @@ func (m *SessionManager) KeepAlive(ctx context.Context, id string, wk *WK) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *SessionManager) ClearAll() {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
for sessionID, item := range m.sessions {
|
||||
// 停止 KeepAlive
|
||||
if item.cancel != nil {
|
||||
item.cancel()
|
||||
}
|
||||
|
||||
userKey := item.Instance.Host + ":" + item.Instance.Username
|
||||
delete(m.userToSession, userKey)
|
||||
delete(m.sessions, sessionID)
|
||||
|
||||
log.Info("清理 Session", zap.String("id", sessionID))
|
||||
}
|
||||
|
||||
log.Info("所有 Session 已清空")
|
||||
}
|
||||
|
||||
func (m *SessionManager) ClearExpired(d time.Duration) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
now := time.Now()
|
||||
|
||||
for sessionID, item := range m.sessions {
|
||||
if now.Sub(item.LastValue) > d {
|
||||
if item.cancel != nil {
|
||||
item.cancel()
|
||||
}
|
||||
|
||||
userKey := item.Instance.Host + ":" + item.Instance.Username
|
||||
delete(m.userToSession, userKey)
|
||||
delete(m.sessions, sessionID)
|
||||
|
||||
log.Info("清理过期 Session", zap.String("id", sessionID))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
5
internal/conf/const.go
Normal file
5
internal/conf/const.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package conf
|
||||
|
||||
const (
|
||||
DdddOCR = "https://ocr.kmux.cn"
|
||||
)
|
||||
@@ -28,11 +28,16 @@ func (h *WKHandler) Login(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
log.Debug("请求数据", zap.Any("req", req))
|
||||
var cookies = []*http.Cookie{
|
||||
{
|
||||
Name: "token",
|
||||
Value: req.Token,
|
||||
Path: "/"},
|
||||
var cookies []*http.Cookie
|
||||
if req.Token != "" {
|
||||
cookies = []*http.Cookie{
|
||||
{
|
||||
Name: "token",
|
||||
Value: req.Token,
|
||||
Path: "/"},
|
||||
}
|
||||
} else {
|
||||
cookies = []*http.Cookie{}
|
||||
}
|
||||
wk := ckwk.NewWK(req.Username, req.Password, req.Host, cookies)
|
||||
if wk == nil {
|
||||
@@ -171,3 +176,16 @@ func (h *WKHandler) AllRecord(ctx *gin.Context) {
|
||||
"page_info": pageInfo,
|
||||
}))
|
||||
}
|
||||
|
||||
func (h *WKHandler) Host(ctx *gin.Context) {
|
||||
ctx.JSON(200, dto.Success(map[string]any{
|
||||
"list": []map[string]any{
|
||||
{"host": "cqcst.leykeji.com", "name": "劳动课程测评考试平台"},
|
||||
{"host": "cqcst.zjxkeji.com", "name": "公益课程平台"},
|
||||
{"host": "cqcst.suwankj.com", "name": "在线课程测评考试平台"},
|
||||
{"host": "cqcst.yuruixxkj.com", "name": "在线测评考试平台"},
|
||||
// {"host": "cqcst.yuncanjykeji.com", "name": "劳动课程测评考试平台"},
|
||||
// {"host": "cqcst.yuruixxkj.com", "name": "公益课程平台"},
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -3,22 +3,33 @@ package router
|
||||
import (
|
||||
"ckwk/internal/handler"
|
||||
"ckwk/internal/middleware"
|
||||
"ckwk/internal/schedule"
|
||||
"time"
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func SetupRouter() *gin.Engine {
|
||||
r := gin.Default()
|
||||
r.Use(cors.New(cors.Config{
|
||||
AllowOrigins: []string{"*://*", "http://localhost:5173"},
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "PATCH"},
|
||||
AllowHeaders: []string{"*", "X-Session-Id"},
|
||||
ExposeHeaders: []string{"Content-Length"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 12 * time.Hour,
|
||||
}))
|
||||
wkHandler := handler.NewWKHandler()
|
||||
sessionMiddleware := middleware.SessionMiddleware(wkHandler.Session)
|
||||
schedule.StartCron(wkHandler.Session)
|
||||
|
||||
api := r.Group("/api")
|
||||
{
|
||||
api.POST("/login", wkHandler.Login)
|
||||
v1 := api.Group("/v1", sessionMiddleware)
|
||||
v1 := api.Group("/v1")
|
||||
{
|
||||
v1.POST("/online", wkHandler.Online)
|
||||
v1.POST("/logout", wkHandler.Logout)
|
||||
v1.GET("/host", wkHandler.Host)
|
||||
}
|
||||
|
||||
v2 := api.Group("/v2", sessionMiddleware)
|
||||
|
||||
32
internal/schedule/schedule.go
Normal file
32
internal/schedule/schedule.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package schedule
|
||||
|
||||
import (
|
||||
"ckwk/internal/ckwk"
|
||||
"ckwk/pkg/log"
|
||||
"time"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func StartCron(m *ckwk.SessionManager) {
|
||||
loc, _ := time.LoadLocation("Asia/Singapore")
|
||||
|
||||
c := cron.New(
|
||||
cron.WithLocation(loc),
|
||||
)
|
||||
|
||||
// 每天 6 点执行
|
||||
_, err := c.AddFunc("0 2 * * *", func() {
|
||||
log.Info("开始定时清理 Session")
|
||||
m.ClearAll()
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Error("cron 添加任务失败", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
c.Start()
|
||||
}
|
||||
Reference in New Issue
Block a user