浏览代码

项目初始化

huangyan 8 月之前
当前提交
356a17fcce

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 9 - 0
.idea/bigdata_archives.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/bigdata_archives.iml" filepath="$PROJECT_DIR$/.idea/bigdata_archives.iml" />
+    </modules>
+  </component>
+</project>

+ 69 - 0
app/controller/systemsetting.go

@@ -0,0 +1,69 @@
+package controller
+
+import (
+	"bigdata_archives/app/e"
+	"bigdata_archives/app/model"
+	"bigdata_archives/app/service"
+	"github.com/gin-gonic/gin"
+	"github.com/go-playground/validator/v10"
+	"strconv"
+)
+
+var SystemSetting service.SystemSettings = &model.SystemSettings{}
+
+// GetSystemSetting 获取系统设置
+func GetSystemSetting(c *gin.Context) {
+	settings, rescode := SystemSetting.GetSystemSettings()
+	if rescode != e.SUCCESS {
+		e.ResponseWithMsg(c, rescode, "获取系统设置失败")
+		return
+	}
+	e.ResponseSuccess(c, settings)
+}
+
+// CreateSystem 创建系统设置
+func CreateSystem(c *gin.Context) {
+	var system model.SystemSettings
+	if err := c.ShouldBindJSON(&system); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	settings, rescode := SystemSetting.CreateSystemSettings(system)
+	if rescode != e.SUCCESS {
+		e.ResponseWithMsg(c, rescode, "创建系统设置失败")
+		return
+	}
+	e.ResponseSuccess(c, settings)
+}
+
+// UpdateSystem 更新系统设置
+func UpdateSystem(c *gin.Context) {
+	var system model.SystemSettings
+	if err := c.ShouldBindJSON(&system); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	settings, rescode := SystemSetting.UpdateSystemSettings(system)
+	if rescode != e.SUCCESS {
+		e.ResponseWithMsg(c, rescode, "更新系统设置失败")
+		return
+	}
+	e.ResponseSuccess(c, settings)
+}
+
+// DeleteSystem 删除系统设置
+func DeleteSystem(c *gin.Context) {
+	value := c.Query("id")
+	id, _ := strconv.Atoi(value)
+	err := validator.New().Var(id, "required")
+	if err != nil {
+		e.ResponseWithMsg(c, e.CheckRequired, e.CheckRequired.GetMsg())
+		return
+	}
+	settings, rescode := SystemSetting.DeleteSystemSettings(id)
+	if rescode != e.SUCCESS {
+		e.ResponseWithMsg(c, rescode, "删除系统设置失败")
+		return
+	}
+	e.ResponseSuccess(c, settings)
+}

+ 124 - 0
app/controller/usercontroller.go

@@ -0,0 +1,124 @@
+package controller
+
+import (
+	"bigdata_archives/app/e"
+	"bigdata_archives/app/model"
+	"bigdata_archives/app/service"
+	"bigdata_archives/unity"
+	"bigdata_archives/utils"
+	"github.com/gin-gonic/gin"
+	"github.com/go-playground/validator/v10"
+	"strconv"
+)
+
+var users service.UserService = &model.User{}
+
+// Login @Summary 用户登录
+func Login(c *gin.Context) {
+	var user model.User
+	if err := c.ShouldBindJSON(&user); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	} else {
+		validate := validator.New()
+		if err := validate.Struct(user); err != nil {
+			e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+			return
+		}
+		login, rescode := users.Login(user.Account, user.Password)
+		if rescode == e.SUCCESS {
+			e.ResponseSuccess(c, login)
+			return
+		}
+		e.ResponseWithMsg(c, rescode, rescode.GetMsg())
+		return
+	}
+}
+
+// AddUser @Summary 添加用户
+func AddUser(c *gin.Context) {
+	var user model.User
+	if err := c.ShouldBindJSON(&user); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	} else {
+		validate := validator.New()
+		if err := validate.Struct(user); err != nil {
+			e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+			return
+		}
+		addUser, rescode := users.AddUser(user)
+		if rescode == e.SUCCESS {
+			e.ResponseSuccess(c, addUser)
+			return
+		}
+		e.ResponseWithMsg(c, rescode, rescode.GetMsg())
+	}
+}
+
+// UserList @Summary 用户列表
+func UserList(c *gin.Context) {
+	var params unity.QueryPageParams
+	if err := c.ShouldBindJSON(&params); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	result, total, err := unity.PaginateWithCondition(params, model.User{}, nil)
+	if err != nil {
+		e.ResponseWithMsg(c, e.PaginationFailed, e.PaginationFailed.GetMsg())
+		return
+	}
+	e.ResPonsePage(c, result, total, params)
+}
+
+// GetUserById @Summary 根据id获取用户
+func GetUserById(c *gin.Context) {
+	value := c.Query("id")
+	atoi, _ := strconv.Atoi(value)
+	err := validator.New().Var(atoi, "required")
+	if err != nil {
+		e.ResponseWithMsg(c, e.CheckRequired, e.CheckRequired.GetMsg())
+		return
+	}
+	id, rescode := users.GetUserById(atoi)
+	if rescode == e.SUCCESS {
+		e.ResponseSuccess(c, id)
+		return
+	}
+	e.ResponseWithMsg(c, rescode, rescode.GetMsg())
+}
+
+// DeleteUser @Summary 删除用户
+func DeleteUser(c *gin.Context) {
+	var user model.User
+	err := c.ShouldBindJSON(&user)
+	if err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	id, err := unity.DeleteById(user.ID, user)
+	if err != nil {
+		e.ResponseWithMsg(c, e.DELETEFAIL, e.DELETEFAIL.GetMsg())
+		return
+	}
+	e.ResponseSuccess(c, id)
+}
+
+// UpdateUserById @Summary 修改用户
+func UpdateUserById(c *gin.Context) {
+	var user model.User
+	if err := c.ShouldBindJSON(&user); err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	if user.Password != "" {
+		md5 := utils.MD5(user.Password)
+		user.Password = md5
+	}
+	id, err := unity.UpdateById(user.ID, user)
+	if err != nil {
+		e.ResponseWithMsg(c, e.UPDATEFAIL, e.UPDATEFAIL.GetMsg())
+		return
+	}
+	e.ResponseSuccess(c, id)
+}

