Browse Source

在线白板后端

huangyan 1 year ago
commit
aa59643474

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 9 - 0
.idea/file_upload.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/file_upload.iml" filepath="$PROJECT_DIR$/.idea/file_upload.iml" />
+    </modules>
+  </component>
+</project>

+ 205 - 0
app/controller/file.go

@@ -0,0 +1,205 @@
+package controller
+
+import (
+	"context"
+	"file_upload/app/e"
+	"file_upload/app/model"
+	"file_upload/global"
+	"file_upload/simple_zap"
+	"github.com/bytedance/sonic"
+	"github.com/gin-gonic/gin"
+)
+
+type Body struct {
+	Name string
+	Data any
+	Type bool
+}
+
+//	func FuileUpload(c *gin.Context) {
+//		const maxMemory = 1 << 20
+//		if err := c.Request.ParseMultipartForm(maxMemory); err != nil {
+//			e.ResponseWithMsg(c, e.ERROR, "获取文件失败")
+//			simple_zap.WithCtx(context.Background()).Sugar().Warn(err)
+//			return
+//		}
+//		file, err := c.FormFile("previewImage")
+//		formFile, err := c.FormFile("excalidrawLib")
+//		if err != nil {
+//			e.ResponseWithMsg(c, e.ERROR, "获取文件失败")
+//			simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取文件失败")
+//			return
+//		}
+//		title := c.PostForm("name")
+//		if err := c.SaveUploadedFile(file, "./upload/"+file.Filename+title+"."+"png"); err != nil {
+//			e.ResponseWithMsg(c, e.ERROR, "保存文件失败")
+//			simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "保存文件失败")
+//			return
+//		}
+//		if err := c.SaveUploadedFile(formFile, "./upload/"+formFile.Filename+title+"."+"excalidrawlib"); err != nil {
+//			e.ResponseWithMsg(c, e.ERROR, "保存文件失败")
+//			simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "保存文件失败")
+//			return
+//		}
+//		e.ResponseSuccess(c, e.SUCCESS)
+//	}
+//
+//	func FileDwon(c *gin.Context) {
+//		filname := "cec.json"
+//		filpath := "./upload/" + filname
+//		if _, err := os.Stat(filpath); os.IsNotExist(err) {
+//			simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "文件获取失败")
+//			c.AbortWithStatus(http.StatusNotFound)
+//			return
+//		}
+//		// 设置 Content-Disposition 响应头,提供默认的文件名
+//		c.Header("Content-Disposition", "attachment; filename="+filname)
+//		// 发送文件内容
+//		c.File(filpath)
+//	}
+func SaveFile(c *gin.Context) {
+	file := Body{}
+	err := c.BindJSON(&file)
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取参数失败")
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	m := map[string]any{
+		"type": file.Type,
+		"data": file.Data,
+	}
+	marshal, err := sonic.Marshal(m)
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "序列化失败")
+		e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
+		return
+	}
+	result, err := global.Rdb.Exists(context.Background(), file.Name).Result()
+	if result == 1 {
+		e.ResponseWithMsg(c, e.AlreadyExists, e.AlreadyExists.GetMsg())
+		return
+	}
+	set := global.Rdb.Set(context.Background(), file.Name, marshal, 0)
+	if set.Err() != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(set.Err(), "保存文件失败")
+		e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
+		return
+	}
+	e.ResponseSuccess(c, e.SUCCESS)
+}
+
+// TemplateItem 用于获取所有的模板项
+// 参数:
+// - c *gin.Context: Gin框架的上下文对象,用于处理HTTP请求和响应
+// 返回值:
+// - 无
+func TemplateItem(c *gin.Context) {
+	type Types struct {
+		Type bool `json:"type"`
+	}
+	t := &Types{}
+	c.BindJSON(&t)
+	var allKeys []string  // 存储所有检索到的模板项的键名
+	var cursor uint64 = 0 // 用于分页查询的游标
+	// 循环检索模板项,直到遍历完所有项或出现错误
+	for {
+		keys, newCursor, err := global.Rdb.Scan(context.Background(), cursor, "*", 100).Result() // 每次检索最多100个键名
+		if err != nil {
+			// 记录日志并返回错误信息
+			simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取模板失败")
+			e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
+			return
+		}
+		allKeys = append(allKeys, keys...) // 将检索到的键名添加到allKeys列表
+		cursor = newCursor                 // 更新游标
+		if cursor == 0 {
+			break // 如果游标为0,表示已遍历完所有项,退出循环
+		}
+	}
+	m := make(map[string]any) // 创建一个map用于存储模板项的键名和对应的值
+	// 遍历所有键名,获取其对应的值
+	for _, key := range allKeys {
+		result, err := global.Rdb.Get(context.Background(), key).Result()
+		if err != nil {
+			// 记录日志并返回错误信息
+			simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取模板失败")
+			e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
+			return
+		}
+		file := model.Root{}
+		//marshal, err := sonic.Marshal(result)
+		err = sonic.Unmarshal([]byte(result), &file)
+		if err != nil {
+			// 记录日志并返回错误信息
+			simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "序列化失败")
+			e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
+			return
+		}
+		if t.Type == file.Type {
+			m[key] = result // 将键名和对应的值添加到map中
+		}
+	}
+	// 返回所有模板项的键值对
+	e.ResponseSuccess(c, m)
+}
+
+// GetTemplate 从服务器获取模板
+func GetTemplate(c *gin.Context) {
+	name := c.Query("name")
+	if name == "" {
+		e.ResponseWithMsg(c, e.ERROR, "参数错误")
+		return
+	}
+	result, err := global.Rdb.Get(context.Background(), name).Result()
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取文件失败")
+		e.ResponseWithMsg(c, e.ERROR, "获取文件失败")
+		return
+	}
+	e.ResponseSuccess(c, result)
+}
+func DeleteTemplate(c *gin.Context) {
+	name := c.Query("name")
+	if name == "" {
+		e.ResponseWithMsg(c, e.ERROR, "参数错误")
+		return
+	}
+	err := global.Rdb.Del(context.Background(), name).Err()
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "删除文件失败")
+		e.ResponseWithMsg(c, e.ERROR, "删除文件失败")
+		return
+	}
+	e.ResponseSuccess(c, e.SUCCESS)
+}
+
+//// SaveUsernameToLocalStorage 保存用户名到本地
+//func SaveUsernameToLocalStorage(c *gin.Context) {
+//	usernam := c.PostForm("username")
+//	simple_zap.WithCtx(context.Background()).Sugar().Info(usernam)
+//	global.Rdb.Set(context.Background(), "username", usernam, 0)
+//	e.ResponseSuccess(c, e.SUCCESS)
+//}
+//
+//// SerializedItems 保存素材到redis数据库
+//func SerializedItems(c *gin.Context) {
+//	type Params struct {
+//		Params string
+//	}
+//	serializedItem := Params{}
+//	err := c.BindJSON(&serializedItem)
+//	if err != nil {
+//		simple_zap.WithCtx(context.Background()).Sugar().Warn("获取参数失败")
+//	}
+//	fmt.Println("serializedItems:", serializedItem.Params)
+//	global.Rdb.Set(context.Background(), "serializedItems", serializedItem.Params, 0)
+//	e.ResponseSuccess(c, e.SUCCESS)
+//}
+
+//// GetSerializedItems 从redis数据库获取素材信息
+//func GetSerializedItems(c *gin.Context) {
+//	get := global.Rdb.Get(context.Background(), "serializedItems")
+//	fmt.Println("GetserializedItems:", get.Val())
+//	e.ResponseSuccess(c, get.Val())
+//}

