Files
aiaa-notification-server/internal/store/source.go
T
ryan 39f3774940 feat: 配置列表分页与钉钉机器人分钟级排队限流
统一 sources/templates/channels/rules 列表为分页响应,避免配置增多时全量返回;按钉钉 access_token 限制每分钟发送并在超限时等待下一分钟,降低触发官方封禁风险。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 00:34:26 +08:00

88 lines
2.7 KiB
Go

package store
import (
"context"
"crypto/rand"
"encoding/hex"
"fmt"
"aiaa-notification-service/internal/model"
)
func generateAPIKey() string {
b := make([]byte, 32)
rand.Read(b)
return "sk-" + hex.EncodeToString(b)
}
func (s *Store) CreateSource(ctx context.Context, src *model.Source) error {
src.APIKey = generateAPIKey()
query := `INSERT INTO notification_source (name, api_key, parse_mode, parse_pattern, status) VALUES (?, ?, ?, ?, ?)`
result, err := s.DB.ExecContext(ctx, query, src.Name, src.APIKey, src.ParseMode, src.ParsePattern, src.Status)
if err != nil {
return fmt.Errorf("create source: %w", err)
}
id, _ := result.LastInsertId()
src.ID = int(id)
return nil
}
func (s *Store) GetSource(ctx context.Context, id int) (*model.Source, error) {
var src model.Source
err := s.DB.GetContext(ctx, &src, `SELECT * FROM notification_source WHERE id = ?`, id)
if err != nil {
return nil, fmt.Errorf("get source %d: %w", id, err)
}
return &src, nil
}
func (s *Store) GetSourceByAPIKey(ctx context.Context, apiKey string) (*model.Source, error) {
var src model.Source
err := s.DB.GetContext(ctx, &src, `SELECT * FROM notification_source WHERE api_key = ? AND status = 1`, apiKey)
if err != nil {
return nil, fmt.Errorf("get source by api_key: %w", err)
}
return &src, nil
}
func (s *Store) GetSourceByName(ctx context.Context, name string) (*model.Source, error) {
var src model.Source
err := s.DB.GetContext(ctx, &src, `SELECT * FROM notification_source WHERE name = ?`, name)
if err != nil {
return nil, fmt.Errorf("get source by name %s: %w", name, err)
}
return &src, nil
}
func (s *Store) ListSources(ctx context.Context, page PageFilter) ([]model.Source, int, error) {
var count int
if err := s.DB.GetContext(ctx, &count, `SELECT COUNT(*) FROM notification_source`); err != nil {
return nil, 0, fmt.Errorf("count sources: %w", err)
}
page.Normalize()
sources := make([]model.Source, 0)
err := s.DB.SelectContext(ctx, &sources, `SELECT * FROM notification_source ORDER BY id LIMIT ? OFFSET ?`, page.PageSize, page.Offset())
if err != nil {
return nil, 0, fmt.Errorf("list sources: %w", err)
}
return sources, count, nil
}
func (s *Store) UpdateSource(ctx context.Context, id int, src *model.Source) error {
query := `UPDATE notification_source SET name=?, parse_mode=?, parse_pattern=?, status=? WHERE id=?`
_, err := s.DB.ExecContext(ctx, query, src.Name, src.ParseMode, src.ParsePattern, src.Status, id)
if err != nil {
return fmt.Errorf("update source %d: %w", id, err)
}
return nil
}
func (s *Store) DeleteSource(ctx context.Context, id int) error {
_, err := s.DB.ExecContext(ctx, `DELETE FROM notification_source WHERE id = ?`, id)
if err != nil {
return fmt.Errorf("delete source %d: %w", id, err)
}
return nil
}