2025-06-17 10:50:08 +08:00

96 lines
2.1 KiB
Go

package render
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/a-h/templ"
"github.com/drhin/logger"
"go.uber.org/zap"
)
type Renderer interface {
Render(ctx context.Context, w http.ResponseWriter, t templ.Component)
JSON(w http.ResponseWriter, data any)
JSONObj(w http.ResponseWriter, message string, data any)
JSONOk(w http.ResponseWriter, message string)
JSONErr(w http.ResponseWriter, message string)
}
type render struct {
log *logger.Logger
}
func NewRender(log *logger.Logger) Renderer {
return &render{
log: log,
}
}
func (r *render) Render(ctx context.Context, w http.ResponseWriter, t templ.Component) {
if err := t.Render(ctx, w); err != nil {
r.log.Error(err.Error(), err,
zap.String("templ render", fmt.Sprintf("%v", t)),
)
}
}
func (r *render) JSON(w http.ResponseWriter, data any) {
respond(w, data)
}
func (r *render) JSONObj(w http.ResponseWriter, message string, data any) {
respond(w, Response{Success: true, Message: message, Data: data})
}
func (r *render) JSONOk(w http.ResponseWriter, message string) {
respond(w, Response{Success: true, Message: message})
}
func (r *render) JSONErr(w http.ResponseWriter, message string) {
respond(w, Response{Success: false, Message: message})
}
type Response struct {
Success bool `json:"success"`
Message string `json:"msg"`
Data any `json:"data"`
}
type ResponseTree struct {
Status ResponseTreeStatus `json:"status"`
Data any `json:"data"`
}
type ResponseTreeStatus struct {
Code int `json:"code"`
Message string `json:"message"`
}
type ResponseList struct {
Code int `json:"code"`
Message string `json:"msg"`
Count int64 `json:"count"`
Data any `json:"data"`
}
func respond(w http.ResponseWriter, data any) {
v, err := json.Marshal(data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusOK)
_, err = w.Write(v)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}