package service import ( "errors" "time" "gorm.io/gorm" "gitea.kmux.cn/zhilv/scriptforge/internal/config" "gitea.kmux.cn/zhilv/scriptforge/internal/idgen" "gitea.kmux.cn/zhilv/scriptforge/internal/model" ) var ( ErrInvalidRuntime = errors.New("invalid runtime") ErrNotFound = errors.New("script not found or expired") ) type ScriptService struct { db *gorm.DB } func NewScriptService(db *gorm.DB) *ScriptService { return &ScriptService{db: db} } type CreateInput struct { Content string Runtime string ExpiresIn string } type CreateResult struct { Script model.Script AdminToken string Command string RawURL string } func (s *ScriptService) Create(input CreateInput, scheme, host string) (*CreateResult, error) { if !config.IsValidRuntime(input.Runtime) { return nil, ErrInvalidRuntime } var d time.Duration switch input.ExpiresIn { case "1h": d = 1 * time.Hour case "24h": d = 24 * time.Hour case "7d": d = 7 * 24 * time.Hour case "30d": d = 30 * 24 * time.Hour default: d = 24 * time.Hour } id, err := idgen.GenerateID(8) if err != nil { return nil, err } adminToken, err := idgen.GenerateToken() if err != nil { return nil, err } script := model.Script{ ID: id, Content: input.Content, Runtime: input.Runtime, AdminToken: adminToken, ExpiresAt: time.Now().Add(d), CreatedAt: time.Now(), } if err := s.db.Create(&script).Error; err != nil { return nil, err } rawURL := scheme + "://" + host + "/raw/" + id command := "curl " + rawURL + " | " + input.Runtime return &CreateResult{ Script: script, AdminToken: adminToken, Command: command, RawURL: rawURL, }, nil } func (s *ScriptService) GetByID(id string) (*model.Script, error) { var script model.Script err := s.db.Where("id = ? AND expires_at > ?", id, time.Now()).First(&script).Error if errors.Is(err, gorm.ErrRecordNotFound) { return nil, ErrNotFound } return &script, err } func (s *ScriptService) Delete(id, token string) error { result := s.db.Where("id = ? AND admin_token = ?", id, token).Delete(&model.Script{}) if result.RowsAffected == 0 { return ErrNotFound } return result.Error } func (s *ScriptService) CleanupExpired() (int64, error) { result := s.db.Where("expires_at <= ?", time.Now()).Delete(&model.Script{}) return result.RowsAffected, result.Error }