refactor(internal): 分离runner
This commit is contained in:
@@ -65,6 +65,15 @@ func HandleCreateRule(c *gin.Context) {
|
||||
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()
|
||||
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": "规则创建成功"})
|
||||
}
|
||||
|
||||
// 编辑规则
|
||||
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) {
|
||||
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{})
|
||||
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 (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/drivers/bilibili"
|
||||
)
|
||||
|
||||
// BilibiliDynamicRuleValidator B站动态规则验证器
|
||||
@@ -15,7 +13,7 @@ func (v *BilibiliDynamicRuleValidator) GetType() string {
|
||||
}
|
||||
|
||||
func (v *BilibiliDynamicRuleValidator) Validate(configJSON string) error {
|
||||
var config bilibili.BiliDynamicConfig
|
||||
var config BiliDynamicConfig
|
||||
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||
return fmt.Errorf("解析B站动态规则配置失败: %v", err)
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package runner
|
||||
package bilibili
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/drivers/bilibili"
|
||||
"github.com/ssdomei232/goodBaby/model"
|
||||
)
|
||||
|
||||
@@ -17,7 +16,7 @@ func (e *BilibiliDynamicExecutor) GetType() string {
|
||||
func (e *BilibiliDynamicExecutor) Execute(rule *model.Rule) error {
|
||||
log.Printf("执行B站动态规则: %s (ID: %d)", rule.Name, rule.ID)
|
||||
|
||||
bilibili.SendBiliDynamicMsg(rule)
|
||||
SendBiliDynamicMsg(rule)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package ruleConfigChecker
|
||||
package dingtalk
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/drivers/dingtalk"
|
||||
)
|
||||
|
||||
// DingTalkRuleValidator 钉钉规则验证器
|
||||
@@ -15,7 +13,7 @@ func (v *DingTalkRuleValidator) GetType() string {
|
||||
}
|
||||
|
||||
func (v *DingTalkRuleValidator) Validate(configJSON string) error {
|
||||
var config dingtalk.DingTalkConfig
|
||||
var config DingTalkConfig
|
||||
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||
return fmt.Errorf("解析钉钉规则配置失败: %v", err)
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
package ruleConfigChecker
|
||||
package email
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/mail"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/drivers/email"
|
||||
)
|
||||
|
||||
// EmailRuleValidator 邮件规则验证器
|
||||
@@ -16,7 +14,7 @@ func (v *EmailRuleValidator) GetType() string {
|
||||
}
|
||||
|
||||
func (v *EmailRuleValidator) Validate(configJSON string) error {
|
||||
var config email.EmailRule
|
||||
var config EmailRule
|
||||
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||
return fmt.Errorf("解析邮件规则配置失败: %v", err)
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package runner
|
||||
package email
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/drivers/email"
|
||||
"github.com/ssdomei232/goodBaby/model"
|
||||
)
|
||||
|
||||
@@ -17,7 +16,7 @@ func (e *EmailExecutor) GetType() string {
|
||||
func (e *EmailExecutor) Execute(rule *model.Rule) error {
|
||||
log.Printf("执行邮件规则: %s (ID: %d)", rule.Name, rule.ID)
|
||||
|
||||
email.SendMail(rule)
|
||||
SendMail(rule)
|
||||
|
||||
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 (
|
||||
"log"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/drivers/github"
|
||||
"github.com/ssdomei232/goodBaby/model"
|
||||
)
|
||||
|
||||
@@ -17,7 +16,7 @@ func (e *GithubMakeRepoPublicExecutor) GetType() string {
|
||||
func (e *GithubMakeRepoPublicExecutor) Execute(rule *model.Rule) error {
|
||||
log.Printf("执行GitHub仓库公开规则: %s (ID: %d)", rule.Name, rule.ID)
|
||||
|
||||
github.MakeRepositoryPublic(rule)
|
||||
MakeRepositoryPublic(rule)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package ruleConfigChecker
|
||||
package onebot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/drivers/onebot"
|
||||
)
|
||||
|
||||
// OneBotRuleValidator OneBot规则验证器
|
||||
@@ -15,7 +13,7 @@ func (v *OneBotRuleValidator) GetType() string {
|
||||
}
|
||||
|
||||
func (v *OneBotRuleValidator) Validate(configJSON string) error {
|
||||
var config onebot.OneBotConfig
|
||||
var config OneBotConfig
|
||||
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||
return fmt.Errorf("解析OneBot规则配置失败: %v", err)
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package runner
|
||||
package onebot
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/ssdomei232/goodBaby/drivers/onebot"
|
||||
"github.com/ssdomei232/goodBaby/model"
|
||||
)
|
||||
|
||||
@@ -17,7 +16,7 @@ func (e *OneBotExecutor) GetType() string {
|
||||
func (e *OneBotExecutor) Execute(rule *model.Rule) error {
|
||||
log.Printf("执行OneBot规则: %s (ID: %d)", rule.Name, rule.ID)
|
||||
|
||||
onebot.SendOneBotMsg(rule)
|
||||
SendOneBotMsg(rule)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -3,6 +3,10 @@ package runner
|
||||
import (
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -57,10 +61,10 @@ func InitExecutorRegistry() *ExecutorRegistry {
|
||||
registry := NewExecutorRegistry()
|
||||
|
||||
// 注册所有规则执行器
|
||||
registry.Register(&BilibiliDynamicExecutor{})
|
||||
registry.Register(&EmailExecutor{})
|
||||
registry.Register(&GithubMakeRepoPublicExecutor{})
|
||||
registry.Register(&OneBotExecutor{})
|
||||
registry.Register(&bilibili.BilibiliDynamicExecutor{})
|
||||
registry.Register(&email.EmailExecutor{})
|
||||
registry.Register(&github.GithubMakeRepoPublicExecutor{})
|
||||
registry.Register(&onebot.OneBotExecutor{})
|
||||
// 未来添加新规则类型时,在这里注册即可
|
||||
|
||||
globalExecutorRegistry = registry
|
||||
|
||||
-13
@@ -59,16 +59,3 @@ func (vr *ValidatorRegistry) GetSupportedTypes() []string {
|
||||
}
|
||||
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.Use(user.AuthMiddleware())
|
||||
{
|
||||
authorized.GET("/user/info", user.HandleGetUserInfo)
|
||||
authorized.GET("/rules", rule.HandleGetAllRules)
|
||||
authorized.POST("/rules", rule.HandleCreateRule)
|
||||
authorized.DELETE("/rules/:ruleID", rule.HandleDeleteRule)
|
||||
authorized.GET("/accounts", account.HandleGetAllAccounts)
|
||||
authorized.POST("/accounts", account.HandleAddAccount)
|
||||
authorized.GET("/accounts/:accountID/check", account.HandleCheckDeleteAccount)
|
||||
authorized.DELETE("/accounts/:accountID", account.HandleDeleteAccount)
|
||||
users := authorized.Group("/user")
|
||||
{
|
||||
users.GET("/info", user.HandleGetUserInfo)
|
||||
}
|
||||
|
||||
rules := authorized.Group("/rules")
|
||||
{
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user