feat(drivers): 新增雨云工单

This commit is contained in:
mei
2026-08-13 09:13:10 +08:00
parent 8163d0d9d4
commit d428a7db2e
12 changed files with 227 additions and 3 deletions
+67
View File
@@ -0,0 +1,67 @@
package rainyun
import (
"encoding/json"
"fmt"
"github.com/ssdomei232/goodBaby/internal/meta"
rain "github.com/ssdomei232/rainyun-go-sdk/v2/rainyun/common"
"github.com/ssdomei232/rainyun-go-sdk/v2/rainyun/user"
)
// RainyunAccountConfigValidator Rainyun账号配置验证器
type RainyunAccountConfigValidator struct{}
func (v *RainyunAccountConfigValidator) GetType() string {
return AccountType
}
func (v *RainyunAccountConfigValidator) Validate(config string) error {
// 解析配置
cfg, err := parseAccount(config)
if err != nil {
return err
}
if cfg.APIKey == "" {
return fmt.Errorf("雨云账号配置中APIKey不能为空")
}
return nil
}
func parseAccount(config string) (*RainyunAccount, error) {
var cfg RainyunAccount
if err := json.Unmarshal([]byte(config), &cfg); err != nil {
return nil, fmt.Errorf("解析雨云账号配置失败: %v", err)
}
return &cfg, nil
}
func (v *RainyunAccountConfigValidator) Test(config string) error {
cfg, err := parseAccount(config)
if err != nil {
return err
}
client := rain.NewClient(cfg.APIKey)
userClient := user.Client{Client: client}
_, err = userClient.GetUserInfo()
if err != nil {
return fmt.Errorf("测试雨云账号配置失败: %v", err)
}
return nil
}
func (v *RainyunAccountConfigValidator) Meta() meta.AccountMeta {
return meta.AccountMeta{
Type: AccountType,
Label: "雨云",
Description: "对接雨云,方便各位代理/运维删库跑路",
Fields: []meta.Field{
{Key: "api_key", Label: "API Key", Type: meta.FieldPassword, Required: true, Secret: true, Placeholder: "xxxxxxxxx"},
},
}
}
+17
View File
@@ -0,0 +1,17 @@
package rainyun
const (
// AccountType Rainyun 账号类型标识
AccountType = "rainyun"
// RuleType 发送 Rainyun 消息的规则类型标识
RuleType = "rainyun-workorder"
)
type RainyunWorkOrderRule struct {
Title string `json:"title"`
Msg string `json:"msg"`
}
type RainyunAccount struct {
APIKey string `json:"api_key"`
}
+38
View File
@@ -0,0 +1,38 @@
package rainyun
import (
"context"
"github.com/ssdomei232/goodBaby/model"
rain "github.com/ssdomei232/rainyun-go-sdk/v2/rainyun/common"
"github.com/ssdomei232/rainyun-go-sdk/v2/rainyun/workorder"
)
func sendRainyunWorkorderMsg(ctx context.Context, rule *model.Rule) error {
rainyunConfig, err := getRainyunConfigFromRule(rule)
if err != nil {
return err
}
rainyunAccount, err := getRainyunAccountFromRule(rule)
if err != nil {
return err
}
client := rain.NewClient(rainyunAccount.APIKey)
workorderClient := workorder.Client{Client: client}
_, err = workorderClient.CreateWorkOrder(&workorder.CreateWorkerorderRequest{
Content: rainyunConfig.Msg,
IsAuthed: false,
IsUrgent: 1,
Title: rainyunConfig.Title,
Type: "reward",
})
if err != nil {
return err
}
return nil
}
+45
View File
@@ -0,0 +1,45 @@
package rainyun
import (
"encoding/json"
"fmt"
"github.com/ssdomei232/goodBaby/internal/meta"
)
// Rainyun规则验证器
type RainyunWorkorderRuleValidator struct{}
func (v *RainyunWorkorderRuleValidator) GetType() string {
return RuleType
}
func (v *RainyunWorkorderRuleValidator) Validate(configJSON string) error {
var config RainyunWorkOrderRule
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
return fmt.Errorf("解析雨云规则配置失败: %v", err)
}
if config.Title == "" {
return fmt.Errorf("雨云规则配置中 title 不能为空")
}
if config.Msg == "" {
return fmt.Errorf("雨云规则配置中 msg 不能为空")
}
return nil
}
func (v *RainyunWorkorderRuleValidator) Meta() meta.RuleMeta {
return meta.RuleMeta{
Type: RuleType,
Label: "发送雨云工单",
Description: "触发时通过雨云向指定的工单系统发送工单。",
AccountType: AccountType,
Fields: []meta.Field{
{Key: "title", Label: "工单标题", Type: meta.FieldTextarea, Required: true},
{Key: "msg", Label: "工单内容", Type: meta.FieldTextarea, Required: true},
},
}
}
+21
View File
@@ -0,0 +1,21 @@
package rainyun
import (
"context"
"log"
"github.com/ssdomei232/goodBaby/model"
)
// RainyunExecutor 雨云执行器
type RainyunWorkorderExecutor struct{}
func (e *RainyunWorkorderExecutor) GetType() string {
return RuleType
}
func (e *RainyunWorkorderExecutor) Execute(ctx context.Context, rule *model.Rule) error {
log.Printf("执行雨云工单规则: %s", rule.Name)
return sendRainyunWorkorderMsg(ctx, rule)
}
+27
View File
@@ -0,0 +1,27 @@
package rainyun
import (
"encoding/json"
"fmt"
"github.com/ssdomei232/goodBaby/handler/db"
"github.com/ssdomei232/goodBaby/model"
)
// 从 Rule 中获取 RainyunConfig
func getRainyunConfigFromRule(rule *model.Rule) (*RainyunWorkOrderRule, error) {
var rainyunConfig RainyunWorkOrderRule
if err := json.Unmarshal([]byte(rule.ConfigJson), &rainyunConfig); err != nil {
return nil, fmt.Errorf("解析Rainyun规则配置失败: %w", err)
}
return &rainyunConfig, nil
}
// 从 Rule 中获取 RainyunAccount
func getRainyunAccountFromRule(rule *model.Rule) (*RainyunAccount, error) {
var rainyunAccount RainyunAccount
if err := db.LoadAccountConfig(rule.AccountID, &rainyunAccount); err != nil {
return nil, err
}
return &rainyunAccount, nil
}