+ 47 - 0
app/e/R.go

@@ -0,0 +1,47 @@
+package e
+
+import (
+	"bigdata_archives/unity"
+	"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,
+	})
+}
+func ResPonsePage(c *gin.Context, data interface{}, total int64, params unity.QueryPageParams) {
+	c.JSON(http.StatusOK, &R{
+		Code:    SUCCESS,
+		Message: SUCCESS.GetMsg(),
+		Data: gin.H{
+			"result":    data,
+			"total":     total,
+			"current":   params.Page,
+			"page_size": params.Size,
+		},
+	})
+}

+ 75 - 0
app/e/code_msg.go

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

+ 20 - 0
app/middleware/admin_middleware.go

@@ -0,0 +1,20 @@
+package middlewares
+
+import (
+	"bigdata_archives/app/e"
+	"bigdata_archives/utils"
+	"github.com/gin-gonic/gin"
+)
+
+func AdminMiddleware() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		header := c.GetHeader("Authorization")
+		_, recode := utils.ParseToken(header)
+		if recode != e.SUCCESS {
+			e.ResponseWithMsg(c, recode, recode.GetMsg())
+			c.Abort()
+		} else {
+			c.Next()
+		}
+	}
+}

+ 24 - 0
app/middleware/cors.go

@@ -0,0 +1,24 @@
+package middlewares
+
+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()
+	}
+}

+ 64 - 0
app/model/system_settings.go

@@ -0,0 +1,64 @@
+package model
+
+import (
+	"bigdata_archives/app/e"
+	"bigdata_archives/global"
+	"bigdata_archives/utils"
+	"log"
+)
+
+type SystemSettings struct {
+	utils.BaseModel
+	Title string `json:"title"`
+}
+
+func (*SystemSettings) TableName() string {
+	return "system_settings"
+}
+func (s SystemSettings) GetSystemSettings() (SystemSettings, e.Rescode) {
+	//TODO implement me
+	tx := global.DBLink.First(&s)
+	if tx.Error == nil && tx.RowsAffected > 0 {
+		return s, e.SUCCESS
+	}
+	return s, e.TheSystemIsAbnormal
+}
+func (s *SystemSettings) UpdateSystemSettings(systemSettings SystemSettings) (SystemSettings, e.Rescode) {
+	//TODO implement me
+	tx := global.DBLink.Where("id = ?", systemSettings.ID).Updates(systemSettings)
+	if tx.Error == nil && tx.RowsAffected > 0 {
+		return systemSettings, e.SUCCESS
+	}
+	return systemSettings, e.UPDATEFAIL
+}
+
+func (s *SystemSettings) CreateSystemSettings(systemSettings SystemSettings) (SystemSettings, e.Rescode) {
+	//TODO implement me
+	tx := global.DBLink.Create(&systemSettings)
+	if tx.Error == nil && tx.RowsAffected > 0 {
+		return systemSettings, e.SUCCESS
+	}
+	return systemSettings, e.CreateFailed
+}
+
+func (s *SystemSettings) DeleteSystemSettings(id int) (SystemSettings, e.Rescode) {
+	//TODO implement me
+	tx := global.DBLink.Where("id = ?", id).Delete(s)
+	if tx.Error == nil && tx.RowsAffected > 0 {
+		return *s, e.SUCCESS
+	}
+	return *s, e.DELETEFAIL
+}
+func CreateSystemSettings() {
+	var setting = SystemSettings{}
+	var count int64
+	global.DBLink.Table("system_settings").Where("id = ?", "1").Count(&count)
+	if count == 0 {
+		setting.Title = "可视化管理平台"
+		create := global.DBLink.Create(&setting)
+		if create.Error == nil && create.RowsAffected > 0 {
+			log.Println("创建系统设置成功")
+		}
+	}
+
+}

