feat: as docker mirror registry

feat: add global proxy config
upgrade: upgrade front(angular) to 19
chore: deployment staff
  1. Dockerfile: build frontend, backend, and run in nginx base image
This commit is contained in:
loveuer
2024-12-23 00:07:44 -08:00
parent aac6c67a5f
commit 6e866b83e4
57 changed files with 22226 additions and 7343 deletions

136
internal/tool/r/resp.go Normal file
View File

@ -0,0 +1,136 @@
package r
import (
"fmt"
"github.com/loveuer/nf"
"strings"
)
const (
MSG200 = "请求成功"
MSG202 = "请求成功, 请稍后..."
MSG400 = "请求参数错误"
MSG401 = "登录已过期, 请重新登录"
MSG403 = "请求权限不足"
MSG404 = "请求资源未找到"
MSG429 = "请求过于频繁, 请稍后再试"
MSG500 = "服务器开小差了, 请稍后再试"
MSG501 = "功能开发中, 尽情期待"
)
func handleEmptyMsg(status uint32, msg string) string {
if msg == "" {
switch status {
case 200:
msg = MSG200
case 202:
msg = MSG202
case 400:
msg = MSG400
case 401:
msg = MSG401
case 403:
msg = MSG403
case 404:
msg = MSG404
case 429:
msg = MSG429
case 500:
msg = MSG500
case 501:
msg = MSG501
}
}
return msg
}
func Resp(c *nf.Ctx, status uint32, msg string, err string, data any) error {
msg = handleEmptyMsg(status, msg)
if data == nil {
return c.Status(int(status)).JSON(nf.Map{"status": status, "msg": msg, "err": err})
}
return c.Status(int(status)).JSON(nf.Map{"status": status, "msg": msg, "err": err, "data": data})
}
func Resp200(c *nf.Ctx, data any, msgs ...string) error {
msg := MSG200
if len(msgs) > 0 && msgs[0] != "" {
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
}
return Resp(c, 200, msg, "", data)
}
func Resp202(c *nf.Ctx, data any, msgs ...string) error {
msg := MSG202
if len(msgs) > 0 && msgs[0] != "" {
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
}
return Resp(c, 202, msg, "", data)
}
func Resp400(c *nf.Ctx, data any, msgs ...string) error {
msg := MSG400
err := ""
if len(msgs) > 0 && msgs[0] != "" {
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
err = msg
}
return Resp(c, 400, msg, err, data)
}
func Resp401(c *nf.Ctx, data any, msgs ...string) error {
msg := MSG401
err := ""
if len(msgs) > 0 && msgs[0] != "" {
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
err = msg
}
return Resp(c, 401, msg, err, data)
}
func Resp403(c *nf.Ctx, data any, msgs ...string) error {
msg := MSG403
err := ""
if len(msgs) > 0 && msgs[0] != "" {
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
err = msg
}
return Resp(c, 403, msg, err, data)
}
func Resp429(c *nf.Ctx, data any, msgs ...string) error {
msg := MSG429
err := ""
if len(msgs) > 0 && msgs[0] != "" {
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
err = ""
}
return Resp(c, 429, msg, err, data)
}
func Resp500(c *nf.Ctx, data any, msgs ...string) error {
msg := MSG500
err := ""
if len(msgs) > 0 && msgs[0] != "" {
msg = fmt.Sprintf("%s: %s", msg, strings.Join(msgs, "; "))
err = msg
}
return Resp(c, 500, msg, err, data)
}

View File

@ -0,0 +1,61 @@
package rerr
import (
"github.com/loveuer/nf"
"net/http"
)
type RepositoryError struct {
Status int
Code string
Message string
}
func Error(c *nf.Ctx, err *RepositoryError) error {
return c.Status(err.Status).JSON(nf.Map{
"errors": []nf.Map{
{
"code": err.Code,
"message": err.Message,
},
},
})
}
func ErrInternal(err error) *RepositoryError {
return &RepositoryError{
Status: http.StatusInternalServerError,
Code: "INTERNAL_SERVER_ERROR",
Message: err.Error(),
}
}
var ErrBlobUnknown = &RepositoryError{
Status: http.StatusNotFound,
Code: "BLOB_UNKNOWN",
Message: "Unknown blob",
}
var ErrUnsupported = &RepositoryError{
Status: http.StatusMethodNotAllowed,
Code: "UNSUPPORTED",
Message: "Unsupported operation",
}
var ErrDigestMismatch = &RepositoryError{
Status: http.StatusBadRequest,
Code: "DIGEST_INVALID",
Message: "digest does not match contents",
}
var ErrDigestInvalid = &RepositoryError{
Status: http.StatusBadRequest,
Code: "NAME_INVALID",
Message: "invalid digest",
}
var ErrUnauthorized = &RepositoryError{
Status: http.StatusUnauthorized,
Code: "UNAUTHORIZED",
Message: "access to the requested resource is not authorized",
}

