mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 07:57:21 +08:00
feat: 重命名主体项目
This commit is contained in:
75
internal/app/ace.go
Normal file
75
internal/app/ace.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gookit/validate"
|
||||
"github.com/knadh/koanf/v2"
|
||||
"github.com/robfig/cron/v3"
|
||||
|
||||
"github.com/tnborg/panel/pkg/queue"
|
||||
)
|
||||
|
||||
type Ace struct {
|
||||
conf *koanf.Koanf
|
||||
router *fiber.App
|
||||
migrator *gormigrate.Gormigrate
|
||||
cron *cron.Cron
|
||||
queue *queue.Queue
|
||||
}
|
||||
|
||||
func NewWeb(conf *koanf.Koanf, router *fiber.App, migrator *gormigrate.Gormigrate, cron *cron.Cron, queue *queue.Queue, _ *validate.Validation) *Ace {
|
||||
return &Ace{
|
||||
conf: conf,
|
||||
router: router,
|
||||
migrator: migrator,
|
||||
cron: cron,
|
||||
queue: queue,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Ace) Run() error {
|
||||
// migrate database
|
||||
if err := r.migrator.Migrate(); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("[DB] database migrated")
|
||||
|
||||
// start cron scheduler
|
||||
r.cron.Start()
|
||||
fmt.Println("[CRON] cron scheduler started")
|
||||
|
||||
// start queue
|
||||
r.queue.Run(context.TODO())
|
||||
|
||||
// run http server
|
||||
config := fiber.ListenConfig{
|
||||
ListenerNetwork: fiber.NetworkTCP,
|
||||
EnablePrefork: r.conf.Bool("http.prefork"),
|
||||
EnablePrintRoutes: r.conf.Bool("http.debug"),
|
||||
DisableStartupMessage: !r.conf.Bool("http.debug"),
|
||||
}
|
||||
if r.conf.Bool("http.tls") {
|
||||
config.CertFile = filepath.Join(Root, "panel/storage/cert.pem")
|
||||
config.CertKeyFile = filepath.Join(Root, "panel/storage/cert.key")
|
||||
fmt.Println("[HTTP] listening and serving on port", r.conf.MustInt("http.port"), "with tls")
|
||||
} else {
|
||||
fmt.Println("[HTTP] listening and serving on port", r.conf.MustInt("http.port"))
|
||||
}
|
||||
|
||||
return r.router.Listen(fmt.Sprintf(":%d", r.conf.MustInt("http.port")), config)
|
||||
}
|
||||
|
||||
func (r *Ace) listenConfig() fiber.ListenConfig {
|
||||
// prefork not support dual stack
|
||||
return fiber.ListenConfig{
|
||||
ListenerNetwork: fiber.NetworkTCP,
|
||||
EnablePrefork: r.conf.Bool("http.prefork"),
|
||||
EnablePrintRoutes: r.conf.Bool("http.debug"),
|
||||
DisableStartupMessage: !r.conf.Bool("http.debug"),
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/bddjr/hlfhr"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
"github.com/gookit/validate"
|
||||
"github.com/knadh/koanf/v2"
|
||||
"github.com/robfig/cron/v3"
|
||||
|
||||
"github.com/tnborg/panel/pkg/queue"
|
||||
)
|
||||
|
||||
type Web struct {
|
||||
conf *koanf.Koanf
|
||||
router *chi.Mux
|
||||
server *hlfhr.Server
|
||||
migrator *gormigrate.Gormigrate
|
||||
cron *cron.Cron
|
||||
queue *queue.Queue
|
||||
}
|
||||
|
||||
func NewWeb(conf *koanf.Koanf, router *chi.Mux, server *hlfhr.Server, migrator *gormigrate.Gormigrate, cron *cron.Cron, queue *queue.Queue, _ *validate.Validation) *Web {
|
||||
return &Web{
|
||||
conf: conf,
|
||||
router: router,
|
||||
server: server,
|
||||
migrator: migrator,
|
||||
cron: cron,
|
||||
queue: queue,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Web) Run() error {
|
||||
// migrate database
|
||||
if err := r.migrator.Migrate(); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("[DB] database migrated")
|
||||
|
||||
// start cron scheduler
|
||||
r.cron.Start()
|
||||
fmt.Println("[CRON] cron scheduler started")
|
||||
|
||||
// start queue
|
||||
r.queue.Run(context.TODO())
|
||||
|
||||
// run http server
|
||||
if r.conf.Bool("http.tls") {
|
||||
cert := filepath.Join(Root, "panel/storage/cert.pem")
|
||||
key := filepath.Join(Root, "panel/storage/cert.key")
|
||||
fmt.Println("[HTTP] listening and serving on port", r.conf.MustInt("http.port"), "with tls")
|
||||
if err := r.server.ListenAndServeTLS(cert, key); !errors.Is(err, http.ErrServerClosed) {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fmt.Println("[HTTP] listening and serving on port", r.conf.MustInt("http.port"))
|
||||
if err := r.server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,25 +1,25 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
type WithAuthorize interface {
|
||||
Authorize(r *http.Request) error
|
||||
Authorize(c fiber.Ctx) error
|
||||
}
|
||||
|
||||
type WithPrepare interface {
|
||||
Prepare(r *http.Request) error
|
||||
Prepare(c fiber.Ctx) error
|
||||
}
|
||||
|
||||
type WithRules interface {
|
||||
Rules(r *http.Request) map[string]string
|
||||
Rules(c fiber.Ctx) map[string]string
|
||||
}
|
||||
|
||||
type WithFilters interface {
|
||||
Filters(r *http.Request) map[string]string
|
||||
Filters(c fiber.Ctx) map[string]string
|
||||
}
|
||||
|
||||
type WithMessages interface {
|
||||
Messages(r *http.Request) map[string]string
|
||||
Messages(c fiber.Ctx) map[string]string
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gookit/validate"
|
||||
"github.com/libtnb/chix"
|
||||
|
||||
@@ -24,58 +25,43 @@ type ErrorResponse struct {
|
||||
}
|
||||
|
||||
// Success 响应成功
|
||||
func Success(w http.ResponseWriter, data any) {
|
||||
render := chix.NewRender(w)
|
||||
defer render.Release()
|
||||
render.JSON(&SuccessResponse{
|
||||
func Success(c fiber.Ctx, data any) error {
|
||||
return c.JSON(&SuccessResponse{
|
||||
Msg: "success",
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
// Error 响应错误
|
||||
func Error(w http.ResponseWriter, code int, format string, args ...any) {
|
||||
render := chix.NewRender(w)
|
||||
defer render.Release()
|
||||
render.Header(chix.HeaderContentType, chix.MIMEApplicationJSONCharsetUTF8) // must before Status()
|
||||
render.Status(code)
|
||||
if len(args) > 0 {
|
||||
format = fmt.Sprintf(format, args...)
|
||||
}
|
||||
render.JSON(&ErrorResponse{
|
||||
Msg: format,
|
||||
func Error(c fiber.Ctx, code int, format string, args ...any) error {
|
||||
return c.Status(code).JSON(&ErrorResponse{
|
||||
Msg: fmt.Sprintf(format, args...),
|
||||
})
|
||||
}
|
||||
|
||||
// ErrorSystem 响应系统错误
|
||||
func ErrorSystem(w http.ResponseWriter) {
|
||||
render := chix.NewRender(w)
|
||||
defer render.Release()
|
||||
render.Header(chix.HeaderContentType, chix.MIMEApplicationJSONCharsetUTF8) // must before Status()
|
||||
render.Status(http.StatusInternalServerError)
|
||||
render.JSON(&ErrorResponse{
|
||||
func ErrorSystem(c fiber.Ctx) error {
|
||||
return c.Status(http.StatusInternalServerError).JSON(&ErrorResponse{
|
||||
Msg: http.StatusText(http.StatusInternalServerError),
|
||||
})
|
||||
}
|
||||
|
||||
// Bind 验证并绑定请求参数
|
||||
func Bind[T any](r *http.Request) (*T, error) {
|
||||
func Bind[T any](c fiber.Ctx) (*T, error) {
|
||||
req := new(T)
|
||||
|
||||
// 绑定参数
|
||||
binder := chix.NewBind(r)
|
||||
defer binder.Release()
|
||||
if slices.Contains([]string{"POST", "PUT", "PATCH", "DELETE"}, strings.ToUpper(r.Method)) {
|
||||
if r.ContentLength > 0 {
|
||||
if err := binder.Body(req); err != nil {
|
||||
if slices.Contains([]string{"POST", "PUT", "PATCH", "DELETE"}, strings.ToUpper(c.Method())) {
|
||||
if c.Request().Header.ContentLength() > 0 {
|
||||
if err := c.Bind().Body(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := binder.Query(req); err != nil {
|
||||
if err := c.Bind().Query(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := binder.URI(req); err != nil {
|
||||
if err := c.Bind().URI(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -87,29 +73,29 @@ func Bind[T any](r *http.Request) (*T, error) {
|
||||
v := df.Create()
|
||||
|
||||
if reqWithPrepare, ok := any(req).(request.WithPrepare); ok {
|
||||
if err = reqWithPrepare.Prepare(r); err != nil {
|
||||
if err = reqWithPrepare.Prepare(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if reqWithAuthorize, ok := any(req).(request.WithAuthorize); ok {
|
||||
if err = reqWithAuthorize.Authorize(r); err != nil {
|
||||
if err = reqWithAuthorize.Authorize(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if reqWithRules, ok := any(req).(request.WithRules); ok {
|
||||
if rules := reqWithRules.Rules(r); rules != nil {
|
||||
if rules := reqWithRules.Rules(c); rules != nil {
|
||||
for key, value := range rules {
|
||||
v.StringRule(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
if reqWithFilters, ok := any(req).(request.WithFilters); ok {
|
||||
if filters := reqWithFilters.Filters(r); filters != nil {
|
||||
if filters := reqWithFilters.Filters(c); filters != nil {
|
||||
v.FilterRules(filters)
|
||||
}
|
||||
}
|
||||
if reqWithMessages, ok := any(req).(request.WithMessages); ok {
|
||||
if messages := reqWithMessages.Messages(r); messages != nil {
|
||||
if messages := reqWithMessages.Messages(c); messages != nil {
|
||||
v.AddMessages(messages)
|
||||
}
|
||||
}
|
||||
@@ -123,8 +109,8 @@ func Bind[T any](r *http.Request) (*T, error) {
|
||||
}
|
||||
|
||||
// Paginate 取分页条目
|
||||
func Paginate[T any](r *http.Request, items []T) (pagedItems []T, total uint) {
|
||||
req, err := Bind[request.Paginate](r)
|
||||
func Paginate[T any](c fiber.Ctx, items []T) (pagedItems []T, total uint) {
|
||||
req, err := Bind[request.Paginate](c)
|
||||
if err != nil {
|
||||
req = &request.Paginate{
|
||||
Page: 1,
|
||||
|
||||
Reference in New Issue
Block a user