+ 124 - 0
app/model/user.go

@@ -0,0 +1,124 @@
+package model
+
+import (
+	"bigdata_archives/app/e"
+	"bigdata_archives/global"
+	"bigdata_archives/unity"
+	"bigdata_archives/utils"
+	"database/sql/driver"
+	"encoding/json"
+	"fmt"
+	"log"
+)
+
+type User struct {
+	utils.BaseModel
+	Account  string `json:"account" validate:"required"`
+	Password string `json:"password" validate:"required"`
+	State    *int   `json:"state"`
+	Menu     Menus  `gorm:"type:json" json:"menu"`
+}
+
+type UserDto struct {
+	User
+	Token string `json:"token"`
+}
+
+func (*User) TableName() string {
+	return "user"
+}
+
+type Menus []string
+
+func (lo Menus) Value() (driver.Value, error) {
+	return json.Marshal(lo)
+}
+
+func (fn *Menus) Scan(src interface{}) error {
+	if src == nil {
+		*fn = make(Menus, 0)
+		return nil
+	}
+	var u []byte
+	switch v := src.(type) {
+	case string:
+		u = []byte(v)
+	case []byte:
+		u = v
+	default:
+		return fmt.Errorf("unsupported type: %T", src)
+	}
+	return json.Unmarshal(u, (*[]string)(fn))
+}
+
+// Login 登录
+func (u *User) Login(userName, password string) (UserDto, e.Rescode) {
+	//TODO implement me
+	md5 := utils.MD5(password)
+	tx := global.DBLink.Where("account = ?", userName).Where("password = ?", md5).Where("state = ?", 1).First(&u)
+	if tx.Error != nil {
+		return UserDto{}, e.AccountAndPasswordIsWrong
+	}
+	if tx.RowsAffected > 0 {
+		token, err := utils.CreateToken(u.ID, u.Account, "user")
+		if err != nil {
+			return UserDto{}, e.TheUserAlreadyExists
+		}
+		var userDto = UserDto{}
+		userDto.Token = token
+		return userDto, e.SUCCESS
+	}
+	return UserDto{}, e.LoginFailed
+}
+
+// CreateAdmin 创建管理员
+func CreateAdmin() {
+	var user = User{}
+	var count int64
+	global.DBLink.Table("user").Where("account = ?", "admin").Count(&count)
+	if count == 0 {
+		user.Account = "admin"
+		user.Menu = []string{"*"}
+		if user.State == nil {
+			user.State = new(int)
+			*user.State = 1
+		}
+		md5 := utils.MD5("123456")
+		user.Password = md5
+		create := global.DBLink.Create(&user)
+		if create.Error == nil && create.RowsAffected > 0 {
+			log.Println("管理员创建成功")
+		}
+	}
+}
+
+// AddUser 添加用户
+func (u *User) AddUser(user User) (User, e.Rescode) {
+	//TODO implement me
+	md5 := utils.MD5(user.Password)
+	user.Password = md5
+	if user.State == nil {
+		user.State = new(int)
+		*user.State = 1
+	}
+	tx := global.DBLink.Create(&user)
+	if tx.Error != nil && tx.RowsAffected == 0 {
+		return User{}, e.CreateFailed
+	} else {
+		return user, e.SUCCESS
+	}
+}
+func (u *User) GetUser(params unity.QueryPageParams) ([]User, e.Rescode) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (u *User) GetUserById(id int) (User, e.Rescode) {
+	//TODO implement me
+	var user User
+	tx := global.DBLink.Where("id = ?", id).First(&user)
+	if tx.Error == nil && tx.RowsAffected > 0 {
+		return user, e.SUCCESS
+	}
+	return User{}, e.TheUserIsEmpty
+}

+ 23 - 0
app/router.go

