✨ 完成基础脚手架
This commit is contained in:
parent
632c76dfa6
commit
5fd8e0a694
7
.env
Normal file
7
.env
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Nacos配置
|
||||||
|
NACOS_HOST=127.0.0.1
|
||||||
|
NACOS_PORT=8848
|
||||||
|
# 命名空间,用默认的public的话这儿就不写
|
||||||
|
NACOS_NAMESPACE=c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a
|
||||||
|
# 除本文件以外的其他托管到Nacos的配置文件 Ps. 后面可以把NACOS_*和系统启动相关的留着,其他的全部托管到Nacos
|
||||||
|
NACOS_CONFIG_NAME=vp.yaml
|
18
api/admin/user.go
Normal file
18
api/admin/user.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ginDemo/core"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type userApi struct{}
|
||||||
|
|
||||||
|
// UserApi 角色接口工厂函数
|
||||||
|
func UserApi() *userApi {
|
||||||
|
return &userApi{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUser 获取当前登录用户信息
|
||||||
|
func (u userApi) GetUser(ctx *gin.Context) {
|
||||||
|
core.R(ctx).OkWithData("Lee")
|
||||||
|
}
|
31
client/mysql.go
Normal file
31
client/mysql.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ginDemo/config"
|
||||||
|
"gitee.ltd/lxh/logger"
|
||||||
|
"gorm.io/driver/mysql"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
var MySQL *gorm.DB
|
||||||
|
|
||||||
|
func InitMySQLClient() {
|
||||||
|
// 创建连接对象
|
||||||
|
mysqlConfig := mysql.Config{
|
||||||
|
DSN: config.Scd.MySQL.GetDSN(),
|
||||||
|
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式
|
||||||
|
DontSupportRenameColumn: true, // 用 `change` 重命名列
|
||||||
|
}
|
||||||
|
conn, err := gorm.Open(mysql.New(mysqlConfig), &gorm.Config{Logger: logger.DefaultGormLogger()})
|
||||||
|
if err != nil {
|
||||||
|
logger.Say.Panic("初始化MySQL连接失败, 错误信息: %v", err)
|
||||||
|
} else {
|
||||||
|
logger.Say.Debug("MySQL连接成功")
|
||||||
|
}
|
||||||
|
MySQL = conn
|
||||||
|
|
||||||
|
//db, err := conn.DB()
|
||||||
|
//db.SetMaxIdleConns(10) // 用于设置连接池中空闲连接的最大数量
|
||||||
|
//db.SetMaxOpenConns(100) // 用于设置数据库连接的最大打开数量
|
||||||
|
//db.SetConnMaxLifetime(time.Hour) // 设置连接的最大存活时间
|
||||||
|
}
|
26
client/redis.go
Normal file
26
client/redis.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"ginDemo/config"
|
||||||
|
"gitee.ltd/lxh/logger"
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Redis *redis.Client
|
||||||
|
|
||||||
|
func InitRedisClient() {
|
||||||
|
conf := config.Scd.Redis
|
||||||
|
// 初始化连接
|
||||||
|
conn := redis.NewClient(&redis.Options{
|
||||||
|
Addr: conf.GetDSN(),
|
||||||
|
Password: conf.Password,
|
||||||
|
DB: conf.Db,
|
||||||
|
})
|
||||||
|
if err := conn.Ping(context.Background()).Err(); err != nil {
|
||||||
|
logger.Say.Panicf("Redis连接初始化失败: %v", err)
|
||||||
|
} else {
|
||||||
|
logger.Say.Debug("Redis连接初始化成功")
|
||||||
|
}
|
||||||
|
Redis = conn
|
||||||
|
}
|
111
common/types/date.go
Normal file
111
common/types/date.go
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 默认时间格式
|
||||||
|
const dateFormat = "2006-01-02 15:04:05.000"
|
||||||
|
|
||||||
|
// DateTime 自定义时间类型
|
||||||
|
type DateTime time.Time
|
||||||
|
|
||||||
|
// Scan implements the Scanner interface.
|
||||||
|
func (dt *DateTime) Scan(value any) error {
|
||||||
|
// mysql 内部日期的格式可能是 2006-01-02 15:04:05 +0800 CST 格式,所以检出的时候还需要进行一次格式化
|
||||||
|
tTime, _ := time.Parse("2006-01-02 15:04:05 +0800 CST", value.(time.Time).String())
|
||||||
|
*dt = DateTime(tTime)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements the driver Valuer interface.
|
||||||
|
func (dt DateTime) Value() (driver.Value, error) {
|
||||||
|
// 0001-01-01 00:00:00 属于空值,遇到空值解析成 null 即可
|
||||||
|
if dt.String() == "0001-01-01 00:00:00.000" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return []byte(dt.Format(dateFormat)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用于 fmt.Println 和后续验证场景
|
||||||
|
func (dt DateTime) String() string {
|
||||||
|
return dt.Format(dateFormat)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format 格式化
|
||||||
|
func (dt DateTime) Format(fm string) string {
|
||||||
|
return time.Time(dt).Format(fm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// After 时间比较
|
||||||
|
func (dt *DateTime) After(now time.Time) bool {
|
||||||
|
return time.Time(*dt).After(now)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before 时间比较
|
||||||
|
func (dt *DateTime) Before(now time.Time) bool {
|
||||||
|
return time.Time(*dt).Before(now)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IBefore 时间比较
|
||||||
|
func (dt *DateTime) IBefore(now DateTime) bool {
|
||||||
|
return dt.Before(time.Time(now))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubTime 对比
|
||||||
|
func (dt DateTime) SubTime(t time.Time) time.Duration {
|
||||||
|
return dt.ToTime().Sub(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub 对比
|
||||||
|
func (dt DateTime) Sub(t DateTime) time.Duration {
|
||||||
|
return dt.ToTime().Sub(t.ToTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToTime 转换为golang的时间类型
|
||||||
|
func (dt DateTime) ToTime() time.Time {
|
||||||
|
return time.Time(dt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNil 是否为空值
|
||||||
|
func (dt DateTime) IsNil() bool {
|
||||||
|
return dt.Format(dateFormat) == "0001-01-01 00:00:00.000"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unix 实现Unix函数
|
||||||
|
func (dt DateTime) Unix() int64 {
|
||||||
|
return dt.ToTime().Unix()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndOfCentury 获取本世纪最后时间
|
||||||
|
func (dt DateTime) EndOfCentury() DateTime {
|
||||||
|
yearEnd := time.Now().Local().Year()/100*100 + 99
|
||||||
|
return DateTime(time.Date(yearEnd, 12, 31, 23, 59, 59, 999999999, time.Local))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======== 序列化 ========
|
||||||
|
|
||||||
|
// MarshalJSON 时间到字符串
|
||||||
|
func (dt DateTime) MarshalJSON() ([]byte, error) {
|
||||||
|
// 过滤掉空数据
|
||||||
|
if dt.IsNil() {
|
||||||
|
return []byte("\"\""), nil
|
||||||
|
}
|
||||||
|
output := fmt.Sprintf(`"%s"`, dt.Format("2006-01-02 15:04:05"))
|
||||||
|
return []byte(output), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON 字符串到时间
|
||||||
|
func (dt *DateTime) UnmarshalJSON(b []byte) error {
|
||||||
|
if len(b) == 2 {
|
||||||
|
*dt = DateTime{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// 解析指定的格式
|
||||||
|
//now, err := time.ParseInLocation(`"`+dateFormat+`"`, string(b), time.Local)
|
||||||
|
now, err := time.ParseInLocation(dateFormat, string(b), time.Local)
|
||||||
|
*dt = DateTime(now)
|
||||||
|
return err
|
||||||
|
}
|
22
common/types/model.go
Normal file
22
common/types/model.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BaseDbModel 数据库通用字段
|
||||||
|
type BaseDbModel struct {
|
||||||
|
Id string `json:"id" gorm:"type:varchar(50);primarykey"`
|
||||||
|
CreatedAt DateTime `json:"createdAt"`
|
||||||
|
UpdatedAt DateTime `json:"updatedAt"`
|
||||||
|
DeletedAt gorm.DeletedAt `json:"-" gorm:"index:deleted"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeforeCreate 创建数据库对象之前生成UUID
|
||||||
|
func (m *BaseDbModel) BeforeCreate(*gorm.DB) (err error) {
|
||||||
|
uuidStr := uuid.New().String() // 生成UUID
|
||||||
|
m.Id = strings.ReplaceAll(uuidStr, "-", "") // 去掉UUID中的"-"
|
||||||
|
return
|
||||||
|
}
|
9
config/app.go
Normal file
9
config/app.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type appInfo struct {
|
||||||
|
AppName string `mapstructure:"name" yaml:"name"` // 应用名称
|
||||||
|
Port uint64 `mapstructure:"port" yaml:"port"` // 端口号
|
||||||
|
Prefix string `mapstructure:"prefix" yaml:"prefix"` // 接口前缀
|
||||||
|
Version string `mapstructure:"version" yaml:"version"` // 版本号
|
||||||
|
Monster bool `mapstructure:"monster" yaml:"monster"` // 妖怪模式
|
||||||
|
}
|
12
config/config.go
Normal file
12
config/config.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
var Scd systemConfigData
|
||||||
|
var Nacos nacosConfig
|
||||||
|
|
||||||
|
// 配置信息
|
||||||
|
type systemConfigData struct {
|
||||||
|
Admin appInfo `mapstructure:"admin" yaml:"admin"` // 系统配置-Admin
|
||||||
|
Api appInfo `mapstructure:"api" yaml:"api"` // 系统配置-Api
|
||||||
|
MySQL mysqlConfig `mapstructure:"mysql" yaml:"mysql"` // MySQL配置
|
||||||
|
Redis redisConfig `mapstructure:"redis" yaml:"redis"` // Redis配置
|
||||||
|
}
|
20
config/mysql.go
Normal file
20
config/mysql.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MySQL配置
|
||||||
|
type mysqlConfig struct {
|
||||||
|
Host string `mapstructure:"host" yaml:"host"` // 主机
|
||||||
|
Port int `mapstructure:"port" yaml:"port"` // 端口
|
||||||
|
User string `mapstructure:"user" yaml:"user"` // 用户名
|
||||||
|
Password string `mapstructure:"password" yaml:"password"` // 密码
|
||||||
|
Db string `mapstructure:"db" yaml:"db"` // 数据库名称
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDSN 返回 MySQL 连接字符串
|
||||||
|
func (c mysqlConfig) GetDSN() string {
|
||||||
|
return fmt.Sprintf("%s:%s@tcp(%s:%v)/%s?charset=utf8mb4&parseTime=True&loc=Local",
|
||||||
|
c.User, c.Password, c.Host, c.Port, c.Db)
|
||||||
|
}
|
9
config/nacos.go
Normal file
9
config/nacos.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
// Nacos配置
|
||||||
|
type nacosConfig struct {
|
||||||
|
Host string `env:"NACOS_HOST"` // 主机
|
||||||
|
Port uint64 `env:"NACOS_PORT" envDefault:"8848"` // 端口
|
||||||
|
NamespaceId string `env:"NACOS_NAMESPACE"` // 命名空间
|
||||||
|
CenterConfigName string `env:"NACOS_CONFIG_NAME" envDefault:"gtest.yml"` // 外部配置文件名,多个以逗号隔开
|
||||||
|
}
|
15
config/redis.go
Normal file
15
config/redis.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Redis配置
|
||||||
|
type redisConfig struct {
|
||||||
|
Host string `mapstructure:"host" yaml:"host"` // 主机
|
||||||
|
Port int `mapstructure:"port" yaml:"port"` // 端口
|
||||||
|
Password string `mapstructure:"password" yaml:"password"` // 密码
|
||||||
|
Db int `mapstructure:"db" yaml:"db"` // 数据库名称
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r redisConfig) GetDSN() string {
|
||||||
|
return fmt.Sprintf("%s:%v", r.Host, r.Port)
|
||||||
|
}
|
52
core/error_handle.go
Normal file
52
core/error_handle.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"gitee.ltd/lxh/logger"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NoMethodHandler 请求方式不对
|
||||||
|
func NoMethodHandler() gin.HandlerFunc {
|
||||||
|
return func(ctx *gin.Context) {
|
||||||
|
R(ctx).FailWithMessageAndCode(fmt.Sprintf("不支持%v请求", ctx.Request.Method), http.StatusMethodNotAllowed)
|
||||||
|
ctx.Abort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoRouteHandler 404异常处理
|
||||||
|
func NoRouteHandler() gin.HandlerFunc {
|
||||||
|
return func(ctx *gin.Context) {
|
||||||
|
R(ctx).FailWithMessageAndCode("请求接口不存在", http.StatusNotFound)
|
||||||
|
ctx.Abort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recovery Panic捕获
|
||||||
|
func Recovery() gin.HandlerFunc {
|
||||||
|
return func(ctx *gin.Context) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
logger.Say.Errorf("系统错误: %v", err)
|
||||||
|
var brokenPipe bool
|
||||||
|
if ne, ok := err.(*net.OpError); ok {
|
||||||
|
if se, ok := ne.Err.(*os.SyscallError); ok {
|
||||||
|
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
|
||||||
|
brokenPipe = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if brokenPipe {
|
||||||
|
logger.Say.Errorf("%s", err)
|
||||||
|
}
|
||||||
|
R(ctx).FailWithMessage("服务器异常,请联系管理员")
|
||||||
|
ctx.Abort()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ctx.Next()
|
||||||
|
}
|
||||||
|
}
|
84
core/response.go
Normal file
84
core/response.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ginDemo/utils"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 返回数据包装
|
||||||
|
type response struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Data any `json:"data"`
|
||||||
|
Msg string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type rs struct {
|
||||||
|
ctx *gin.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义状态码
|
||||||
|
const (
|
||||||
|
ERROR = http.StatusInternalServerError
|
||||||
|
SUCCESS = http.StatusOK
|
||||||
|
)
|
||||||
|
|
||||||
|
func R(ctx *gin.Context) *rs {
|
||||||
|
return &rs{ctx}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result 手动组装返回结果
|
||||||
|
func (r rs) Result(code int, data any, msg string) {
|
||||||
|
//if data == nil {
|
||||||
|
// data = map[string]any{}
|
||||||
|
//}
|
||||||
|
|
||||||
|
r.ctx.JSON(code, response{
|
||||||
|
code,
|
||||||
|
data,
|
||||||
|
msg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok 返回无数据的成功
|
||||||
|
func (r rs) Ok() {
|
||||||
|
r.Result(SUCCESS, nil, "操作成功")
|
||||||
|
}
|
||||||
|
|
||||||
|
// OkWithMessage 返回自定义成功的消息
|
||||||
|
func (r rs) OkWithMessage(message string) {
|
||||||
|
r.Result(SUCCESS, nil, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OkWithData 自定义内容的成功返回
|
||||||
|
func (r rs) OkWithData(data any) {
|
||||||
|
r.Result(SUCCESS, data, "操作成功")
|
||||||
|
}
|
||||||
|
|
||||||
|
// OkWithPageData 返回分页数据
|
||||||
|
func (r rs) OkWithPageData(data any, total int64, current, size int) {
|
||||||
|
// 计算总页码
|
||||||
|
totalPage := utils.GenTotalPage(total, size)
|
||||||
|
// 返回结果
|
||||||
|
r.Result(SUCCESS, PageData{Current: current, Size: size, Total: total, TotalPage: totalPage, Records: data}, "操作成功")
|
||||||
|
}
|
||||||
|
|
||||||
|
// OkDetailed 自定义消息和内容的成功返回
|
||||||
|
func (r rs) OkDetailed(data any, message string) {
|
||||||
|
r.Result(SUCCESS, data, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail 返回默认失败
|
||||||
|
func (r rs) Fail() {
|
||||||
|
r.Result(ERROR, nil, "操作失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FailWithMessage 返回默认状态码自定义消息的失败
|
||||||
|
func (r rs) FailWithMessage(message string) {
|
||||||
|
r.Result(ERROR, nil, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FailWithMessageAndCode 返回自定义消息和状态码的失败
|
||||||
|
func (r rs) FailWithMessageAndCode(message string, code int) {
|
||||||
|
r.Result(code, nil, message)
|
||||||
|
}
|
10
core/response_page.go
Normal file
10
core/response_page.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
// PageData 分页数据通用结构体
|
||||||
|
type PageData struct {
|
||||||
|
Current int `json:"current"` // 当前页码
|
||||||
|
Size int `json:"size"` // 每页数量
|
||||||
|
Total int64 `json:"total"` // 总数
|
||||||
|
TotalPage int `json:"total_page"` // 总页数
|
||||||
|
Records any `json:"records"` // 返回数据
|
||||||
|
}
|
116
go.mod
Normal file
116
go.mod
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
module ginDemo
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require (
|
||||||
|
gitee.ltd/lxh/logger v1.0.7
|
||||||
|
github.com/caarlos0/env/v6 v6.9.1
|
||||||
|
github.com/duke-git/lancet/v2 v2.0.5
|
||||||
|
github.com/fsnotify/fsnotify v1.5.4
|
||||||
|
github.com/gin-gonic/gin v1.7.7
|
||||||
|
github.com/go-redis/redis/v8 v8.11.5
|
||||||
|
github.com/google/uuid v1.3.0
|
||||||
|
github.com/lixh00/nacos-viper-remote v0.4.1-0.20220225021138-2935b772c7c1
|
||||||
|
github.com/spf13/viper v1.11.0
|
||||||
|
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
|
gorm.io/driver/mysql v1.3.3
|
||||||
|
gorm.io/gorm v1.23.5
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
cloud.google.com/go v0.101.1 // indirect
|
||||||
|
cloud.google.com/go/compute v1.6.1 // indirect
|
||||||
|
cloud.google.com/go/firestore v1.6.1 // indirect
|
||||||
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1584 // indirect
|
||||||
|
github.com/armon/go-metrics v0.3.11 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/buger/jsonparser v1.1.1 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
|
github.com/coreos/go-semver v0.3.0 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/fatih/color v1.13.0 // indirect
|
||||||
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
|
github.com/go-errors/errors v1.4.2 // indirect
|
||||||
|
github.com/go-kit/kit v0.12.0 // indirect
|
||||||
|
github.com/go-kit/log v0.2.0 // indirect
|
||||||
|
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.0 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||||
|
github.com/go-playground/validator/v10 v10.11.0 // indirect
|
||||||
|
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
|
github.com/google/go-cmp v0.5.8 // indirect
|
||||||
|
github.com/googleapis/gax-go/v2 v2.3.0 // indirect
|
||||||
|
github.com/hashicorp/consul/api v1.12.0 // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
|
github.com/hashicorp/go-hclog v1.2.0 // indirect
|
||||||
|
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
|
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||||
|
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||||
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
github.com/hashicorp/serf v0.9.7 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
|
github.com/jpillora/backoff v1.0.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
|
github.com/lixh00/loki-client-go v1.0.1 // indirect
|
||||||
|
github.com/magiconair/properties v1.8.6 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||||
|
github.com/miekg/dns v1.1.48 // indirect
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 // 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/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||||
|
github.com/nacos-group/nacos-sdk-go/v2 v2.0.3 // indirect
|
||||||
|
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
|
||||||
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.0.0 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.12.1 // indirect
|
||||||
|
github.com/prometheus/client_model v0.2.0 // indirect
|
||||||
|
github.com/prometheus/common v0.34.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
|
github.com/prometheus/prometheus v1.8.2-0.20201028100903-3245b3267b24 // indirect
|
||||||
|
github.com/sagikazarmark/crypt v0.5.0 // indirect
|
||||||
|
github.com/spf13/afero v1.8.2 // indirect
|
||||||
|
github.com/spf13/cast v1.4.1 // indirect
|
||||||
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/stretchr/objx v0.3.0 // indirect
|
||||||
|
github.com/subosito/gotenv v1.2.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||||
|
go.etcd.io/etcd/api/v3 v3.5.4 // indirect
|
||||||
|
go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect
|
||||||
|
go.etcd.io/etcd/client/v2 v2.305.4 // indirect
|
||||||
|
go.opencensus.io v0.23.0 // indirect
|
||||||
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
|
go.uber.org/multierr v1.8.0 // indirect
|
||||||
|
go.uber.org/zap v1.21.0 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
|
||||||
|
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
golang.org/x/tools v0.1.10 // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
|
||||||
|
google.golang.org/api v0.78.0 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3 // indirect
|
||||||
|
google.golang.org/grpc v1.46.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.28.0 // indirect
|
||||||
|
gopkg.in/ini.v1 v1.66.4 // indirect
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
|
)
|
9
initialize/clients.go
Normal file
9
initialize/clients.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import "ginDemo/client"
|
||||||
|
|
||||||
|
// 初始化数据库客户端
|
||||||
|
func initClient() {
|
||||||
|
client.InitMySQLClient()
|
||||||
|
//client.InitRedisClient()
|
||||||
|
}
|
67
initialize/config.go
Normal file
67
initialize/config.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ginDemo/config"
|
||||||
|
"gitee.ltd/lxh/logger"
|
||||||
|
"github.com/caarlos0/env/v6"
|
||||||
|
"github.com/fsnotify/fsnotify"
|
||||||
|
nr "github.com/lixh00/nacos-viper-remote"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
_ "github.com/spf13/viper/remote"
|
||||||
|
)
|
||||||
|
|
||||||
|
var vp *viper.Viper
|
||||||
|
|
||||||
|
// 初始化Nacos
|
||||||
|
func initNacos() {
|
||||||
|
// 初始化Nacos配置
|
||||||
|
if err := env.Parse(&config.Nacos); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if config.Nacos.Host == "" {
|
||||||
|
logger.Say.Panic("Nacos配置错误")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化配置文件
|
||||||
|
func initConfig() {
|
||||||
|
vp = viper.New()
|
||||||
|
|
||||||
|
// 配置 Viper for Nacos 的远程仓库参数
|
||||||
|
nr.SetOptions(&nr.Option{
|
||||||
|
Url: config.Nacos.Host, // nacos server 多地址需要地址用;号隔开,如 Url: "loc1;loc2;loc3"
|
||||||
|
Port: config.Nacos.Port, // nacos server端口号
|
||||||
|
NamespaceId: config.Nacos.NamespaceId, // nacos namespace
|
||||||
|
GroupName: "DEFAULT_GROUP", // nacos group
|
||||||
|
Config: nr.Config{DataId: config.Nacos.CenterConfigName}, // nacos DataID
|
||||||
|
Auth: nil, // 如果需要验证登录,需要此参数
|
||||||
|
})
|
||||||
|
err := vp.AddRemoteProvider("nacos", config.Nacos.Host, "")
|
||||||
|
if err != nil {
|
||||||
|
logger.Say.Panicf("%s", err)
|
||||||
|
}
|
||||||
|
vp.SetConfigType("yaml")
|
||||||
|
//尝试进行配置读取
|
||||||
|
if err = vp.ReadRemoteConfig(); err != nil {
|
||||||
|
logger.Say.Panic(err)
|
||||||
|
}
|
||||||
|
//异步监听Nacos中的配置变化,如发生配置更改,会直接同步到 viper实例中。
|
||||||
|
err = vp.WatchRemoteConfigOnChannel()
|
||||||
|
if err != nil {
|
||||||
|
logger.Say.Errorf("监听远程配置变动失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析配置文件为结构体
|
||||||
|
if err = vp.Unmarshal(&config.Scd); err != nil {
|
||||||
|
logger.Say.Panic(err)
|
||||||
|
}
|
||||||
|
vp.WatchConfig() // 监听配置文件变化
|
||||||
|
vp.OnConfigChange(func(e fsnotify.Event) {
|
||||||
|
logger.Say.Info("配置文件发生变动:", e.Name)
|
||||||
|
if err = vp.Unmarshal(&config.Scd); err != nil {
|
||||||
|
logger.Say.Panic(err)
|
||||||
|
}
|
||||||
|
// 配置文件发生变动,重新初始化一下连接信息
|
||||||
|
initClient()
|
||||||
|
})
|
||||||
|
}
|
19
initialize/db_table.go
Normal file
19
initialize/db_table.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ginDemo/client"
|
||||||
|
"ginDemo/model/entity"
|
||||||
|
"gitee.ltd/lxh/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 初始化数据库表
|
||||||
|
func databaseTable() {
|
||||||
|
dbs := []any{
|
||||||
|
new(entity.User), // 管理员用户
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := client.MySQL.AutoMigrate(dbs...); err != nil {
|
||||||
|
logger.Say.Panicf("数据库表预初始化处理:%s", err.Error())
|
||||||
|
}
|
||||||
|
logger.Say.Debugf("数据库表预初始化处理完成")
|
||||||
|
}
|
9
initialize/init.go
Normal file
9
initialize/init.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
// InitSystem 初始化系统
|
||||||
|
func InitSystem() {
|
||||||
|
initNacos() // 初始化nacos
|
||||||
|
initConfig() // 初始化配置
|
||||||
|
initClient() // 初始化连接池等信息
|
||||||
|
databaseTable() // 初始化数据库表信息
|
||||||
|
}
|
27
logs/nacos/cache/vp.yaml@@DEFAULT_GROUP@@c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a
vendored
Normal file
27
logs/nacos/cache/vp.yaml@@DEFAULT_GROUP@@c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
admin:
|
||||||
|
port: 8082
|
||||||
|
name: loser_admin
|
||||||
|
version: v1
|
||||||
|
prefix: /admin/v1
|
||||||
|
|
||||||
|
api:
|
||||||
|
port: 8083
|
||||||
|
name: loser_api
|
||||||
|
version: v1
|
||||||
|
prefix: /api/v1
|
||||||
|
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
host: 101.35.50.11
|
||||||
|
port: 3306
|
||||||
|
user: godev
|
||||||
|
password: loser765911.
|
||||||
|
db: golang
|
||||||
|
|
||||||
|
|
||||||
|
# Redis配置
|
||||||
|
redis:
|
||||||
|
host: 101.35.50.11
|
||||||
|
port: 6379
|
||||||
|
password: loser7659
|
||||||
|
db: 0
|
104
logs/nacos/log/nacos-sdk.log
Normal file
104
logs/nacos/log/nacos-sdk.log
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
2022-05-07T15:51:35.792+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-14e2e4ee-fcf5-4b33-874e-c987b013d940 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T15:51:35.805+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-07T15:51:55.814+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-14e2e4ee-fcf5-4b33-874e-c987b013d940 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=2
|
||||||
|
2022-05-07T15:51:55.814+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-14e2e4ee-fcf5-4b33-874e-c987b013d940 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T15:52:15.816+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-14e2e4ee-fcf5-4b33-874e-c987b013d940 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=1
|
||||||
|
2022-05-07T15:52:15.816+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-14e2e4ee-fcf5-4b33-874e-c987b013d940 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T15:52:35.826+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-14e2e4ee-fcf5-4b33-874e-c987b013d940 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=0
|
||||||
|
2022-05-07T15:52:35.826+0800 INFO rpc/rpc_client.go:308 config-0-14e2e4ee-fcf5-4b33-874e-c987b013d940 try to re connect to a new server, server is not appointed, will choose a random server.
|
||||||
|
2022-05-07T15:52:35.826+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"mysql.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=0, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T15:52:35.933+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"mysql.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=1, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T15:52:36.040+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"mysql.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=2, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T15:52:36.146+0800 INFO config_client/config_client.go:192 get config from server error:client not connected, current status:STARTING
|
||||||
|
2022-05-07T15:52:36.146+0800 ERROR config_client/config_client.go:195 get config from cache error:failed to read config cache file:logs/nacos/cache\config\mysql.yaml@@DEFAULT_GROUP@@41f4f415-970b-4839-8f71-d4fa4c6d6c30,err:open logs/nacos/cache\config\mysql.yaml@@DEFAULT_GROUP@@41f4f415-970b-4839-8f71-d4fa4c6d6c30: The system cannot find the path specified.
|
||||||
|
2022-05-07T16:50:50.559+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-ab17c067-9b1b-433a-946d-86e63481c1e9 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T16:50:50.572+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-07T16:51:10.570+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-ab17c067-9b1b-433a-946d-86e63481c1e9 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=2
|
||||||
|
2022-05-07T16:51:10.570+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-ab17c067-9b1b-433a-946d-86e63481c1e9 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T16:51:30.575+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-ab17c067-9b1b-433a-946d-86e63481c1e9 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=1
|
||||||
|
2022-05-07T16:51:30.576+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-ab17c067-9b1b-433a-946d-86e63481c1e9 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T16:51:50.590+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-ab17c067-9b1b-433a-946d-86e63481c1e9 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=0
|
||||||
|
2022-05-07T16:51:50.591+0800 INFO rpc/rpc_client.go:308 config-0-ab17c067-9b1b-433a-946d-86e63481c1e9 try to re connect to a new server, server is not appointed, will choose a random server.
|
||||||
|
2022-05-07T16:51:50.591+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"mysql.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=0, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:51:50.698+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"mysql.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=1, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:51:50.808+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"mysql.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=2, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:51:50.919+0800 INFO config_client/config_client.go:192 get config from server error:client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:51:50.920+0800 ERROR config_client/config_client.go:195 get config from cache error:failed to read config cache file:logs/nacos/cache\config\mysql.yaml@@DEFAULT_GROUP@@41f4f415-970b-4839-8f71-d4fa4c6d6c30,err:open logs/nacos/cache\config\mysql.yaml@@DEFAULT_GROUP@@41f4f415-970b-4839-8f71-d4fa4c6d6c30: The system cannot find the path specified.
|
||||||
|
2022-05-07T16:54:30.518+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-7a5cea5d-2c3b-4839-ab16-433a9ccca8dd try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T16:54:30.531+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-07T16:54:50.537+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-7a5cea5d-2c3b-4839-ab16-433a9ccca8dd fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=2
|
||||||
|
2022-05-07T16:54:50.537+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-7a5cea5d-2c3b-4839-ab16-433a9ccca8dd try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T16:55:10.545+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-7a5cea5d-2c3b-4839-ab16-433a9ccca8dd fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=1
|
||||||
|
2022-05-07T16:55:10.546+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-7a5cea5d-2c3b-4839-ab16-433a9ccca8dd try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T16:55:30.548+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-7a5cea5d-2c3b-4839-ab16-433a9ccca8dd fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=0
|
||||||
|
2022-05-07T16:55:30.549+0800 INFO rpc/rpc_client.go:308 config-0-7a5cea5d-2c3b-4839-ab16-433a9ccca8dd try to re connect to a new server, server is not appointed, will choose a random server.
|
||||||
|
2022-05-07T16:55:30.549+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=0, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:55:30.656+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=1, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:55:30.765+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=2, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:55:30.874+0800 INFO config_client/config_client.go:192 get config from server error:client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:55:30.874+0800 ERROR config_client/config_client.go:195 get config from cache error:failed to read config cache file:logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@41f4f415-970b-4839-8f71-d4fa4c6d6c30,err:open logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@41f4f415-970b-4839-8f71-d4fa4c6d6c30: The system cannot find the path specified.
|
||||||
|
2022-05-07T16:57:10.643+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-2516e397-0f43-45c6-aaa7-5ea477ef4f35 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T16:57:10.657+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-07T16:57:30.664+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-2516e397-0f43-45c6-aaa7-5ea477ef4f35 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=2
|
||||||
|
2022-05-07T16:57:30.665+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-2516e397-0f43-45c6-aaa7-5ea477ef4f35 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T16:57:50.677+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-2516e397-0f43-45c6-aaa7-5ea477ef4f35 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=1
|
||||||
|
2022-05-07T16:57:50.677+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-2516e397-0f43-45c6-aaa7-5ea477ef4f35 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8080}
|
||||||
|
2022-05-07T16:58:10.678+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-2516e397-0f43-45c6-aaa7-5ea477ef4f35 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=0
|
||||||
|
2022-05-07T16:58:10.678+0800 INFO rpc/rpc_client.go:308 config-0-2516e397-0f43-45c6-aaa7-5ea477ef4f35 try to re connect to a new server, server is not appointed, will choose a random server.
|
||||||
|
2022-05-07T16:58:10.679+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=0, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:58:10.787+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=1, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:58:10.896+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"41f4f415-970b-4839-8f71-d4fa4c6d6c30","tag":""}, retryTimes=2, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:58:11.006+0800 INFO config_client/config_client.go:192 get config from server error:client not connected, current status:STARTING
|
||||||
|
2022-05-07T16:58:11.006+0800 ERROR config_client/config_client.go:195 get config from cache error:failed to read config cache file:logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@41f4f415-970b-4839-8f71-d4fa4c6d6c30,err:open logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@41f4f415-970b-4839-8f71-d4fa4c6d6c30: The system cannot find the path specified.
|
||||||
|
2022-05-07T17:22:04.919+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-bb1d8767-ce4e-4949-b76b-e8221d38aaa1 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-07T17:22:04.931+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-07T17:22:24.928+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-bb1d8767-ce4e-4949-b76b-e8221d38aaa1 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=2
|
||||||
|
2022-05-07T17:22:24.928+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-bb1d8767-ce4e-4949-b76b-e8221d38aaa1 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-07T17:22:44.936+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-bb1d8767-ce4e-4949-b76b-e8221d38aaa1 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=1
|
||||||
|
2022-05-07T17:22:44.936+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-bb1d8767-ce4e-4949-b76b-e8221d38aaa1 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-07T17:23:04.940+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-bb1d8767-ce4e-4949-b76b-e8221d38aaa1 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=0
|
||||||
|
2022-05-07T17:23:04.940+0800 INFO rpc/rpc_client.go:308 config-0-bb1d8767-ce4e-4949-b76b-e8221d38aaa1 try to re connect to a new server, server is not appointed, will choose a random server.
|
||||||
|
2022-05-07T17:23:04.940+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a","tag":""}, retryTimes=0, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T17:23:05.048+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a","tag":""}, retryTimes=1, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T17:23:05.157+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a","tag":""}, retryTimes=2, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T17:23:05.266+0800 INFO config_client/config_client.go:192 get config from server error:client not connected, current status:STARTING
|
||||||
|
2022-05-07T17:23:05.266+0800 ERROR config_client/config_client.go:195 get config from cache error:failed to read config cache file:logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a,err:open logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a: The system cannot find the path specified.
|
||||||
|
2022-05-07T17:36:19.249+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-d9fadd01-929c-4b33-8b0a-558aa0394ea2 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-07T17:36:19.260+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-07T17:36:39.260+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-d9fadd01-929c-4b33-8b0a-558aa0394ea2 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=2
|
||||||
|
2022-05-07T17:36:39.260+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-d9fadd01-929c-4b33-8b0a-558aa0394ea2 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-07T17:36:59.268+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-d9fadd01-929c-4b33-8b0a-558aa0394ea2 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=1
|
||||||
|
2022-05-07T17:36:59.269+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-d9fadd01-929c-4b33-8b0a-558aa0394ea2 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-07T17:37:19.272+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-d9fadd01-929c-4b33-8b0a-558aa0394ea2 fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=0
|
||||||
|
2022-05-07T17:37:19.272+0800 INFO rpc/rpc_client.go:308 config-0-d9fadd01-929c-4b33-8b0a-558aa0394ea2 try to re connect to a new server, server is not appointed, will choose a random server.
|
||||||
|
2022-05-07T17:37:19.272+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a","tag":""}, retryTimes=0, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T17:37:19.382+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a","tag":""}, retryTimes=1, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T17:37:19.492+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a","tag":""}, retryTimes=2, error=client not connected, current status:STARTING
|
||||||
|
2022-05-07T17:37:19.600+0800 INFO config_client/config_client.go:192 get config from server error:client not connected, current status:STARTING
|
||||||
|
2022-05-07T17:37:19.601+0800 ERROR config_client/config_client.go:195 get config from cache error:failed to read config cache file:logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a,err:open logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a: The system cannot find the path specified.
|
||||||
|
2022-05-09T08:42:25.076+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-3da5854f-08ac-47b0-96c2-e91e71d99e3e try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-09T08:42:25.085+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-09T08:42:45.093+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-3da5854f-08ac-47b0-96c2-e91e71d99e3e fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=2
|
||||||
|
2022-05-09T08:42:45.093+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-3da5854f-08ac-47b0-96c2-e91e71d99e3e try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-09T08:43:05.094+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-3da5854f-08ac-47b0-96c2-e91e71d99e3e fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=1
|
||||||
|
2022-05-09T08:43:05.094+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-3da5854f-08ac-47b0-96c2-e91e71d99e3e try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-09T08:43:25.097+0800 WARN rpc/rpc_client.go:216 [RpcClient.Start] config-0-3da5854f-08ac-47b0-96c2-e91e71d99e3e fail to connect to server on start up, error message=rpc error: code = Unavailable desc = failed to receive server preface within timeout, start up retry times left=0
|
||||||
|
2022-05-09T08:43:25.098+0800 INFO rpc/rpc_client.go:308 config-0-3da5854f-08ac-47b0-96c2-e91e71d99e3e try to re connect to a new server, server is not appointed, will choose a random server.
|
||||||
|
2022-05-09T08:43:25.098+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a","tag":""}, retryTimes=0, error=client not connected, current status:STARTING
|
||||||
|
2022-05-09T08:43:25.206+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a","tag":""}, retryTimes=1, error=client not connected, current status:STARTING
|
||||||
|
2022-05-09T08:43:25.316+0800 ERROR rpc/rpc_client.go:505 Send request fail, request=ConfigQueryRequest, body={"requestId":"","module":"config","group":"DEFAULT_GROUP","dataId":"vp.yaml","tenant":"c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a","tag":""}, retryTimes=2, error=client not connected, current status:STARTING
|
||||||
|
2022-05-09T08:43:25.425+0800 INFO config_client/config_client.go:192 get config from server error:client not connected, current status:STARTING
|
||||||
|
2022-05-09T08:43:25.425+0800 ERROR config_client/config_client.go:195 get config from cache error:failed to read config cache file:logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a,err:open logs/nacos/cache\config\vp.yaml@@DEFAULT_GROUP@@c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a: The system cannot find the path specified.
|
||||||
|
2022-05-09T08:45:51.496+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-f40d1bc4-ae4d-4419-a6f1-6ff8212ef3a1 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-09T08:45:51.505+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-09T08:45:51.779+0800 INFO rpc/rpc_client.go:224 config-0-f40d1bc4-ae4d-4419-a6f1-6ff8212ef3a1 success to connect to server {serverIp:101.35.50.11 serverPort:8848} on start up, connectionId=1652057150757_106.91.6.123_42052
|
||||||
|
2022-05-09T08:47:01.394+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-eba4eae2-0573-4ccf-95ed-6a10a9887cce try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-09T08:47:01.402+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-09T08:47:01.644+0800 INFO rpc/rpc_client.go:224 config-0-eba4eae2-0573-4ccf-95ed-6a10a9887cce success to connect to server {serverIp:101.35.50.11 serverPort:8848} on start up, connectionId=1652057220660_106.91.6.123_42056
|
||||||
|
2022-05-09T08:48:10.048+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-0f60d6e9-6193-42b5-8a18-18ed1cef387e try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-09T08:48:10.056+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-09T08:48:10.268+0800 INFO rpc/rpc_client.go:224 config-0-0f60d6e9-6193-42b5-8a18-18ed1cef387e success to connect to server {serverIp:101.35.50.11 serverPort:8848} on start up, connectionId=1652057289303_106.91.6.123_42060
|
||||||
|
2022-05-09T08:50:16.604+0800 INFO config_client/config_proxy.go:184 config-0-0f60d6e9-6193-42b5-8a18-18ed1cef387e [server-push] config changed. dataId=vp.yaml, group=DEFAULT_GROUP,tenant=c2b1a6c5-ab3d-422c-b4a7-de80a3c4d62a
|
||||||
|
2022-05-09T08:51:09.183+0800 INFO rpc/rpc_client.go:214 [RpcClient.Start] config-0-25c51fe1-45b7-4a4f-8d1e-fbc95d1950c2 try to connect to server on start up, server: {serverIp:101.35.50.11 serverPort:8848}
|
||||||
|
2022-05-09T08:51:09.191+0800 INFO util/common.go:96 Local IP:10.11.0.20
|
||||||
|
2022-05-09T08:51:09.429+0800 INFO rpc/rpc_client.go:224 config-0-25c51fe1-45b7-4a4f-8d1e-fbc95d1950c2 success to connect to server {serverIp:101.35.50.11 serverPort:8848} on start up, connectionId=1652057468447_106.91.6.123_42062
|
57
main.go
Normal file
57
main.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"ginDemo/config"
|
||||||
|
"ginDemo/core"
|
||||||
|
"ginDemo/initialize"
|
||||||
|
admRoute "ginDemo/route/admin"
|
||||||
|
"gitee.ltd/lxh/logger"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var g errgroup.Group
|
||||||
|
|
||||||
|
// 系统初始化
|
||||||
|
func init() {
|
||||||
|
initialize.InitSystem() // 初始化系统配置
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动入口
|
||||||
|
func main() {
|
||||||
|
// 强制日志颜色化
|
||||||
|
gin.ForceConsoleColor()
|
||||||
|
// 定义启动入口
|
||||||
|
adm := &http.Server{
|
||||||
|
Addr: fmt.Sprintf(":%d", config.Scd.Admin.Port),
|
||||||
|
Handler: admin(),
|
||||||
|
ReadTimeout: 5 * time.Second,
|
||||||
|
WriteTimeout: 1 * time.Minute,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动项目
|
||||||
|
g.Go(func() error {
|
||||||
|
return adm.ListenAndServe()
|
||||||
|
})
|
||||||
|
if err := g.Wait(); err != nil {
|
||||||
|
logger.Say.Panicf("启动失败,错误信息:%s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成Admin服务
|
||||||
|
func admin() http.Handler {
|
||||||
|
app := gin.New()
|
||||||
|
app.Use(gin.Recovery())
|
||||||
|
// 开启自定义请求方式不允许处理函数
|
||||||
|
app.HandleMethodNotAllowed = true
|
||||||
|
// 处理请求方式不对
|
||||||
|
app.NoMethod(core.NoMethodHandler())
|
||||||
|
// 404返回数据
|
||||||
|
app.NoRoute(core.NoRouteHandler())
|
||||||
|
// 初始化路由
|
||||||
|
admRoute.InitRoute(app.Group(config.Scd.Admin.Prefix))
|
||||||
|
return app
|
||||||
|
}
|
19
model/cache/user.go
vendored
Normal file
19
model/cache/user.go
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package cache
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
// UserInfo 登录用的用户信息结构体
|
||||||
|
type UserInfo struct {
|
||||||
|
UserType string `json:"userType"` // 用户类型
|
||||||
|
RoleCodes string `json:"roleCodes"` // 角色代码
|
||||||
|
UserId string `json:"userId"` // 用户Id
|
||||||
|
}
|
||||||
|
|
||||||
|
// String 实现Stringer接口
|
||||||
|
func (i UserInfo) String() (string, error) {
|
||||||
|
b, err := json.Marshal(i)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(b), nil
|
||||||
|
}
|
21
model/entity/user.go
Normal file
21
model/entity/user.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package entity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ginDemo/common/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// User 普通用户表
|
||||||
|
type User struct {
|
||||||
|
types.BaseDbModel
|
||||||
|
Phone string `json:"phone" gorm:"type:varchar(255) not null comment '手机号'"`
|
||||||
|
Password string `json:"password" gorm:"type:varchar(255) not null comment '密码'"`
|
||||||
|
Nickname string `json:"nickname" gorm:"type:varchar(255) comment '昵称'"`
|
||||||
|
Avatar string `json:"avatar" gorm:"type:varchar(255) comment '头像'"`
|
||||||
|
Birthday *string `json:"birthday" gorm:"type:varchar(10); comment 生日"`
|
||||||
|
LastLoginAt *types.DateTime `json:"last_login_at" gorm:"comment:'最后登录时间'"`
|
||||||
|
LastLoginIp *string `json:"last_login_ip" gorm:"type:varchar(255) comment '最后登录ip'"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (User) TableName() string {
|
||||||
|
return "t_user"
|
||||||
|
}
|
5
model/readme.md
Normal file
5
model/readme.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## 系统定义的结构体都放在这个包下面
|
||||||
|
|
||||||
|
### 注意事项
|
||||||
|
1. entity包对应的是数据库表结构
|
||||||
|
2. 所有涉及param和entity转换的操作,都放在param里面去实现一个`ToEntity`函数和`FromEntity`函数,避免两个包交叉引用
|
19
repository/user.go
Normal file
19
repository/user.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ginDemo/client"
|
||||||
|
"ginDemo/model/entity"
|
||||||
|
)
|
||||||
|
|
||||||
|
type user struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// User ...
|
||||||
|
func User() *user {
|
||||||
|
return &user{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUser 查询单个用户信息
|
||||||
|
func (user) GetUser(user *entity.User) (err error) {
|
||||||
|
return client.MySQL.Take(&user, user).Error
|
||||||
|
}
|
12
route/admin/route.go
Normal file
12
route/admin/route.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitRoute 初始化路由
|
||||||
|
func InitRoute(g *gin.RouterGroup) {
|
||||||
|
|
||||||
|
user(g.Group("/user")) // 用户相关路由
|
||||||
|
|
||||||
|
}
|
11
route/admin/user.go
Normal file
11
route/admin/user.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ginDemo/api/admin"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 用户相关路由
|
||||||
|
func user(g *gin.RouterGroup) {
|
||||||
|
g.GET("", admin.UserApi().GetUser) // 获取当前登录用户信息
|
||||||
|
}
|
63
utils/file.go
Normal file
63
utils/file.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/fileutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fileUtils struct{}
|
||||||
|
|
||||||
|
func FileUtils() *fileUtils {
|
||||||
|
return &fileUtils{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fileUtils) CheckIsExists(path string) (bool, error) {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckAndCreate 判断文件名是否存在,不存在就创建
|
||||||
|
func (f fileUtils) CheckAndCreate(path string) error {
|
||||||
|
exists, err := f.CheckIsExists(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
err = os.MkdirAll(path, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelPath 删除目录下的所有文件和目录本身
|
||||||
|
func (f fileUtils) DelPath(path string) error {
|
||||||
|
files, err := fileutil.ListFileNames(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, file := range files {
|
||||||
|
// 如果是目录,则递归删除
|
||||||
|
if fileutil.IsDir(file) {
|
||||||
|
err = f.DelPath(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = fileutil.RemoveFile(fmt.Sprintf("%s/%s", path, file))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ = fileutil.RemoveFile(path)
|
||||||
|
return nil
|
||||||
|
}
|
79
utils/http.go
Normal file
79
utils/http.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type httpUtil struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Http 暴露接口
|
||||||
|
func Http() *httpUtil {
|
||||||
|
return &httpUtil{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProxy 重写创建代理函数,加入 Host 信息
|
||||||
|
func (hu httpUtil) NewProxy(target *url.URL) *httputil.ReverseProxy {
|
||||||
|
targetQuery := target.RawQuery
|
||||||
|
director := func(req *http.Request) {
|
||||||
|
req.Host = target.Host
|
||||||
|
req.URL.Scheme = target.Scheme
|
||||||
|
req.URL.Host = target.Host
|
||||||
|
req.URL.Path, req.URL.RawPath = hu.joinURLPath(target, req.URL)
|
||||||
|
// 过滤掉参数
|
||||||
|
if uri, err := url.Parse(req.URL.Path); err == nil {
|
||||||
|
req.URL.Path = uri.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
var rawQuery string
|
||||||
|
if targetQuery == "" || req.URL.RawQuery == "" {
|
||||||
|
rawQuery = targetQuery + req.URL.RawQuery
|
||||||
|
} else {
|
||||||
|
rawQuery = targetQuery + "&" + req.URL.RawQuery
|
||||||
|
}
|
||||||
|
req.URL.RawQuery = rawQuery
|
||||||
|
if _, ok := req.Header["User-Agent"]; !ok {
|
||||||
|
// explicitly disable User-Agent so it's not set to default value
|
||||||
|
req.Header.Set("User-Agent", "")
|
||||||
|
}
|
||||||
|
// 补充内部调用Header
|
||||||
|
req.Header.Set("X-Request-From", "internal")
|
||||||
|
}
|
||||||
|
return &httputil.ReverseProxy{Director: director}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hu httpUtil) joinURLPath(a, b *url.URL) (path, rawpath string) {
|
||||||
|
if a.RawPath == "" && b.RawPath == "" {
|
||||||
|
return hu.singleJoiningSlash(a.Path, b.Path), ""
|
||||||
|
}
|
||||||
|
// Same as singleJoiningSlash, but uses EscapedPath to determine
|
||||||
|
// whether a slash should be added
|
||||||
|
apath := a.EscapedPath()
|
||||||
|
bpath := b.EscapedPath()
|
||||||
|
|
||||||
|
aslash := strings.HasSuffix(apath, "/")
|
||||||
|
bslash := strings.HasPrefix(bpath, "/")
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case aslash && bslash:
|
||||||
|
return a.Path + b.Path[1:], apath + bpath[1:]
|
||||||
|
case !aslash && !bslash:
|
||||||
|
return a.Path + "/" + b.Path, apath + "/" + bpath
|
||||||
|
}
|
||||||
|
return a.Path + b.Path, apath + bpath
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hu httpUtil) singleJoiningSlash(a, b string) string {
|
||||||
|
aslash := strings.HasSuffix(a, "/")
|
||||||
|
bslash := strings.HasPrefix(b, "/")
|
||||||
|
switch {
|
||||||
|
case aslash && bslash:
|
||||||
|
return a + b[1:]
|
||||||
|
case !aslash && !bslash:
|
||||||
|
return a + "/" + b
|
||||||
|
}
|
||||||
|
return a + b
|
||||||
|
}
|
24
utils/id.go
Normal file
24
utils/id.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type idUtil struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Id 暴露接口
|
||||||
|
func Id() *idUtil {
|
||||||
|
return &idUtil{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenOrderNo 生成订单Id
|
||||||
|
func (idUtil) GenOrderNo() string {
|
||||||
|
ss := time.Now().Format("20060102")
|
||||||
|
sss := time.Now().UnixNano() / 1e8
|
||||||
|
r := rand.Intn(1000)
|
||||||
|
n := fmt.Sprintf("%s%d%03d", ss, sss, r)
|
||||||
|
return n
|
||||||
|
}
|
31
utils/math.go
Normal file
31
utils/math.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"gitee.ltd/lxh/logger"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mathUtil struct{}
|
||||||
|
|
||||||
|
func MathUtil() *mathUtil {
|
||||||
|
return &mathUtil{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mathUtil) Sqrt(datas []float64, avg float64) float64 {
|
||||||
|
if len(datas) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var aaa float64
|
||||||
|
for _, d := range datas {
|
||||||
|
co := d - avg
|
||||||
|
aaa += co * co
|
||||||
|
}
|
||||||
|
d, err := strconv.ParseFloat(fmt.Sprintf("%.2f", math.Sqrt(aaa/float64(len(datas)))), 64)
|
||||||
|
if err != nil {
|
||||||
|
logger.Say.Errorf("生成标准差失败:%v", err)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
14
utils/page.go
Normal file
14
utils/page.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
// GenTotalPage 计算总页数
|
||||||
|
func GenTotalPage(count int64, size int) int {
|
||||||
|
totalPage := 0
|
||||||
|
if count > 0 {
|
||||||
|
upPage := 0
|
||||||
|
if int(count)%size > 0 {
|
||||||
|
upPage = 1
|
||||||
|
}
|
||||||
|
totalPage = (int(count) / size) + upPage
|
||||||
|
}
|
||||||
|
return totalPage
|
||||||
|
}
|
73
utils/random.go
Normal file
73
utils/random.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
mr "math/rand"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type random struct{}
|
||||||
|
|
||||||
|
func Random() *random {
|
||||||
|
return &random{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRandomInt 获取指定长度的随机数字
|
||||||
|
func (r random) GetRandomInt(len int) string {
|
||||||
|
var numbers = []byte{0, 1, 2, 3, 4, 5, 7, 8, 9}
|
||||||
|
var container string
|
||||||
|
length := bytes.NewReader(numbers).Len()
|
||||||
|
|
||||||
|
for i := 1; i <= len; i++ {
|
||||||
|
rd, err := rand.Int(rand.Reader, big.NewInt(int64(length)))
|
||||||
|
if err != nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
container += fmt.Sprintf("%d", numbers[rd.Int64()])
|
||||||
|
}
|
||||||
|
return container
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRandomNumber 获取指定范围内的一个随机数
|
||||||
|
func (r random) GetRandomNumber(min, max int) int {
|
||||||
|
mr.Seed(time.Now().UnixNano())
|
||||||
|
rn := mr.Intn(max-min) + min
|
||||||
|
return rn
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLiveHouseId 获取腾讯TRTC直播间Id
|
||||||
|
func (r random) GetLiveHouseId() string {
|
||||||
|
id := r.GetRandomNumber(1, 4294967295)
|
||||||
|
return fmt.Sprintf("%d", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRandomString 生成随机字符串
|
||||||
|
func (r random) GetRandomString(len int) string {
|
||||||
|
var container string
|
||||||
|
var str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||||
|
b := bytes.NewBufferString(str)
|
||||||
|
length := b.Len()
|
||||||
|
bigInt := big.NewInt(int64(length))
|
||||||
|
for i := 0; i < len; i++ {
|
||||||
|
randomInt, _ := rand.Int(rand.Reader, bigInt)
|
||||||
|
container += string(str[randomInt.Int64()])
|
||||||
|
}
|
||||||
|
return container
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRandomStringSafe 获取去掉了iI0O1的随机字符串
|
||||||
|
func (r random) GetRandomStringSafe(len int) string {
|
||||||
|
var container string
|
||||||
|
var str = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789"
|
||||||
|
b := bytes.NewBufferString(str)
|
||||||
|
length := b.Len()
|
||||||
|
bigInt := big.NewInt(int64(length))
|
||||||
|
for i := 0; i < len; i++ {
|
||||||
|
randomInt, _ := rand.Int(rand.Reader, bigInt)
|
||||||
|
container += string(str[randomInt.Int64()])
|
||||||
|
}
|
||||||
|
return container
|
||||||
|
}
|
27
utils/time.go
Normal file
27
utils/time.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type timeUtils struct{}
|
||||||
|
|
||||||
|
func TimeUtils() *timeUtils {
|
||||||
|
return &timeUtils{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DurationString Duration转自定义String
|
||||||
|
func (tu timeUtils) DurationString(d time.Duration) string {
|
||||||
|
if d.Seconds() == 0 {
|
||||||
|
return "00:00:00"
|
||||||
|
}
|
||||||
|
s := d.String()
|
||||||
|
s = strings.ReplaceAll(s, "h", ":")
|
||||||
|
s = strings.ReplaceAll(s, "m", ":")
|
||||||
|
idx := strings.Index(s, ".")
|
||||||
|
if idx == -1 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return s[:idx]
|
||||||
|
}
|
20
utils/token.go
Normal file
20
utils/token.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 生成Token的密钥,写死,防止乱改
|
||||||
|
//var jwtSecret = "qSxw4fCBBBecPsws"
|
||||||
|
|
||||||
|
// HashPassword 加密密码
|
||||||
|
func HashPassword(pass *string) {
|
||||||
|
bytePass := []byte(*pass)
|
||||||
|
hPass, _ := bcrypt.GenerateFromPassword(bytePass, bcrypt.DefaultCost)
|
||||||
|
*pass = string(hPass)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComparePassword 校验密码
|
||||||
|
func ComparePassword(dbPass, pass string) bool {
|
||||||
|
return bcrypt.CompareHashAndPassword([]byte(dbPass), []byte(pass)) == nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user