refactor(internal): 分离runner
This commit is contained in:
@@ -65,6 +65,15 @@ func HandleCreateRule(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查关联账号和 Timer 是否存在(可以没有关联账号)
|
||||||
|
if exist, err := checkRuleConfigAccountAndTimerExist(newRule); err != nil {
|
||||||
|
c.JSON(500, gin.H{"code": 500, "data": "服务器内部错误"})
|
||||||
|
return
|
||||||
|
} else if !exist {
|
||||||
|
c.JSON(400, gin.H{"code": 400, "data": "关联的账户或Timer不存在"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 规则校验
|
// 规则校验
|
||||||
validatorRegistry := ruleConfigChecker.InitValidatorRegistry()
|
validatorRegistry := ruleConfigChecker.InitValidatorRegistry()
|
||||||
if err := validatorRegistry.Validate(newRule.Type, newRule.ConfigJson); err != nil {
|
if err := validatorRegistry.Validate(newRule.Type, newRule.ConfigJson); err != nil {
|
||||||
@@ -82,6 +91,79 @@ func HandleCreateRule(c *gin.Context) {
|
|||||||
c.JSON(200, gin.H{"code": 200, "data": "规则创建成功"})
|
c.JSON(200, gin.H{"code": 200, "data": "规则创建成功"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 编辑规则
|
||||||
|
func HandleEditRule(c *gin.Context) {
|
||||||
|
gormDB, err := db.GetGormDB()
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"code": 500, "data": "服务器内部错误"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userInfo, err := user.GetUserInfoByGinCtx(c)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(401, gin.H{"code": 401, "data": "获取用户信息失败"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ruleID, err := strconv.Atoi(c.Param("ruleID"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"code": 400, "data": "规则 ID 格式错误"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var rule model.Rule
|
||||||
|
result := gormDB.Where("id = ? AND uid = ?", ruleID, userInfo.ID).First(&rule)
|
||||||
|
if result.Error != nil {
|
||||||
|
c.JSON(404, gin.H{"code": 404, "data": "规则不存在"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var updatedRule model.Rule
|
||||||
|
if err := c.BindJSON(&updatedRule); err != nil {
|
||||||
|
c.JSON(400, gin.H{"code": 400, "data": "输入参数错误"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if updatedRule.Type == "" {
|
||||||
|
c.JSON(400, gin.H{"code": 400, "data": "规则类型不能为空"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if updatedRule.Name == "" {
|
||||||
|
c.JSON(400, gin.H{"code": 400, "data": "规则名称不能为空"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查关联账号和 Timer 是否存在(可以没有关联账号)
|
||||||
|
if exist, err := checkRuleConfigAccountAndTimerExist(updatedRule); err != nil {
|
||||||
|
c.JSON(500, gin.H{"code": 500, "data": "服务器内部错误"})
|
||||||
|
return
|
||||||
|
} else if !exist {
|
||||||
|
c.JSON(400, gin.H{"code": 400, "data": "关联的账户或Timer不存在"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 规则校验
|
||||||
|
validatorRegistry := ruleConfigChecker.InitValidatorRegistry()
|
||||||
|
if err := validatorRegistry.Validate(updatedRule.Type, updatedRule.ConfigJson); err != nil {
|
||||||
|
c.JSON(400, gin.H{"code": 400, "data": fmt.Sprintf("规则配置验证失败: %s", err.Error())})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rule.Name = updatedRule.Name
|
||||||
|
rule.Type = updatedRule.Type
|
||||||
|
rule.ConfigJson = updatedRule.ConfigJson
|
||||||
|
rule.AccountID = updatedRule.AccountID
|
||||||
|
rule.TimerID = updatedRule.TimerID
|
||||||
|
|
||||||
|
result = gormDB.Save(&rule)
|
||||||
|
if result.Error != nil {
|
||||||
|
c.JSON(500, gin.H{"code": 500, "data": "更新规则失败"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, gin.H{"code": 200, "data": "规则更新成功"})
|
||||||
|
}
|
||||||
|
|
||||||
// 根据删除规则
|
// 根据删除规则
|
||||||
func HandleDeleteRule(c *gin.Context) {
|
func HandleDeleteRule(c *gin.Context) {
|
||||||
userInfo, err := user.GetUserInfoByGinCtx(c)
|
userInfo, err := user.GetUserInfoByGinCtx(c)
|
||||||
|
|||||||
@@ -15,3 +15,38 @@ func DeleteRuleByID(id uint, uid uint) error {
|
|||||||
result := gormDB.Where("id = ? AND uid = ?", id, uid).Delete(&model.Rule{})
|
result := gormDB.Where("id = ? AND uid = ?", id, uid).Delete(&model.Rule{})
|
||||||
return result.Error
|
return result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查关联账号和 Timer 是否存在(可以没有关联账号)
|
||||||
|
func checkRuleConfigAccountAndTimerExist(rule model.Rule) (exist bool, err error) {
|
||||||
|
gormDB, err := db.GetGormDB()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if rule.TimerID == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var count int64
|
||||||
|
if rule.AccountID != 0 {
|
||||||
|
result := gormDB.Model(&model.Account{}).Where("id = ? AND uid = ?", rule.AccountID, rule.UID).Count(&count)
|
||||||
|
if result.Error != nil {
|
||||||
|
return false, result.Error
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rule.TimerID != 0 {
|
||||||
|
result := gormDB.Model(&model.Timer{}).Where("id = ? AND uid = ?", rule.TimerID, rule.UID).Count(&count)
|
||||||
|
if result.Error != nil {
|
||||||
|
return false, result.Error
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package ruleConfigChecker
|
package bilibili
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ssdomei232/goodBaby/drivers/bilibili"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// BilibiliDynamicRuleValidator B站动态规则验证器
|
// BilibiliDynamicRuleValidator B站动态规则验证器
|
||||||
@@ -15,7 +13,7 @@ func (v *BilibiliDynamicRuleValidator) GetType() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *BilibiliDynamicRuleValidator) Validate(configJSON string) error {
|
func (v *BilibiliDynamicRuleValidator) Validate(configJSON string) error {
|
||||||
var config bilibili.BiliDynamicConfig
|
var config BiliDynamicConfig
|
||||||
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||||
return fmt.Errorf("解析B站动态规则配置失败: %v", err)
|
return fmt.Errorf("解析B站动态规则配置失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package runner
|
package bilibili
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/ssdomei232/goodBaby/drivers/bilibili"
|
|
||||||
"github.com/ssdomei232/goodBaby/model"
|
"github.com/ssdomei232/goodBaby/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ func (e *BilibiliDynamicExecutor) GetType() string {
|
|||||||
func (e *BilibiliDynamicExecutor) Execute(rule *model.Rule) error {
|
func (e *BilibiliDynamicExecutor) Execute(rule *model.Rule) error {
|
||||||
log.Printf("执行B站动态规则: %s (ID: %d)", rule.Name, rule.ID)
|
log.Printf("执行B站动态规则: %s (ID: %d)", rule.Name, rule.ID)
|
||||||
|
|
||||||
bilibili.SendBiliDynamicMsg(rule)
|
SendBiliDynamicMsg(rule)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package ruleConfigChecker
|
package dingtalk
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ssdomei232/goodBaby/drivers/dingtalk"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DingTalkRuleValidator 钉钉规则验证器
|
// DingTalkRuleValidator 钉钉规则验证器
|
||||||
@@ -15,7 +13,7 @@ func (v *DingTalkRuleValidator) GetType() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *DingTalkRuleValidator) Validate(configJSON string) error {
|
func (v *DingTalkRuleValidator) Validate(configJSON string) error {
|
||||||
var config dingtalk.DingTalkConfig
|
var config DingTalkConfig
|
||||||
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||||
return fmt.Errorf("解析钉钉规则配置失败: %v", err)
|
return fmt.Errorf("解析钉钉规则配置失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
package ruleConfigChecker
|
package email
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
|
|
||||||
"github.com/ssdomei232/goodBaby/drivers/email"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// EmailRuleValidator 邮件规则验证器
|
// EmailRuleValidator 邮件规则验证器
|
||||||
@@ -16,7 +14,7 @@ func (v *EmailRuleValidator) GetType() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *EmailRuleValidator) Validate(configJSON string) error {
|
func (v *EmailRuleValidator) Validate(configJSON string) error {
|
||||||
var config email.EmailRule
|
var config EmailRule
|
||||||
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||||
return fmt.Errorf("解析邮件规则配置失败: %v", err)
|
return fmt.Errorf("解析邮件规则配置失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package runner
|
package email
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/ssdomei232/goodBaby/drivers/email"
|
|
||||||
"github.com/ssdomei232/goodBaby/model"
|
"github.com/ssdomei232/goodBaby/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ func (e *EmailExecutor) GetType() string {
|
|||||||
func (e *EmailExecutor) Execute(rule *model.Rule) error {
|
func (e *EmailExecutor) Execute(rule *model.Rule) error {
|
||||||
log.Printf("执行邮件规则: %s (ID: %d)", rule.Name, rule.ID)
|
log.Printf("执行邮件规则: %s (ID: %d)", rule.Name, rule.ID)
|
||||||
|
|
||||||
email.SendMail(rule)
|
SendMail(rule)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GithubMakeRepositoryPublicRuleValidator struct{}
|
||||||
|
|
||||||
|
func (v *GithubMakeRepositoryPublicRuleValidator) GetType() string {
|
||||||
|
return "github_make_repository_public"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *GithubMakeRepositoryPublicRuleValidator) Validate(configJSON string) error {
|
||||||
|
var config GithubReposConfig
|
||||||
|
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||||
|
return fmt.Errorf("解析 GitHub 规则配置失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(config.Repos) == 0 {
|
||||||
|
return fmt.Errorf("GitHub 规则配置错误: 至少需要指定一个仓库")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package runner
|
package github
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/ssdomei232/goodBaby/drivers/github"
|
|
||||||
"github.com/ssdomei232/goodBaby/model"
|
"github.com/ssdomei232/goodBaby/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ func (e *GithubMakeRepoPublicExecutor) GetType() string {
|
|||||||
func (e *GithubMakeRepoPublicExecutor) Execute(rule *model.Rule) error {
|
func (e *GithubMakeRepoPublicExecutor) Execute(rule *model.Rule) error {
|
||||||
log.Printf("执行GitHub仓库公开规则: %s (ID: %d)", rule.Name, rule.ID)
|
log.Printf("执行GitHub仓库公开规则: %s (ID: %d)", rule.Name, rule.ID)
|
||||||
|
|
||||||
github.MakeRepositoryPublic(rule)
|
MakeRepositoryPublic(rule)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package ruleConfigChecker
|
package onebot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ssdomei232/goodBaby/drivers/onebot"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// OneBotRuleValidator OneBot规则验证器
|
// OneBotRuleValidator OneBot规则验证器
|
||||||
@@ -15,7 +13,7 @@ func (v *OneBotRuleValidator) GetType() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (v *OneBotRuleValidator) Validate(configJSON string) error {
|
func (v *OneBotRuleValidator) Validate(configJSON string) error {
|
||||||
var config onebot.OneBotConfig
|
var config OneBotConfig
|
||||||
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||||
return fmt.Errorf("解析OneBot规则配置失败: %v", err)
|
return fmt.Errorf("解析OneBot规则配置失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package runner
|
package onebot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/ssdomei232/goodBaby/drivers/onebot"
|
|
||||||
"github.com/ssdomei232/goodBaby/model"
|
"github.com/ssdomei232/goodBaby/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ func (e *OneBotExecutor) GetType() string {
|
|||||||
func (e *OneBotExecutor) Execute(rule *model.Rule) error {
|
func (e *OneBotExecutor) Execute(rule *model.Rule) error {
|
||||||
log.Printf("执行OneBot规则: %s (ID: %d)", rule.Name, rule.ID)
|
log.Printf("执行OneBot规则: %s (ID: %d)", rule.Name, rule.ID)
|
||||||
|
|
||||||
onebot.SendOneBotMsg(rule)
|
SendOneBotMsg(rule)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,10 @@ package runner
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ssdomei232/goodBaby/drivers/bilibili"
|
||||||
|
"github.com/ssdomei232/goodBaby/drivers/email"
|
||||||
|
"github.com/ssdomei232/goodBaby/drivers/github"
|
||||||
|
"github.com/ssdomei232/goodBaby/drivers/onebot"
|
||||||
"github.com/ssdomei232/goodBaby/model"
|
"github.com/ssdomei232/goodBaby/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -57,10 +61,10 @@ func InitExecutorRegistry() *ExecutorRegistry {
|
|||||||
registry := NewExecutorRegistry()
|
registry := NewExecutorRegistry()
|
||||||
|
|
||||||
// 注册所有规则执行器
|
// 注册所有规则执行器
|
||||||
registry.Register(&BilibiliDynamicExecutor{})
|
registry.Register(&bilibili.BilibiliDynamicExecutor{})
|
||||||
registry.Register(&EmailExecutor{})
|
registry.Register(&email.EmailExecutor{})
|
||||||
registry.Register(&GithubMakeRepoPublicExecutor{})
|
registry.Register(&github.GithubMakeRepoPublicExecutor{})
|
||||||
registry.Register(&OneBotExecutor{})
|
registry.Register(&onebot.OneBotExecutor{})
|
||||||
// 未来添加新规则类型时,在这里注册即可
|
// 未来添加新规则类型时,在这里注册即可
|
||||||
|
|
||||||
globalExecutorRegistry = registry
|
globalExecutorRegistry = registry
|
||||||
|
|||||||
-13
@@ -59,16 +59,3 @@ func (vr *ValidatorRegistry) GetSupportedTypes() []string {
|
|||||||
}
|
}
|
||||||
return types
|
return types
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitValidatorRegistry 初始化验证器注册表并注册所有验证器
|
|
||||||
func InitValidatorRegistry() *ValidatorRegistry {
|
|
||||||
registry := NewValidatorRegistry()
|
|
||||||
|
|
||||||
// 注册所有规则验证器
|
|
||||||
registry.Register(&BilibiliDynamicRuleValidator{})
|
|
||||||
registry.Register(&EmailRuleValidator{})
|
|
||||||
registry.Register(&OneBotRuleValidator{})
|
|
||||||
registry.Register(&DingTalkRuleValidator{})
|
|
||||||
|
|
||||||
return registry
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package ruleConfigChecker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ssdomei232/goodBaby/drivers/bilibili"
|
||||||
|
"github.com/ssdomei232/goodBaby/drivers/dingtalk"
|
||||||
|
"github.com/ssdomei232/goodBaby/drivers/email"
|
||||||
|
"github.com/ssdomei232/goodBaby/drivers/github"
|
||||||
|
"github.com/ssdomei232/goodBaby/drivers/onebot"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitValidatorRegistry 初始化验证器注册表并注册所有验证器
|
||||||
|
func InitValidatorRegistry() *ValidatorRegistry {
|
||||||
|
registry := NewValidatorRegistry()
|
||||||
|
|
||||||
|
// 注册所有规则验证器
|
||||||
|
registry.Register(&bilibili.BilibiliDynamicRuleValidator{})
|
||||||
|
registry.Register(&email.EmailRuleValidator{})
|
||||||
|
registry.Register(&onebot.OneBotRuleValidator{})
|
||||||
|
registry.Register(&dingtalk.DingTalkRuleValidator{})
|
||||||
|
registry.Register(&github.GithubMakeRepositoryPublicRuleValidator{})
|
||||||
|
|
||||||
|
return registry
|
||||||
|
}
|
||||||
@@ -36,14 +36,26 @@ func main() {
|
|||||||
authorized := v1.Group("/")
|
authorized := v1.Group("/")
|
||||||
authorized.Use(user.AuthMiddleware())
|
authorized.Use(user.AuthMiddleware())
|
||||||
{
|
{
|
||||||
authorized.GET("/user/info", user.HandleGetUserInfo)
|
users := authorized.Group("/user")
|
||||||
authorized.GET("/rules", rule.HandleGetAllRules)
|
{
|
||||||
authorized.POST("/rules", rule.HandleCreateRule)
|
users.GET("/info", user.HandleGetUserInfo)
|
||||||
authorized.DELETE("/rules/:ruleID", rule.HandleDeleteRule)
|
}
|
||||||
authorized.GET("/accounts", account.HandleGetAllAccounts)
|
|
||||||
authorized.POST("/accounts", account.HandleAddAccount)
|
rules := authorized.Group("/rules")
|
||||||
authorized.GET("/accounts/:accountID/check", account.HandleCheckDeleteAccount)
|
{
|
||||||
authorized.DELETE("/accounts/:accountID", account.HandleDeleteAccount)
|
rules.GET("/", rule.HandleGetAllRules)
|
||||||
|
rules.POST("/", rule.HandleCreateRule)
|
||||||
|
rules.PUT("/:ruleID", rule.HandleEditRule)
|
||||||
|
rules.DELETE("/:ruleID", rule.HandleDeleteRule)
|
||||||
|
}
|
||||||
|
|
||||||
|
accounts := authorized.Group("/accounts")
|
||||||
|
{
|
||||||
|
accounts.GET("/", account.HandleGetAllAccounts)
|
||||||
|
accounts.POST("/", account.HandleAddAccount)
|
||||||
|
accounts.GET("/:accountID/check", account.HandleCheckDeleteAccount)
|
||||||
|
accounts.DELETE("/:accountID", account.HandleDeleteAccount)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Run(":8088")
|
r.Run(":8088")
|
||||||
|
|||||||
Reference in New Issue
Block a user