初始提交: ScriptForge 脚本快速转运行链接服务
Some checks failed
Release / build-and-release (push) Failing after 1m31s
Some checks failed
Release / build-and-release (push) Failing after 1m31s
- Go 后端 (Gin + GORM + SQLite) 提供 API 和纯文本脚本服务 - Vite + React + TypeScript + Tailwind 前端 - 单二进制部署 (Go embed 前端静态文件) - Gitea Actions CI/CD: 打标签自动构建多平台 Release - 支持 bash/zsh/sh/fish/python3/node/ruby/php 8种运行环境 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
103
backend/internal/handler/script.go
Normal file
103
backend/internal/handler/script.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"gitea.kmux.cn/zhilv/scriptforge/internal/service"
|
||||
)
|
||||
|
||||
type createRequest struct {
|
||||
Content string `json:"content" binding:"required,max=16384"`
|
||||
Runtime string `json:"runtime" binding:"required"`
|
||||
ExpiresIn string `json:"expires_in" binding:"required,oneof=1h 24h 7d 30d"`
|
||||
}
|
||||
|
||||
func CreateScript(svc *service.ScriptService) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var req createRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
scheme := "https"
|
||||
if strings.HasPrefix(c.Request.Host, "localhost") || strings.HasPrefix(c.Request.Host, "127.0.0.1") {
|
||||
scheme = "http"
|
||||
}
|
||||
|
||||
result, err := svc.Create(service.CreateInput{
|
||||
Content: req.Content,
|
||||
Runtime: req.Runtime,
|
||||
ExpiresIn: req.ExpiresIn,
|
||||
}, scheme, c.Request.Host)
|
||||
|
||||
if errors.Is(err, service.ErrInvalidRuntime) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid runtime, supported: bash, zsh, sh, fish, python3, node, ruby, php"})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{
|
||||
"id": result.Script.ID,
|
||||
"admin_token": result.AdminToken,
|
||||
"url": result.RawURL,
|
||||
"command": result.Command,
|
||||
"runtime": result.Script.Runtime,
|
||||
"expires_at": result.Script.ExpiresAt,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func GetScript(svc *service.ScriptService) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
script, err := svc.GetByID(id)
|
||||
if errors.Is(err, service.ErrNotFound) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "script not found or expired"})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"id": script.ID,
|
||||
"runtime": script.Runtime,
|
||||
"content": script.Content,
|
||||
"content_length": len(script.Content),
|
||||
"created_at": script.CreatedAt,
|
||||
"expires_at": script.ExpiresAt,
|
||||
"expired": false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteScript(svc *service.ScriptService) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
token := c.Query("token")
|
||||
if token == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "token query parameter is required"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := svc.Delete(id, token); errors.Is(err, service.ErrNotFound) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "script not found or invalid token"})
|
||||
return
|
||||
} else if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal error"})
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user