+ 34 - 0
app/e/R.go

@@ -0,0 +1,34 @@
+package e
+
+import (
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+type R struct {
+	Code    Rescode     `json:"code"`
+	Message any         `json:"message"`
+	Data    interface{} `json:"data"`
+}
+
+func ResponseError(c *gin.Context, code Rescode) {
+	c.JSON(http.StatusOK, &R{
+		Code:    code,
+		Message: code.GetMsg(),
+		Data:    nil,
+	})
+}
+func ResponseSuccess(c *gin.Context, data interface{}) {
+	c.JSON(http.StatusOK, &R{
+		Code:    SUCCESS,
+		Message: SUCCESS.GetMsg(),
+		Data:    data,
+	})
+}
+func ResponseWithMsg(c *gin.Context, code Rescode, msg any) {
+	c.JSON(http.StatusOK, &R{
+		Code:    code,
+		Message: msg,
+		Data:    nil,
+	})
+}

+ 63 - 0
app/e/code_msg.go

@@ -0,0 +1,63 @@
+package e
+
+type Rescode int64
+
+const (
+	SUCCESS Rescode = 200 + iota
+	ERROR
+)
+
+const (
+	TokenIsInvalid Rescode = 1001 + iota
+	TokenIsExpired
+	DELETEFAIL
+	UPDATEFAIL
+	ErrorFileReadFailed
+	PaginationFailed
+	JSONParsingFailed
+	TheUserAlreadyExists
+	AlreadyExists
+	TheSystemIsAbnormal
+	CodeIsError
+	Theuseralreadyexists
+	ThePhoneNumberIsWrong
+	AnExceptionOccursWhenSendingAnSMSVerificationCode
+	TokenIsFaild
+	ThePasswordIsWrongOrThePhoneNumberIsIncorrect
+	HasSend
+	TheUserIsEmpty
+)
+
+var MsgFlags = map[Rescode]string{
+	SUCCESS:               "ok",
+	ERROR:                 "fail",
+	DELETEFAIL:            "删除失败",
+	TheUserAlreadyExists:  "用户已存在",
+	TheSystemIsAbnormal:   "系统异常",
+	CodeIsError:           "验证码错误",
+	UPDATEFAIL:            "更新失败",
+	Theuseralreadyexists:  "用户已存在",
+	JSONParsingFailed:     "json解析失败",
+	ThePhoneNumberIsWrong: "手机号错误",
+	HasSend:               "验证码已发送",
+	AlreadyExists:         "手机号已存在",
+	PaginationFailed:      "分页查询失败",
+	ErrorFileReadFailed:   "文件获取失败",
+	AnExceptionOccursWhenSendingAnSMSVerificationCode: "发送短信验证码出现异常",
+	ThePasswordIsWrongOrThePhoneNumberIsIncorrect:     "手机号或者密码错误",
+	TokenIsInvalid: "Token 无效",
+	TokenIsExpired: "Token 过期",
+	TokenIsFaild:   "Token 生成失败",
+	TheUserIsEmpty: "用户为空",
+}
+
+func (c Rescode) GetMsg() string {
+	// 检查Rescode是否在MsgFlags中定义,避免返回意外的消息
+	msg, ok := MsgFlags[c]
+	if ok {
+		return msg
+	} else {
+		// 如果Rescode无效,则返回错误消息
+		return MsgFlags[ERROR]
+	}
+}

+ 24 - 0
app/middlewares/cors.go

@@ -0,0 +1,24 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+func Cors() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		method := c.Request.Method
+		origin := c.Request.Header.Get("Origin")
+		if origin != "" {
+			c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名
+			c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
+			c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
+			c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
+			c.Header("Access-Control-Allow-Credentials", "true")
+		}
+		if method == "OPTIONS" {
+			c.AbortWithStatus(http.StatusNoContent)
+		}
+		c.Next()
+	}
+}