@@ -0,0 +1,23 @@
+package app
+
+import (
+	middlewares "bigdata_archives/app/middleware"
+	"bigdata_archives/app/routers"
+	"bigdata_archives/global"
+	"github.com/gin-gonic/gin"
+)
+
+func InitRouter() error {
+	engine := gin.New()
+	gin.SetMode(global.ServerSetting.Mode)
+	engine.Use(middlewares.Cors())
+	//配置前端静态资源
+	engine.StaticFile("/", "./frontend/dist/index.html")
+	engine.Static("/assets", "./frontend/dist/assets")
+	engine.Static("/libs", "./frontend/dist/libs")
+	engine.StaticFile("/favicon.ico", "./frontend/dist/favicon.ico")
+	routers.UserRouter(engine)
+	engine.Use(middlewares.AdminMiddleware())
+	routers.SystemRouter(engine)
+	return engine.Run(global.ServerSetting.Port)
+}

+ 14 - 0
app/routers/system.go

@@ -0,0 +1,14 @@
+package routers
+
+import (
+	"bigdata_archives/app/controller"
+	"github.com/gin-gonic/gin"
+)
+
+func SystemRouter(r *gin.Engine) {
+	group := r.Group("/api")
+	group.GET("/setting", controller.GetSystemSetting)
+	group.POST("/setting", controller.CreateSystem)
+	group.PUT("/setting", controller.UpdateSystem)
+	group.DELETE("/setting", controller.DeleteSystem)
+}

+ 17 - 0
app/routers/usersrouter.go

@@ -0,0 +1,17 @@
+package routers
+
+import (
+	"bigdata_archives/app/controller"
+	middlewares "bigdata_archives/app/middleware"
+	"github.com/gin-gonic/gin"
+)
+
+func UserRouter(r *gin.Engine) {
+	group := r.Group("/api")
+	group.POST("/login", controller.Login)
+	group.POST("/user", controller.AddUser).Use(middlewares.AdminMiddleware())
+	group.POST("/userlist", controller.UserList).Use(middlewares.AdminMiddleware())
+	group.GET("/getuser", controller.GetUserById).Use(middlewares.AdminMiddleware())
+	group.DELETE("/user", controller.DeleteUser).Use(middlewares.AdminMiddleware())
+	group.PUT("/user", controller.UpdateUserById).Use(middlewares.AdminMiddleware())
+}

+ 13 - 0
app/service/systemSettings.go

@@ -0,0 +1,13 @@
+package service
+
+import (
+	"bigdata_archives/app/e"
+	"bigdata_archives/app/model"
+)
+
+type SystemSettings interface {
+	GetSystemSettings() (model.SystemSettings, e.Rescode)
+	UpdateSystemSettings(systemSettings model.SystemSettings) (model.SystemSettings, e.Rescode)
+	CreateSystemSettings(systemSettings model.SystemSettings) (model.SystemSettings, e.Rescode)
+	DeleteSystemSettings(id int) (model.SystemSettings, e.Rescode)
+}

+ 18 - 0
app/service/user_service.go

@@ -0,0 +1,18 @@
+package service
+
+import (
+	"bigdata_archives/app/e"
+	"bigdata_archives/app/model"
+	"bigdata_archives/unity"
+)
+
+type UserService interface {
+	// Login 账号密码登录
+	Login(userName, password string) (model.UserDto, e.Rescode)
+	// AddUser 添加用户
+	AddUser(user model.User) (model.User, e.Rescode)
+	// GetUser 获取用户
+	GetUser(params unity.QueryPageParams) ([]model.User, e.Rescode)
+	// GetUserById 根据id获取用户
+	GetUserById(id int) (model.User, e.Rescode)
+}

+ 45 - 0
configs/config.yaml

@@ -0,0 +1,45 @@
+database:
+  # 数据库类型
+  dialect: mysql
+  # host地址
+  host: 127.0.0.1
+  # 端口
+  port: 3306
+  # 数据库名称
+  db: bigdata_archives
+  # 数据库用户名
+  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: "192.168.0.100:6379"
+  password: ""
+  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
+}

+ 13 - 0
database/migrate.go

@@ -0,0 +1,13 @@
+package database
+
+import (
+	"bigdata_archives/app/model"
+	"gorm.io/gorm"
+)
+
+func Migrate(db *gorm.DB) {
+	db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(
+		model.User{},
+		model.SystemSettings{},
+	)
+}

+ 34 - 0
global/db.go