View File

@ -0,0 +1,38 @@
package tools
import (
"context"
"time"
)
func Timeout(seconds ...int) (ctx context.Context) {
var (
duration time.Duration
)
if len(seconds) > 0 && seconds[0] > 0 {
duration = time.Duration(seconds[0]) * time.Second
} else {
duration = time.Duration(30) * time.Second
}
ctx, _ = context.WithTimeout(context.Background(), duration)
return
}
func TimeoutCtx(ctx context.Context, seconds ...int) context.Context {
var (
duration time.Duration
)
if len(seconds) > 0 && seconds[0] > 0 {
duration = time.Duration(seconds[0]) * time.Second
} else {
duration = time.Duration(30) * time.Second
}
nctx, _ := context.WithTimeout(ctx, duration)
return nctx
}

View File

@ -0,0 +1,125 @@
package tools
import (
"encoding/json"
"fmt"
"io"
"os"
"reflect"
"strings"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/loveuer/nf/nft/log"
)
func TablePrinter(data any, writers ...io.Writer) {
var w io.Writer = os.Stdout
if len(writers) > 0 && writers[0] != nil {
w = writers[0]
}
t := table.NewWriter()
structPrinter(t, "", data)
_, _ = fmt.Fprintln(w, t.Render())
}
func structPrinter(w table.Writer, prefix string, item any) {
Start:
rv := reflect.ValueOf(item)
if rv.IsZero() {
return
}
for rv.Type().Kind() == reflect.Pointer {
rv = rv.Elem()
}
switch rv.Type().Kind() {
case reflect.Invalid,
reflect.Uintptr,
reflect.Chan,
reflect.Func,
reflect.UnsafePointer:
case reflect.Bool,
reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64,
reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Float32,
reflect.Float64,
reflect.Complex64,
reflect.Complex128,
reflect.Interface:
w.AppendRow(table.Row{strings.TrimPrefix(prefix, "."), rv.Interface()})
case reflect.String:
val := rv.String()
if len(val) <= 160 {
w.AppendRow(table.Row{strings.TrimPrefix(prefix, "."), val})
return
}
w.AppendRow(table.Row{strings.TrimPrefix(prefix, "."), val[0:64] + "..." + val[len(val)-64:]})
case reflect.Array, reflect.Slice:
for i := 0; i < rv.Len(); i++ {
p := strings.Join([]string{prefix, fmt.Sprintf("[%d]", i)}, ".")
structPrinter(w, p, rv.Index(i).Interface())
}
case reflect.Map:
for _, k := range rv.MapKeys() {
structPrinter(w, fmt.Sprintf("%s.{%v}", prefix, k), rv.MapIndex(k).Interface())
}
case reflect.Pointer:
goto Start
case reflect.Struct:
for i := 0; i < rv.NumField(); i++ {
p := fmt.Sprintf("%s.%s", prefix, rv.Type().Field(i).Name)
field := rv.Field(i)
// log.Debug("TablePrinter: prefix: %s, field: %v", p, rv.Field(i))
if !field.CanInterface() {
return
}
structPrinter(w, p, field.Interface())
}
}
}
func TableMapPrinter(data []byte) {
m := make(map[string]any)
if err := json.Unmarshal(data, &m); err != nil {
log.Warn(err.Error())
return
}
t := table.NewWriter()
addRow(t, "", m)
fmt.Println(t.Render())
}
func addRow(w table.Writer, prefix string, m any) {
rv := reflect.ValueOf(m)
switch rv.Type().Kind() {
case reflect.Map:
for _, k := range rv.MapKeys() {
key := k.String()
if prefix != "" {
key = strings.Join([]string{prefix, k.String()}, ".")
}
addRow(w, key, rv.MapIndex(k).Interface())
}
case reflect.Slice, reflect.Array:
for i := 0; i < rv.Len(); i++ {
addRow(w, fmt.Sprintf("%s[%d]", prefix, i), rv.Index(i).Interface())
}
default:
w.AppendRow(table.Row{prefix, m})
}
}