+ 52 - 0
app/model/model.go

@@ -0,0 +1,52 @@
+package model
+
+type State struct {
+	FontSize        float64    `json:"fontSize"`
+	DragStrokeStyle string     `json:"dragStrokeStyle"`
+	ShowGrid        bool       `json:"showGrid"`
+	StrokeStyle     string     `json:"strokeStyle"`
+	BackgroundColor string     `json:"backgroundColor"`
+	GridConfig      GridConfig `json:"gridConfig"`
+	ScrollY         float64    `json:"scrollY"`
+	FillStyle       string     `json:"fillStyle"`
+	Readonly        bool       `json:"readonly"`
+	Scale           float64    `json:"scale"`
+	ScrollStep      float64    `json:"scrollStep"`
+	FontFamily      string     `json:"fontFamily"`
+	ScrollX         float64    `json:"scrollX"`
+}
+
+type GridConfig struct {
+	Size        float64 `json:"size"`
+	StrokeStyle string  `json:"strokeStyle"`
+	LineWidth   float64 `json:"lineWidth"`
+}
+
+type Element struct {
+	GroupId string       `json:"groupId"`
+	Type    string       `json:"type"`
+	Width   float64      `json:"width"`
+	Height  float64      `json:"height"`
+	X       float64      `json:"x"`
+	Y       float64      `json:"y"`
+	Rotate  float64      `json:"rotate"`
+	Style   ElementStyle `json:"style"`
+}
+
+type ElementStyle struct {
+	StrokeStyle string  `json:"strokeStyle"`
+	FillStyle   string  `json:"fillStyle"`
+	LineWidth   float64 `json:"lineWidth"`
+	LineDash    float64 `json:"lineDash"`
+	GlobalAlpha float64 `json:"globalAlpha"`
+}
+
+type Data struct {
+	State    State     `json:"state"`
+	Elements []Element `json:"elements"`
+}
+
+type Root struct {
+	Type bool `json:"type"`
+	Data Data `json:"data"`
+}

+ 29 - 0
app/router.go

@@ -0,0 +1,29 @@
+package app
+
+import (
+	"file_upload/app/controller"
+	middleware "file_upload/app/middlewares"
+	"file_upload/global"
+	"github.com/gin-gonic/gin"
+	//swaggerFiles "github.com/swaggo/files"
+	//ginSwagger "github.com/swaggo/gin-swagger"
+)
+
+func InitRouter() error {
+	engine := gin.New()
+	//记录日志
+	engine.Use(middleware.Cors())
+	//engine.GET("/swagger/*any", ginSwagger.DisablingWrapHandler(swaggerFiles.Handler, global.SwaggerSetting.Enable))
+	gin.SetMode(global.ServerSetting.Mode)
+	group := engine.Group("/api")
+	group.Use(middleware.Cors())
+	//group.POST("/upload", controller.FuileUpload)
+	group.GET("/download", controller.FileDwon)
+	group.POST("/savefile", controller.SaveFile)
+	group.POST("/template", controller.TemplateItem)
+	group.GET("/template", controller.GetTemplate)
+	//group.POST("/username", controller.SaveUsernameToLocalStorage)
+	//group.POST("/serializedItems", controller.SerializedItems)
+	//group.GET("/serializedItems", controller.GetSerializedItems)
+	return engine.Run(global.ServerSetting.Port)
+}

+ 45 - 0
configs/config.yaml

@@ -0,0 +1,45 @@
+database:
+  # 数据库类型
+  dialect: mysql
+  # host地址
+  host: 127.0.0.1
+  # 端口
+  port: 3306
+  # 数据库名称
+  db: lc_oauth
+  # 数据库用户名
+  userName: root
+  # 数据库密码
+  password: 123456
+  # 其他配置参数
+  otherParams: charset=utf8mb4&parseTime=True&loc=Local
+  # 最大空闲连接数
+  maxIdleConn: 20
+  # 最大连接数
+  maxOpenConn: 200
+  # 连接超时关闭时间,单位:秒
+  connMaxLifetime: 60
+jwt:
+  secret: "xxxxx"
+  refresh_expire: 168
+  Issuer: "lc_oauth"
+# 服务相关配置
+server:
+  # 启动模式 debug、release
+  mode: debug
+  # http服务信息
+  insecureServingInfo:
+  # 监听端口
+  port: ":8080"
+subMail:
+  appid: "97173"
+  signature: "f639a60e41ee0554921d89884f5ff87e"
+redis:
+  addr: "116.204.6.184:6379"
+  password: "123456"
+  db: 0
+nats:
+  NatsServer_Url: "nats://127.0.0.0:4222"
+swag:
+  # 将环境变量 NAME_OF_ENV_VARIABLE设置为任意值,则 /swagger/*any 返回404响应
+  enable: "NAME_OF_ENV_VARIABLE"

+ 46 - 0
configs/setting.go