@@ -0,0 +1,34 @@
+package global
+
+import (
+	"fmt"
+	"gorm.io/driver/mysql"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+)
+
+var (
+	DBLink *gorm.DB
+)
+
+func SetupDBLink() error {
+	var err error
+	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?%s",
+		DatabaseSetting.UserName,
+		DatabaseSetting.Password,
+		DatabaseSetting.Host,
+		DatabaseSetting.Db,
+		DatabaseSetting.OtherParams,
+	)
+	DBLink, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
+		DisableForeignKeyConstraintWhenMigrating: true,
+		Logger:                                   logger.Default.LogMode(logger.Info),
+	})
+	if err != nil {
+		return err
+	}
+	//DBLink.SingularTable(true)
+	//DBLink.DB().SetMaxIdleConns(DatabaseSetting.MaxIdleConn)
+	//DBLink.DB().SetMaxOpenConns(DatabaseSetting.MaxOpenConn)
+	return nil
+}

+ 24 - 0
global/redis.go

@@ -0,0 +1,24 @@
+package global
+
+import (
+	"bigdata_archives/simple_zap"
+	"context"
+	"fmt"
+	"github.com/go-redis/redis/v8"
+)
+
+var Rdb *redis.Client
+
+func SetupRedisLink() {
+	Rdb = redis.NewClient(&redis.Options{
+		Addr:     RedisSetting.Addr,
+		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 "bigdata_archives/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
+}

+ 63 - 0
go.mod

@@ -0,0 +1,63 @@
+module bigdata_archives
+
+go 1.21
+
+require (
+	github.com/bytedance/sonic v1.11.6
+	github.com/gin-gonic/gin v1.10.0
+	github.com/go-playground/locales v0.14.1
+	github.com/go-playground/universal-translator v0.18.1
+	github.com/go-playground/validator/v10 v10.20.0
+	github.com/go-redis/redis/v8 v8.11.5
+	github.com/go-resty/resty/v2 v2.13.1
+	github.com/spf13/viper v1.19.0
+	go.uber.org/zap v1.27.0
+	gopkg.in/natefinch/lumberjack.v2 v2.2.1
+	gorm.io/driver/mysql v1.5.7
+	gorm.io/gorm v1.25.11
+)
+
+require (
+	github.com/bytedance/sonic/loader v0.1.1 // indirect
+	github.com/cespare/xxhash/v2 v2.1.2 // indirect
+	github.com/cloudwego/base64x v0.1.4 // indirect
+	github.com/cloudwego/iasm v0.2.0 // 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-sql-driver/mysql v1.7.0 // indirect
+	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
+	github.com/hashicorp/hcl v1.0.0 // indirect
+	github.com/jinzhu/inflection v1.0.0 // indirect
+	github.com/jinzhu/now v1.1.5 // 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/pelletier/go-toml/v2 v2.2.2 // 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.8.0 // indirect
+	golang.org/x/crypto v0.23.0 // indirect
+	golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
+	golang.org/x/net v0.25.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
+	golang.org/x/text v0.15.0 // indirect
+	google.golang.org/protobuf v1.34.1 // indirect
+	gopkg.in/ini.v1 v1.67.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)

+ 206 - 0
go.sum

@@ -0,0 +1,206 @@
+github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
+github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
+github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
+github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
+github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
+github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
+github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
+github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
+github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
+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.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
+github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
+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.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
+github.com/go-playground/validator/v10 v10.20.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/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g=
+github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0=
+github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
+github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+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/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/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/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
+github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+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/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/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.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
+github.com/pelletier/go-toml/v2 v2.2.2/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.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
+github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
+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=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+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.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
+golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+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/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
+golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
+google.golang.org/protobuf v1.34.1/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-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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=
+gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
+gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
+gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
+gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
+nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

+ 36 - 0
main.go

@@ -0,0 +1,36 @@
+package main
+
+import (
+	"bigdata_archives/app"
+	"bigdata_archives/app/model"
+	"bigdata_archives/database"
+	"bigdata_archives/global"
+	"bigdata_archives/simple_zap"
+	"context"
+)
+
+func init() {
+	// 初始化配置
+	err := global.SetupSetting()
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "初始化配置失败")
+	}
+	// 初始化数据库连接
+	err = global.SetupDBLink()
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "初始化数据库连接失败")
+	}
+	// 迁移数据库
+	database.Migrate(global.DBLink)
+	//创建管理员用户
+	model.CreateAdmin()
+	//初始化系统设置
+	model.CreateSystemSettings()
+
+}
+func main() {
+	err := app.InitRouter()
+	if err != nil {
+		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "初始化路由失败")
+	}
+}

+ 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
+}

+ 16 - 0
unity/getuid.go

