Files
video-factory/main.go
T
2026-07-24 13:05:57 +08:00

108 lines
2.7 KiB
Go

package main
import (
"context"
"errors"
"net/http"
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"
"time"
commonHttp "video-factory/common"
"video-factory/shortdrama/controller"
"video-factory/shortdrama/service"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/util/gvalid"
_ "github.com/gogf/gf/contrib/drivers/sqlite/v2"
)
func init() {
gvalid.RegisterRule("password-complex", func(ctx context.Context, input gvalid.RuleFuncInput) error {
pwd := input.Value.String()
var hasUpper, hasLower, hasDigit, hasSpecial bool
for _, c := range pwd {
switch {
case c >= 'A' && c <= 'Z':
hasUpper = true
case c >= 'a' && c <= 'z':
hasLower = true
case c >= '0' && c <= '9':
hasDigit = true
default:
hasSpecial = true
}
}
if !hasUpper {
return errors.New("密码必须包含大写字母")
}
if !hasLower {
return errors.New("密码必须包含小写字母")
}
if !hasDigit {
return errors.New("密码必须包含数字")
}
if !hasSpecial {
return errors.New("密码必须包含特殊符号")
}
return nil
})
}
func main() {
// ==================== API 路由(通过 RouteRegister 自动注册,遵循 ai-agent 规范) ====================
commonHttp.RouteRegister([]interface{}{
controller.Drama,
controller.Scene,
controller.Character,
controller.Prop,
controller.Bgm,
controller.Episode,
controller.Generation,
controller.ModelConfig,
controller.UserModelConfig,
controller.User,
controller.Agent,
controller.Customer,
controller.Transaction,
controller.PaymentOrder,
controller.PaymentChannelTrade,
controller.PaymentConfig,
controller.RegionPricing,
})
// ==================== Workspace 文件服务(鉴权保护) ====================
// 通过 BindHandler 代替 AddStaticPath,确保经过 JWT 中间件鉴权
commonHttp.Httpserver.BindHandler("/workspace/*", func(r *ghttp.Request) {
relPath := strings.TrimPrefix(r.URL.Path, "/workspace/")
if relPath == "" || strings.Contains(relPath, "..") {
r.Response.WriteStatus(http.StatusForbidden)
return
}
filePath := filepath.Join("workspace", relPath)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
r.Response.WriteStatus(http.StatusNotFound)
return
}
r.Response.ServeFile(filePath)
})
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
// 启动时恢复未完成的视频生成轮询
service.GenerationService.StartVideoPoller(ctx)
g.Log().Info(ctx, "service started on :3006")
<-ctx.Done()
g.Log().Info(ctx, "shutting down...")
time.Sleep(3 * time.Second) // 等待当前任务完成
g.Log().Info(ctx, "bye")
}