@@ -0,0 +1,46 @@
+package global
+
+import "github.com/spf13/viper"
+
+type Settings struct {
+	vp *viper.Viper
+}
+
+var sections = make(map[string]interface{})
+
+// NewSetting 读取配置
+func NewSetting() (*Settings, error) {
+	vp := viper.New()
+	vp.SetConfigName("config")
+	vp.AddConfigPath("configs")
+	vp.SetConfigType("yaml")
+	err := vp.ReadInConfig()
+	if err != nil {
+		return nil, err
+	}
+	s := &Settings{vp}
+	return s, nil
+}
+
+// ReadSection 读取指定的一段
+func (s *Settings) ReadSection(k string, v interface{}) error {
+	err := s.vp.UnmarshalKey(k, v)
+	if err != nil {
+		return err
+	}
+	if _, ok := sections[k]; !ok {
+		sections[k] = v
+	}
+	return nil
+}
+
+// ReloadAllSection 重新加载
+func (s *Settings) ReloadAllSection() error {
+	for k, v := range sections {
+		err := s.ReadSection(k, v)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}

+ 27 - 0
global/redis.go

@@ -0,0 +1,27 @@
+package global
+
+import (
+	"context"
+	"file_upload/simple_zap"
+	"fmt"
+	"github.com/go-redis/redis/v8"
+)
+
+var Rdb *redis.Client
+
+func SetupRedisLink() {
+	//addr := RedisSetting.Addr
+	//password := RedisSetting.Password
+	//db := RedisSetting.DB
+	Rdb = redis.NewClient(&redis.Options{
+		Addr:     RedisSetting.Addr,
+		Password: RedisSetting.Password,
+		DB:       0,
+	})
+	ctx := context.Background()
+	_, err := Rdb.Ping(ctx).Result()
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn("redis连接失败", err)
+		fmt.Println(err)
+	}
+}

+ 76 - 0
global/setting.go