@@ -0,0 +1,16 @@
+package unity
+
+import (
+	"github.com/gin-gonic/gin"
+)
+
+func GetUId(c *gin.Context) int {
+	//mustGet := c.MustGet("user")
+	value, exists := c.Get("user")
+	if exists {
+		users := value.(map[string]interface{})
+		id := int(users["ID"].(float64))
+		return id
+	}
+	return 0
+}

+ 17 - 0
unity/randomId.go

@@ -0,0 +1,17 @@
+package unity
+
+import (
+	"math/rand"
+	"time"
+)
+
+func RandomId() string {
+	const letterBytes = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	rand.Seed(time.Now().UnixNano())
+
+	b := make([]byte, 32)
+	for i := range b {
+		b[i] = letterBytes[rand.Intn(len(letterBytes))]
+	}
+	return string(b)
+}

+ 120 - 0
unity/unity.go

@@ -0,0 +1,120 @@
+package unity
+
+import (
+	"bigdata_archives/global"
+	"errors"
+)
+
+type PageParams struct {
+	Page int    `json:"page" form:"page"`
+	Size int    `json:"size" form:"size"`
+	Desc string `json:"desc" form:"desc"`
+}
+type QueryPageParams struct {
+	Page  int    `json:"page" form:"page"`
+	Size  int    `json:"size" form:"size"`
+	Query string `json:"query" form:"query"`
+	Desc  string `json:"desc" form:"desc"`
+}
+
+// Paginate 使用给定的DB连接执行分页查询
+func Paginate[T any](params PageParams, model T) (result []T, total int64, current int, err error) {
+	var count int64
+	if err = global.DBLink.Model(model).Count(&count).Error; err != nil {
+		return nil, 0, 0, err
+	}
+
+	// 计算总页数
+	//	totalPages := int(math.Ceil(float64(count) / float64(params.Size)))
+	// 计算偏移量并设置分页大小
+	offset := (params.Page - 1) * params.Size
+	// 执行实际分页查询
+	if err = global.DBLink.Offset(offset).Limit(params.Size).Order(params.Desc).Find(&result).Error; err != nil {
+		return nil, 0, 0, err
+	}
+	return result, count, params.Page, nil
+}
+
+func PaginateWithCondition[T any](params QueryPageParams, model T, queryCond interface{}) (result []T, total int64, err error) {
+	var count int64
+	if queryCond != nil {
+		if err = global.DBLink.Model(model).Where(queryCond, params.Query).Count(&count).Error; err != nil {
+			return nil, 0, err
+		}
+		// 计算查询的偏移量,并设置每次查询的记录数量
+		offset := (params.Page - 1) * params.Size
+		// 执行分页查询,包括偏移量设置、限制查询数量、排序及应用额外查询条件
+		if err = global.DBLink.Offset(offset).Limit(params.Size).Order(params.Desc).Where(queryCond, params.Query).Find(&result).Error; err != nil {
+			return nil, 0, err
+		}
+	} else {
+		if err = global.DBLink.Model(model).Count(&count).Error; err != nil {
+			return nil, 0, err
+		}
+		// 计算查询的偏移量,并设置每次查询的记录数量
+		offset := (params.Page - 1) * params.Size
+		// 执行分页查询,包括偏移量设置、限制查询数量、排序及应用额外查询条件
+		if err = global.DBLink.Offset(offset).Limit(params.Size).Order(params.Desc).Find(&result).Error; err != nil {
+			return nil, 0, err
+		}
+	}
+	return result, count, nil
+}
+
+func AddGenericItem[T any](item T, mapper func(T) interface{}) error {
+	dbModel := mapper(item)
+	if err := global.DBLink.Create(dbModel).Error; err != nil {
+		return err
+	}
+	return nil
+}
+
+// GetById 根据id查询
+func GetById[T any](id int, model T) (T, error) {
+	tx := global.DBLink.Where("id = ?", id).First(&model)
+	if tx.RowsAffected <= 0 {
+		return model, errors.New("查询失败,当前id不存在")
+	} else {
+		return model, nil
+	}
+}
+
+// UpdateById 根据id进行修改
+func UpdateById[T any](id uint, model T) (T, error) {
+	tx := global.DBLink.Where("id = ?", id).Updates(&model)
+	if tx.RowsAffected > 0 {
+		return model, nil
+	} else {
+		return model, errors.New("修改失败当前id不存在")
+	}
+}
+
+// Add 添加
+func Add[T any](model T) (T, error) {
+	tx := global.DBLink.Create(&model)
+	if tx.RowsAffected > 0 {
+		return model, nil
+	} else {
+		return model, errors.New("添加失败")
+	}
+}
+
+// DeleteById 根据id删除
+func DeleteById[T any](id uint, model T) (T, error) {
+	tx := global.DBLink.Where("id = ?", id).Delete(&model)
+	if tx.RowsAffected > 0 {
+		return model, nil
+	} else {
+		return model, errors.New("删除失败当前id不存在")
+	}
+}
+
+// QueryAll 获取所有信息
+func QueryAll(table string) ([]any, error) {
+	var result []any
+	tx := global.DBLink.Table(table).Find(&result)
+	if tx.Error != nil {
+		return result, errors.New("查询失败")
+	}
+	return result, nil
+}

+ 39 - 0
unity/zh_cn.go

@@ -0,0 +1,39 @@
+package unity
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin/binding"
+	"github.com/go-playground/locales/en"
+	"github.com/go-playground/locales/zh"
+	ut "github.com/go-playground/universal-translator"
+	"github.com/go-playground/validator/v10"
+	enTranslations "github.com/go-playground/validator/v10/translations/en"
+	chTranslations "github.com/go-playground/validator/v10/translations/zh"
+)
+
+var Trans ut.Translator
+
+func Translator(local string) (err error) {
+	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+		zhT := zh.New()
+		enT := en.New()
+		uni := ut.New(enT, zhT, enT)
+		var o bool
+		Trans, o = uni.GetTranslator(local)
+		if !o {
+			return fmt.Errorf("uni.GetTranslator(%s) failed", local)
+		}
+		//register translate
+		// 注册翻译器
+		switch local {
+		case "en":
+			err = enTranslations.RegisterDefaultTranslations(v, Trans)
+		case "zh":
+			err = chTranslations.RegisterDefaultTranslations(v, Trans)
+		default:
+			err = enTranslations.RegisterDefaultTranslations(v, Trans)
+		}
+		return
+	}
+	return
+}

+ 47 - 0
utils/create_code.go

@@ -0,0 +1,47 @@
+package utils
+
+import (
+	"bigdata_archives/app/e"
+	"bigdata_archives/global"
+	"context"
+	"fmt"
+	"go.uber.org/zap"
+	"math/rand"
+	"time"
+)
+
+func CreatCode() string {
+	const chars = "0123456789"
+	result := make([]byte, 6)
+	rand.Seed(time.Now().UnixNano())
+	for i := range result {
+		index := rand.Intn(len(chars))
+		result[i] = chars[index]
+	}
+	return string(result)
+}
+
+func SendModel(phone string) e.Rescode {
+	ctx := context.Background()
+	ss := NewSMS(global.SubMailSetting.Appid, global.SubMailSetting.Signature)
+	result, err := global.Rdb.Exists(ctx, phone).Result()
+	if result == 1 {
+		fmt.Println("验证码已经发送", zap.Error(err))
+		return e.HasSend
+	}
+	if err != nil {
+		fmt.Println("redis查询出现异常", zap.Error(err))
+		return e.TheSystemIsAbnormal
+	}
+	code := CreatCode()
+	content := fmt.Sprintf("【冷链智控系统】您的短信验证码:%s,请在5分钟内输入", code)
+	res, err := ss.Send(phone, content)
+	if err != nil || res.Status != SUCCESS {
+		fmt.Println("发送短信验证码出现异常", zap.Any("res", res), zap.Error(err))
+		return e.AnExceptionOccursWhenSendingAnSMSVerificationCode
+	} else {
+		//验证码装入redis并且设置过期时间
+		err = global.Rdb.Set(ctx, phone, code, 300*time.Second).Err()
+		return e.SUCCESS
+	}
+}

+ 59 - 0
utils/create_token.go

@@ -0,0 +1,59 @@
+package utils
+
+import (
+	"bigdata_archives/app/e"
+	"bigdata_archives/global"
+	"errors"
+	"github.com/golang-jwt/jwt/v4"
+	"time"
+)
+
+type MyClaims struct {
+	UserId   uint   `json:"user_id"`
+	UserName string `json:"user_name"`
+	Role     string `json:"role"`
+	jwt.RegisteredClaims
+}
+
+const TokenExpireDuration = time.Hour * 72
+
+func CreateToken(userId uint, userName, role string) (string, error) {
+	claims := MyClaims{
+		UserId:   userId,
+		UserName: userName,
+		Role:     role,
+		RegisteredClaims: jwt.RegisteredClaims{
+			ExpiresAt: jwt.NewNumericDate(time.Now().Add(TokenExpireDuration)),
+			Issuer:    global.JwtSetting.Issuer,
+		},
+	}
+	var mySerect = []byte(global.JwtSetting.Secret)
+	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+	return token.SignedString(mySerect)
+}
+func ParseToken(tokenStr string) (*MyClaims, e.Rescode) {
+	// 使用全局配置中的密钥对token进行解析。
+	var mySecret = []byte(global.JwtSetting.Secret)
+	// 尝试解析并验证JWT令牌。
+	claims := new(MyClaims)
+	token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
+		return mySecret, nil
+	})
+
+	if err != nil {
+		if errors.Is(err, jwt.ErrSignatureInvalid) || errors.Is(err, jwt.ErrInvalidKey) {
+			return nil, e.TokenIsInvalid
+		} else if ve, ok := err.(*jwt.ValidationError); ok && ve.Errors&jwt.ValidationErrorExpired != 0 {
+			return nil, e.TokenIsExpired
+		}
+		return nil, e.TokenIsInvalid
+	}
+
+	// 验证令牌是否有效。
+	if !token.Valid {
+		return nil, e.TokenIsInvalid
+	}
+
+	// 如果令牌有效,则返回解析出的声明信息。
+	return claims, e.SUCCESS
+}