@@ -0,0 +1,76 @@
+package global
+
+import (
+	global "file_upload/configs"
+)
+
+// DatabaseSettingS 数据库配置
+type DatabaseSettingS struct {
+	Dialect         string `json:"dialect"`
+	Host            string `json:"host"`
+	Port            string `json:"port"`
+	UserName        string `json:"userName"`
+	Password        string `json:"password"`
+	Db              string `json:"db"`
+	OtherParams     string `json:"otherParams"`
+	MaxIdleConn     int    `json:"max_idle_conn"`
+	MaxOpenConn     int    `json:"max_open_conn"`
+	ConnMaxLifetime string `json:"conn_max_lifetime"`
+}
+
+// Nats 配置
+type Nats struct {
+	NatsServerUrl string `json:"NatsServer_Url"`
+}
+
+// Jwt 配置
+type Jwt struct {
+	Secret        string `json:"secret"`
+	RefreshExpire int    `json:"refresh_expire"`
+	Issuer        string `json:"issuer"`
+}
+
+// ServerSettingS 服务器配置
+type ServerSettingS struct {
+	Mode                string `json:"mode"`
+	Port                string `json:"port"`
+	InsecureServingInfo string `json:"insecure_serving_info"`
+}
+type SubMail struct {
+	Appid     string `json:"appid"`
+	Signature string `json:"signature"`
+}
+type Redis struct {
+	Addr     string `json:"addr"`
+	Password string `json:"password"`
+	DB       int    `json:"db"`
+}
+type Swagger struct {
+	Enable string `json:"enable"`
+}
+
+var (
+	DatabaseSetting *DatabaseSettingS
+	NatsSetting     *Nats
+	JwtSetting      *Jwt
+	ServerSetting   *ServerSettingS
+	SubMailSetting  *SubMail
+	RedisSetting    *Redis
+	SwaggerSetting  *Swagger
+)
+
+// SetupSetting 读取配置到全局变量
+func SetupSetting() error {
+	s, err := global.NewSetting()
+	err = s.ReadSection("Database", &DatabaseSetting)
+	err = s.ReadSection("Nats", &NatsSetting)
+	err = s.ReadSection("Jwt", &JwtSetting)
+	err = s.ReadSection("Server", &ServerSetting)
+	err = s.ReadSection("SubMail", &SubMailSetting)
+	err = s.ReadSection("Redis", &RedisSetting)
+	err = s.ReadSection("Swagger", &SwaggerSetting)
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 58 - 0
go.mod

@@ -0,0 +1,58 @@
+module file_upload
+
+go 1.21
+
+require (
+	github.com/gin-gonic/gin v1.9.1
+	github.com/go-redis/redis/v8 v8.11.5
+	github.com/spf13/viper v1.18.2
+	go.uber.org/zap v1.27.0
+	gopkg.in/natefinch/lumberjack.v2 v2.2.1
+)
+
+require (
+	github.com/bytedance/sonic v1.11.3 // indirect
+	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
+	github.com/chenzhuoyu/iasm v0.9.1 // indirect
+	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
+	github.com/fsnotify/fsnotify v1.7.0 // indirect
+	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/go-playground/validator/v10 v10.19.0 // indirect
+	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/google/go-cmp v0.6.0 // indirect
+	github.com/hashicorp/hcl v1.0.0 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/cpuid/v2 v2.2.7 // indirect
+	github.com/leodido/go-urn v1.4.0 // indirect
+	github.com/magiconair/properties v1.8.7 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/mitchellh/mapstructure v1.5.0 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
+	github.com/pelletier/go-toml/v2 v2.2.0 // indirect
+	github.com/sagikazarmark/locafero v0.4.0 // indirect
+	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
+	github.com/sourcegraph/conc v0.3.0 // indirect
+	github.com/spf13/afero v1.11.0 // indirect
+	github.com/spf13/cast v1.6.0 // indirect
+	github.com/spf13/pflag v1.0.5 // indirect
+	github.com/subosito/gotenv v1.6.0 // indirect
+	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+	github.com/ugorji/go/codec v1.2.12 // indirect
+	go.uber.org/multierr v1.10.0 // indirect
+	golang.org/x/arch v0.7.0 // indirect
+	golang.org/x/crypto v0.22.0 // indirect
+	golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
+	golang.org/x/net v0.24.0 // indirect
+	golang.org/x/sys v0.19.0 // indirect
+	golang.org/x/text v0.14.0 // indirect
+	google.golang.org/protobuf v1.33.0 // indirect
+	gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
+	gopkg.in/ini.v1 v1.67.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)

+ 157 - 0
go.sum

@@ -0,0 +1,157 @@
+github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
+github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
+github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA=
+github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
+github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
+github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
+github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
+github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
+github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
+github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
+github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
+github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
+github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
+github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
+github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
+github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
+github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
+github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
+github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo=
+github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
+github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
+github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
+github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
+github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
+github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
+github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
+github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
+github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
+github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
+github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
+github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
+github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
+go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
+go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
+golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
+golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
+golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
+golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
+golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

+ 116 - 0
log/app.log

@@ -0,0 +1,116 @@
+{"level":"warn","time":"2024-04-09T21:10:23.363+0800","lineNum":"file_upload/main.go:14","func":"main.init.0","message":"<nil>"}
+{"level":"warn","time":"2024-04-10T15:08:01.502+0800","lineNum":"controller/fileUpload.go:20","func":"file_upload/app/controller.FuileUpload","message":"http: no such file"}
+{"level":"warn","time":"2024-04-10T15:09:32.780+0800","lineNum":"controller/fileUpload.go:20","func":"file_upload/app/controller.FuileUpload","message":"http: no such file"}
+{"level":"warn","time":"2024-04-10T15:10:08.591+0800","lineNum":"controller/fileUpload.go:20","func":"file_upload/app/controller.FuileUpload","message":"http: no such file"}
+{"level":"warn","time":"2024-04-10T15:11:35.769+0800","lineNum":"controller/fileUpload.go:20","func":"file_upload/app/controller.FuileUpload","message":"http: no such file"}
+{"level":"warn","time":"2024-04-10T15:19:09.999+0800","lineNum":"controller/fileUpload.go:24","func":"file_upload/app/controller.FuileUpload","message":"http: no such file"}
+{"level":"warn","time":"2024-04-10T15:20:13.812+0800","lineNum":"controller/fileUpload.go:24","func":"file_upload/app/controller.FuileUpload","message":"http: no such file"}
+{"level":"warn","time":"2024-04-10T15:25:25.164+0800","lineNum":"controller/fileUpload.go:25","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T15:25:25.181+0800","lineNum":"controller/fileUpload.go:34","func":"file_upload/app/controller.FuileUpload","message":"http: no such file获取文件失败"}
+{"level":"warn","time":"2024-04-10T15:26:12.817+0800","lineNum":"controller/fileUpload.go:25","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T15:27:25.042+0800","lineNum":"controller/fileUpload.go:34","func":"file_upload/app/controller.FuileUpload","message":"http: no such file获取文件失败"}
+{"level":"warn","time":"2024-04-10T15:37:11.908+0800","lineNum":"controller/fileUpload.go:25","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T15:37:11.921+0800","lineNum":"controller/fileUpload.go:34","func":"file_upload/app/controller.FuileUpload","message":"http: no such file获取文件失败"}
+{"level":"warn","time":"2024-04-10T15:37:11.921+0800","lineNum":"controller/fileUpload.go:25","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T15:37:11.922+0800","lineNum":"controller/fileUpload.go:34","func":"file_upload/app/controller.FuileUpload","message":"http: no such file获取文件失败"}
+{"level":"warn","time":"2024-04-10T15:38:48.248+0800","lineNum":"controller/fileUpload.go:25","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T15:41:13.289+0800","lineNum":"controller/fileUpload.go:25","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T15:44:07.096+0800","lineNum":"controller/fileUpload.go:25","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T15:47:50.816+0800","lineNum":"controller/fileUpload.go:26","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T15:48:44.327+0800","lineNum":"controller/fileUpload.go:26","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T16:02:37.197+0800","lineNum":"controller/fileUpload.go:26","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T16:04:23.279+0800","lineNum":"controller/fileUpload.go:26","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T16:07:06.937+0800","lineNum":"controller/fileUpload.go:26","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-10T16:35:59.303+0800","lineNum":"controller/fileUpload.go:26","func":"file_upload/app/controller.FuileUpload","message":"invalid character '-' in numeric literaljson解析失败"}
+{"level":"warn","time":"2024-04-12T10:15:01.654+0800","lineNum":"global/redis.go:24","func":"file_upload/global.SetupRedisLink","message":"redis连接失败dial tcp 192.168.0.100:6379: i/o timeout"}
+{"level":"info","time":"2024-04-12T11:04:14.714+0800","lineNum":"controller/fileUpload.go:56","func":"file_upload/app/controller.SaveUsernameToLocalStorage","message":""}
+{"level":"info","time":"2024-04-12T11:04:14.719+0800","lineNum":"controller/fileUpload.go:56","func":"file_upload/app/controller.SaveUsernameToLocalStorage","message":""}
+{"level":"info","time":"2024-04-12T11:08:25.520+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:08:28.789+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:09:34.080+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:09:34.992+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:10:11.454+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:11:20.670+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:11:53.134+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:12:37.407+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:13:08.941+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:16:00.560+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:23:37.708+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:23:37.708+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:33:21.029+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:33:34.426+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:36:33.407+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:37:12.069+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:37:28.868+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:37:32.302+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:37:56.607+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:38:19.036+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:38:52.967+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:40:37.117+0800","lineNum":"controller/fileUpload.go:62","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:40:51.263+0800","lineNum":"controller/fileUpload.go:63","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:40:59.205+0800","lineNum":"controller/fileUpload.go:63","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:41:42.969+0800","lineNum":"controller/fileUpload.go:63","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:42:37.651+0800","lineNum":"controller/fileUpload.go:63","func":"file_upload/app/controller.SerializedItems","message":""}
+{"level":"info","time":"2024-04-12T11:49:22.589+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal array into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:28:16.714+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type []interface {}"}
+{"level":"info","time":"2024-04-12T12:32:02.472+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:42:02.957+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:42:04.532+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:42:17.735+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:44:06.073+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:44:06.076+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:44:17.355+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:46:08.327+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:46:12.343+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:46:21.897+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"json: cannot unmarshal object into Go value of type string"}
+{"level":"info","time":"2024-04-12T12:47:42.838+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T13:56:52.390+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T13:56:54.652+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T13:57:06.361+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T13:57:38.443+0800","lineNum":"controller/fileUpload.go:64","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:00:28.155+0800","lineNum":"controller/fileUpload.go:66","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:02:07.979+0800","lineNum":"controller/fileUpload.go:69","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:02:23.405+0800","lineNum":"controller/fileUpload.go:69","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:02:39.691+0800","lineNum":"controller/fileUpload.go:69","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:03:43.246+0800","lineNum":"controller/fileUpload.go:70","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:05:44.934+0800","lineNum":"controller/fileUpload.go:70","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:06:01.615+0800","lineNum":"controller/fileUpload.go:70","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:06:48.383+0800","lineNum":"controller/fileUpload.go:70","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:06:48.383+0800","lineNum":"controller/fileUpload.go:70","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:07:00.876+0800","lineNum":"controller/fileUpload.go:70","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:12:17.525+0800","lineNum":"controller/fileUpload.go:70","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:12:38.443+0800","lineNum":"controller/fileUpload.go:70","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:14:09.847+0800","lineNum":"controller/fileUpload.go:72","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:18:26.814+0800","lineNum":"controller/fileUpload.go:72","func":"file_upload/app/controller.SerializedItems","message":"<nil>"}
+{"level":"info","time":"2024-04-12T14:19:39.683+0800","lineNum":"controller/fileUpload.go:74","func":"file_upload/app/controller.SerializedItems","message":"EOF"}
+{"level":"info","time":"2024-04-12T14:20:25.082+0800","lineNum":"controller/fileUpload.go:74","func":"file_upload/app/controller.SerializedItems","message":"EOF"}
+{"level":"info","time":"2024-04-12T14:21:06.105+0800","lineNum":"controller/fileUpload.go:67","func":"file_upload/app/controller.SerializedItems","message":"{[{\"id\":\"XOxMtR7pQmbeQJ8JFH67r\",\"status\":\"unpublished\",\"elements\":[{\"type\":\"ellipse\",\"version\":101,\"versionNonce\":478164098,\"isDeleted\":false,\"id\":\"fX6N86TfVdOIdc3PSD3KL\",\"fillStyle\":\"hachure\",\"strokeWidth\":1,\"strokeStyle\":\"solid\",\"roughness\":1,\"opacity\":100,\"angle\":0,\"x\":540.2000122070312,\"y\":-37.400001525878906,\"strokeColor\":\"#000000\",\"backgroundColor\":\"transparent\",\"width\":272.79998779296875,\"height\":266.4000015258789,\"seed\":518248706,\"groupIds\":[],\"roundness\":{\"type\":2},\"boundElements\":[],\"updated\":1712902311981,\"link\":null,\"locked\":false},{\"type\":\"rectangle\",\"version\":146,\"versionNonce\":1953708482,\"isDeleted\":false,\"id\":\"PELjrZObO6_8JBXTADkEn\",\"fillStyle\":\"hachure\",\"strokeWidth\":1,\"strokeStyle\":\"solid\",\"roughness\":1,\"opacity\":100,\"angle\":0,\"x\":566.5999755859375,\"y\":1.0000152587890625,\"strokeColor\":\"#000000\",\"backgroundColor\":\"transparent\",\"width\":218.40002441406253,\"height\":192.79998779296878,\"seed\":222975042,\"groupIds\":[],\"roundness\":{\"type\":3},\"boundElements\":[],\"updated\":1712902326027,\"link\":null,\"locked\":false}],\"created\":1712902332363}]}"}
+{"level":"info","time":"2024-04-12T14:21:54.360+0800","lineNum":"controller/fileUpload.go:67","func":"file_upload/app/controller.SerializedItems","message":"{[{\"id\":\"XOxMtR7pQmbeQJ8JFH67r\",\"status\":\"unpublished\",\"elements\":[{\"type\":\"ellipse\",\"version\":101,\"versionNonce\":478164098,\"isDeleted\":false,\"id\":\"fX6N86TfVdOIdc3PSD3KL\",\"fillStyle\":\"hachure\",\"strokeWidth\":1,\"strokeStyle\":\"solid\",\"roughness\":1,\"opacity\":100,\"angle\":0,\"x\":540.2000122070312,\"y\":-37.400001525878906,\"strokeColor\":\"#000000\",\"backgroundColor\":\"transparent\",\"width\":272.79998779296875,\"height\":266.4000015258789,\"seed\":518248706,\"groupIds\":[],\"roundness\":{\"type\":2},\"boundElements\":[],\"updated\":1712902311981,\"link\":null,\"locked\":false},{\"type\":\"rectangle\",\"version\":146,\"versionNonce\":1953708482,\"isDeleted\":false,\"id\":\"PELjrZObO6_8JBXTADkEn\",\"fillStyle\":\"hachure\",\"strokeWidth\":1,\"strokeStyle\":\"solid\",\"roughness\":1,\"opacity\":100,\"angle\":0,\"x\":566.5999755859375,\"y\":1.0000152587890625,\"strokeColor\":\"#000000\",\"backgroundColor\":\"transparent\",\"width\":218.40002441406253,\"height\":192.79998779296878,\"seed\":222975042,\"groupIds\":[],\"roundness\":{\"type\":3},\"boundElements\":[],\"updated\":1712902326027,\"link\":null,\"locked\":false}],\"created\":1712902332363}]}"}
+{"level":"warn","time":"2024-04-14T15:53:08.658+0800","lineNum":"global/redis.go:24","func":"file_upload/global.SetupRedisLink","message":"redis连接失败NOAUTH Authentication required."}
+{"level":"warn","time":"2024-04-14T15:58:38.061+0800","lineNum":"global/redis.go:24","func":"file_upload/global.SetupRedisLink","message":"redis连接失败dial tcp 116.204.6.184:6379: i/o timeout"}
+{"level":"warn","time":"2024-04-16T09:11:12.268+0800","lineNum":"controller/file.go:68","func":"file_upload/app/controller.SaveFile","message":"redis: can't marshal map[string]interface {} (implement encoding.BinaryMarshaler)保存文件失败"}
+{"level":"warn","time":"2024-04-16T09:12:58.839+0800","lineNum":"controller/file.go:68","func":"file_upload/app/controller.SaveFile","message":"redis: can't marshal map[string]interface {} (implement encoding.BinaryMarshaler)保存文件失败"}
+{"level":"warn","time":"2024-04-16T11:17:36.064+0800","lineNum":"controller/file.go:136","func":"file_upload/app/controller.TemplateItem","message":"Mismatch type controller.File with value string \"at index 0: mismatched type with value\\n\\n\\t\\\"{\\\\\\\"type\\\\\\\":true,\\\\\\\"data\\\\\\\":{\\\\\\\"stat\\n\\t^...............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T11:17:54.491+0800","lineNum":"controller/file.go:136","func":"file_upload/app/controller.TemplateItem","message":"Mismatch type controller.File with value string \"at index 0: mismatched type with value\\n\\n\\t\\\"{\\\\\\\"type\\\\\\\":true,\\\\\\\"data\\\\\\\":{\\\\\\\"stat\\n\\t^...............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T11:18:33.403+0800","lineNum":"controller/file.go:136","func":"file_upload/app/controller.TemplateItem","message":"Mismatch type controller.File with value string \"at index 0: mismatched type with value\\n\\n\\t\\\"{\\\\\\\"type\\\\\\\":true,\\\\\\\"data\\\\\\\":{\\\\\\\"stat\\n\\t^...............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T11:29:34.619+0800","lineNum":"controller/file.go:136","func":"file_upload/app/controller.TemplateItem","message":"Mismatch type controller.File with value string \"at index 0: mismatched type with value\\n\\n\\t\\\"{\\\\\\\"type\\\\\\\":true,\\\\\\\"data\\\\\\\":{\\\\\\\"stat\\n\\t^...............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T11:36:41.629+0800","lineNum":"controller/file.go:136","func":"file_upload/app/controller.TemplateItem","message":"Mismatch type controller.File with value string \"at index 0: mismatched type with value\\n\\n\\t\\\"{\\\\\\\"type\\\\\\\":true,\\\\\\\"data\\\\\\\":{\\\\\\\"stat\\n\\t^...............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T11:37:41.180+0800","lineNum":"controller/file.go:137","func":"file_upload/app/controller.TemplateItem","message":"Mismatch type model.Root with value string \"at index 0: mismatched type with value\\n\\n\\t\\\"{\\\\\\\"type\\\\\\\":true,\\\\\\\"data\\\\\\\":{\\\\\\\"stat\\n\\t^...............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T11:38:54.719+0800","lineNum":"controller/file.go:133","func":"file_upload/app/controller.TemplateItem","message":"Mismatch type string with value bool \"at index 8: mismatched type with value\\n\\n\\t{\\\"type\\\":true,\\\"data\\\":{\\\"state\\\":{\\\"f\\n\\t........^.......................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:13:41.911+0800","lineNum":"controller/file.go:138","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:14:20.613+0800","lineNum":"controller/file.go:138","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:15:36.076+0800","lineNum":"controller/file.go:138","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:17:58.897+0800","lineNum":"controller/file.go:138","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:21:06.130+0800","lineNum":"controller/file.go:138","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:25:34.016+0800","lineNum":"controller/file.go:138","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:28:33.070+0800","lineNum":"controller/file.go:145","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:33:10.781+0800","lineNum":"controller/file.go:144","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:42:25.071+0800","lineNum":"controller/file.go:144","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T14:43:09.678+0800","lineNum":"controller/file.go:144","func":"file_upload/app/controller.TemplateItem","message":"\"Syntax error at index 3: invalid char\\n\\n\\t\\n\\nssh-rsa AAAAB3NzaC1yc2EAAAADAQ\\n\\t...^............................\\n\"序列化失败"}
+{"level":"warn","time":"2024-04-16T20:24:31.713+0800","lineNum":"global/redis.go:24","func":"file_upload/global.SetupRedisLink","message":"redis连接失败dial tcp 116.204.6.184:6379: connectex: A socket operation was attempted to an unreachable network."}
+{"level":"warn","time":"2024-04-17T09:41:59.882+0800","lineNum":"controller/file.go:65","func":"file_upload/app/controller.SaveFile","message":"invalid character 'o' looking for beginning of value获取参数失败"}
+{"level":"warn","time":"2024-04-17T09:45:20.379+0800","lineNum":"controller/file.go:65","func":"file_upload/app/controller.SaveFile","message":"invalid character 'o' looking for beginning of value获取参数失败"}
+{"level":"warn","time":"2024-04-17T10:10:49.232+0800","lineNum":"controller/file.go:163","func":"file_upload/app/controller.GetTemplate","message":"read tcp 192.168.11.29:54613->116.204.6.184:6379: i/o timeout获取文件失败"}
+{"level":"warn","time":"2024-04-17T14:30:22.609+0800","lineNum":"controller/file.go:119","func":"file_upload/app/controller.TemplateItem","message":"dial tcp 116.204.6.184:6379: connectex: A socket operation was attempted to an unreachable network.获取模板失败"}
+{"level":"warn","time":"2024-04-17T14:33:01.401+0800","lineNum":"controller/file.go:119","func":"file_upload/app/controller.TemplateItem","message":"dial tcp 116.204.6.184:6379: i/o timeout获取模板失败"}
+{"level":"warn","time":"2024-04-17T14:33:20.595+0800","lineNum":"controller/file.go:119","func":"file_upload/app/controller.TemplateItem","message":"dial tcp 116.204.6.184:6379: i/o timeout获取模板失败"}

+ 24 - 0
main.go

@@ -0,0 +1,24 @@
+package main
+
+import (
+	"context"
+	"file_upload/app"
+	"file_upload/global"
+	"file_upload/simple_zap"
+)
+
+func init() {
+	err := global.SetupSetting()
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(err)
+		return
+	}
+	global.SetupRedisLink()
+}
+func main() {
+	err := app.InitRouter()
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(err)
+		return
+	}
+}