+ 13 - 0
utils/md5.go

@@ -0,0 +1,13 @@
+package utils
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+)
+
+func MD5(password string) string {
+	bytes := []byte(password)
+	sum := md5.Sum(bytes)
+	toString := hex.EncodeToString(sum[:])
+	return toString
+}

+ 55 - 0
utils/sms.go

@@ -0,0 +1,55 @@
+package utils
+
+import (
+	"encoding/json"
+	"github.com/go-resty/resty/v2"
+)
+
+const (
+	SUCCESS = "success"
+)
+
+type SMS struct {
+	Appid     string
+	Signature string
+}
+
+func NewSMS(appid, signature string) *SMS {
+	return &SMS{
+		Appid:     appid,
+		Signature: signature,
+	}
+}
+
+type SendRes struct {
+	Status  string `json:"status"`
+	Send_id string `json:"send_id"`
+	Fee     int    `json:"fee"`
+	Msg     string `json:"msg"`
+	Code    int    `json:"code"`
+}
+
+// Send 短信发送
+func (t *SMS) Send(to, content string) (SendRes, error) {
+	client := resty.New()
+	resp, err := client.R().
+		SetHeader("Content-Type", "application/x-www-form-urlencoded").
+		SetFormData(map[string]string{
+			"appid":     t.Appid,
+			"signature": t.Signature,
+			"to":        to,
+			"content":   content,
+		}).
+		SetResult(&SendRes{}).
+		Post("https://api-v4.mysubmail.com/sms/send.json")
+
+	if err != nil {
+		return SendRes{}, err
+	}
+
+	temp := SendRes{}
+	if err = json.Unmarshal(resp.Body(), &temp); err != nil {
+		return SendRes{}, err
+	}
+	return temp, nil
+}

+ 70 - 0
utils/time.go

@@ -0,0 +1,70 @@
+package utils
+
+import (
+	"database/sql/driver"
+	"fmt"
+	"time"
+)
+
+const timeFormat = "2006-01-02 15:04:05"
+const timezone = "Asia/Shanghai"
+
+// Time 全局定义
+type Time time.Time
+
+func (t Time) MarshalJSON() ([]byte, error) {
+	b := make([]byte, 0, len(timeFormat)+2)
+	if time.Time(t).IsZero() {
+		b = append(b, '"')
+		b = append(b, '"')
+		return b, nil
+	}
+
+	b = append(b, '"')
+	b = time.Time(t).AppendFormat(b, timeFormat)
+	b = append(b, '"')
+	return b, nil
+}
+
+func (t *Time) UnmarshalJSON(data []byte) (err error) {
+	now, err := time.ParseInLocation(`"`+timeFormat+`"`, string(data), time.Local)
+	*t = Time(now)
+	return
+}
+
+func (t Time) String() string {
+	if time.Time(t).IsZero() {
+		return ""
+	}
+	return time.Time(t).Format(timeFormat)
+}
+
+func (t Time) Local() time.Time {
+	loc, _ := time.LoadLocation(timezone)
+	return time.Time(t).In(loc)
+}
+
+func (t Time) Value() (driver.Value, error) {
+	var zeroTime time.Time
+	var ti = time.Time(t)
+	if ti.UnixNano() == zeroTime.UnixNano() {
+		return nil, nil
+	}
+	return ti, nil
+}
+
+func (t *Time) Scan(v interface{}) error {
+	value, ok := v.(time.Time)
+	if ok {
+		*t = Time(value)
+		return nil
+	}
+	return fmt.Errorf("can not convert %v to timestamp", v)
+}
+
+type BaseModel struct {
+	ID        uint `gorm:"primary_key" json:"id"`
+	CreatedAt Time
+	UpdatedAt Time
+	DeletedAt *Time `sql:"index"`
+}