+ 62 - 0
simple_zap/simple_zap.go

@@ -0,0 +1,62 @@
+package simple_zap
+
+import (
+	"context"
+	"go.uber.org/zap"
+	"go.uber.org/zap/zapcore"
+	"gopkg.in/natefinch/lumberjack.v2"
+)
+
+const loggerCtxKey = "baozhida"
+
+var Logger *zap.Logger
+
+func init() {
+	hook := lumberjack.Logger{
+		Filename:   "./log/app.log",
+		MaxSize:    1,
+		Compress:   true,
+		MaxAge:     30,
+		MaxBackups: 7,
+		LocalTime:  true,
+	}
+	encoder_config := zapcore.EncoderConfig{
+		MessageKey:     "message",
+		LevelKey:       "level",
+		TimeKey:        "time",
+		CallerKey:      "lineNum",
+		FunctionKey:    "func",
+		LineEnding:     zapcore.DefaultLineEnding,      // 回车符换行
+		EncodeLevel:    zapcore.LowercaseLevelEncoder,  // level小写: info,debug,warn等 而不是 Info, Debug,Warn等
+		EncodeTime:     zapcore.ISO8601TimeEncoder,     // 时间格式: "2006-01-02T15:04:05.000Z0700"
+		EncodeDuration: zapcore.SecondsDurationEncoder, // 时间戳用float64型,更加准确, 另一种是NanosDurationEncoder int64
+		EncodeCaller:   zapcore.ShortCallerEncoder,     // 产生日志文件的路径格式: 包名/文件名:行号
+	}
+	caller := zap.AddCaller()         //日志打印输出 文件名, 行号, 函数名
+	development := zap.Development()  // 可输出 dpanic, panic 级别的日志
+	field := zap.Fields()             // 负责给日志生成一个个 k-v 对
+	var syncers []zapcore.WriteSyncer // io writer
+	syncers = append(syncers, zapcore.AddSync(&hook))
+	atomic_level := zap.NewAtomicLevel()  // 设置日志 level
+	atomic_level.SetLevel(zap.DebugLevel) // 打印 debug, info, warn,eror, depanic,panic,fetal 全部级别日志
+	core := zapcore.NewCore(zapcore.NewJSONEncoder(encoder_config), zapcore.NewMultiWriteSyncer(syncers...), atomic_level)
+	Logger = zap.New(core, caller, development, field)
+
+}
+
+// NewCtx 给 ctx 注入一个 looger, logger 中包含Field(内含日志打印的 k-v对)
+func NewCtx(ctx context.Context, fields ...zapcore.Field) context.Context {
+	return context.WithValue(ctx, loggerCtxKey, WithCtx(ctx).With(fields...))
+}
+
+// WithCtx 尝试从 context 中获取带有 traceId Field的 logge
+func WithCtx(ctx context.Context) *zap.Logger {
+	if ctx == nil {
+		return Logger
+	}
+	ctx_logger, ok := ctx.Value(loggerCtxKey).(*zap.Logger)
+	if ok {
+		return ctx_logger
+	}
+	return Logger
+}

File diff suppressed because it is too large
+ 52 - 0
upload/cec.json


File diff suppressed because it is too large
+ 52 - 0
upload/sda.json


File diff suppressed because it is too large
+ 52 - 0
upload/sdasadas.json


File diff suppressed because it is too large
+ 52 - 0
upload/未命名sdsa.json


File diff suppressed because it is too large
+ 52 - 0
upload/皮卡丘.json


Some files were not shown because too many files changed in this diff