refactor: 引入tailwind css & 后端部分非公共包位置调整

This commit is contained in:
meilin.huang
2025-04-18 22:07:37 +08:00
parent 585cbbed23
commit abd2b4bac0
168 changed files with 763 additions and 793 deletions

View File

@@ -1,30 +0,0 @@
package config
import (
"fmt"
"mayfly-go/pkg/utils/assert"
"mayfly-go/pkg/utils/cryptox"
)
type Aes struct {
Key string `yaml:"key"`
}
// 编码并base64
func (a *Aes) EncryptBase64(data []byte) (string, error) {
return cryptox.AesEncryptBase64(data, []byte(a.Key))
}
// base64解码后再aes解码
func (a *Aes) DecryptBase64(data string) ([]byte, error) {
return cryptox.AesDecryptBase64(data, []byte(a.Key))
}
func (a *Aes) Valid() {
if a.Key == "" {
return
}
aesKeyLen := len(a.Key)
assert.IsTrue(aesKeyLen == 16 || aesKeyLen == 24 || aesKeyLen == 32,
fmt.Sprintf("config.yml之 [aes.key] 长度需为16、24、32位长度, 当前为%d位", aesKeyLen))
}

View File

@@ -1,12 +0,0 @@
package config
import "fmt"
const (
AppName = "mayfly-go"
Version = "v1.9.4"
)
func GetAppInfo() string {
return fmt.Sprintf("[%s:%s]", AppName, Version)
}

View File

@@ -1,131 +0,0 @@
package config
import (
"flag"
"fmt"
"mayfly-go/pkg/logx"
"mayfly-go/pkg/utils/ymlx"
"os"
"path/filepath"
"strconv"
)
type ConfigItem interface {
// 验证配置
Valid()
// 如果不存在配置值,则设置默认值
Default()
}
// 配置文件映射对象
var Conf *Config
func Init() {
configFilePath := flag.String("e", "./config.yml", "配置文件路径,默认为可执行文件目录")
flag.Parse()
// 获取启动参数中,配置文件的绝对路径
path, _ := filepath.Abs(*configFilePath)
startConfigParam := &CmdConfigParam{ConfigFilePath: path}
// 读取配置文件信息
yc := &Config{}
if err := ymlx.LoadYml(startConfigParam.ConfigFilePath, yc); err != nil {
logx.Warn(fmt.Sprintf("读取配置文件[%s]失败: %s, 使用系统默认配置或环境变量配置", startConfigParam.ConfigFilePath, err.Error()))
}
// 尝试使用系统环境变量替换配置信息
yc.ReplaceOsEnv()
yc.IfBlankDefaultValue()
// 校验配置文件内容信息
yc.Valid()
Conf = yc
}
// 启动配置参数
type CmdConfigParam struct {
ConfigFilePath string // -e 配置文件路径
}
// yaml配置文件映射对象
type Config struct {
Server Server `yaml:"server"`
Jwt Jwt `yaml:"jwt"`
Aes Aes `yaml:"aes"`
Mysql Mysql `yaml:"mysql"`
Sqlite Sqlite `yaml:"sqlite"`
Redis Redis `yaml:"redis"`
Log Log `yaml:"log"`
}
func (c *Config) IfBlankDefaultValue() {
c.Log.Default()
// 优先初始化log因为后续的一些default方法中会需要用到。统一日志输出
logx.Init(logx.Config{
Level: c.Log.Level,
Type: c.Log.Type,
AddSource: c.Log.AddSource,
Filename: c.Log.File.Name,
Filepath: c.Log.File.Path,
MaxSize: c.Log.File.MaxSize,
MaxAge: c.Log.File.MaxAge,
Compress: c.Log.File.Compress,
})
c.Server.Default()
c.Jwt.Default()
c.Mysql.Default()
c.Sqlite.Default()
}
// 配置文件内容校验
func (c *Config) Valid() {
c.Jwt.Valid()
c.Aes.Valid()
}
// 替换系统环境变量,如果环境变量中存在该值,则优先使用环境变量设定的值
func (c *Config) ReplaceOsEnv() {
serverPort := os.Getenv("MAYFLY_SERVER_PORT")
if serverPort != "" {
if num, err := strconv.Atoi(serverPort); err != nil {
panic("环境变量-[MAYFLY_SERVER_PORT]-服务端口号需为数字")
} else {
c.Server.Port = num
}
}
dbHost := os.Getenv("MAYFLY_DB_HOST")
if dbHost != "" {
c.Mysql.Host = dbHost
}
dbName := os.Getenv("MAYFLY_DB_NAME")
if dbName != "" {
c.Mysql.Dbname = dbName
}
dbUser := os.Getenv("MAYFLY_DB_USER")
if dbUser != "" {
c.Mysql.Username = dbUser
}
dbPwd := os.Getenv("MAYFLY_DB_PASS")
if dbPwd != "" {
c.Mysql.Password = dbPwd
}
sqlitePath := os.Getenv("MAYFLY_SQLITE_PATH")
if sqlitePath != "" {
c.Sqlite.Path = sqlitePath
}
aesKey := os.Getenv("MAYFLY_AES_KEY")
if aesKey != "" {
c.Aes.Key = aesKey
}
jwtKey := os.Getenv("MAYFLY_JWT_KEY")
if jwtKey != "" {
c.Jwt.Key = jwtKey
}
}

View File

@@ -1,34 +0,0 @@
package config
import (
"mayfly-go/pkg/logx"
"mayfly-go/pkg/utils/assert"
"mayfly-go/pkg/utils/stringx"
)
type Jwt struct {
Key string `yaml:"key"`
ExpireTime uint64 `yaml:"expire-time"` // 过期时间,单位分钟
RefreshTokenExpireTime uint64 `yaml:"refresh-token-expire-time"` // 刷新token的过期时间单位分钟
}
func (j *Jwt) Default() {
if j.Key == "" {
// 如果配置文件中的jwt key为空则随机生成字符串
j.Key = stringx.Rand(32)
logx.Warnf("未配置jwt.key, 随机生成key为: %s", j.Key)
}
if j.ExpireTime == 0 {
j.ExpireTime = 1440
logx.Warnf("未配置jwt.expire-time, 默认值: %d", j.ExpireTime)
}
if j.RefreshTokenExpireTime == 0 {
j.RefreshTokenExpireTime = j.ExpireTime * 5
logx.Warnf("未配置jwt.refresh-token-expire-time, 默认值: %d", j.RefreshTokenExpireTime)
}
}
func (j *Jwt) Valid() {
assert.IsTrue(j.ExpireTime != 0, "config.yml之[jwt.expire-time] 不能为空")
}

View File

@@ -1,33 +0,0 @@
package config
import (
"mayfly-go/pkg/logx"
)
type Log struct {
Level string `yaml:"level"`
Type string `yaml:"type"`
AddSource bool `yaml:"add-source"`
File LogFile `yaml:"file"`
}
func (l *Log) Default() {
if l.Level == "" {
l.Level = "info"
logx.Warnf("未配置log.level, 默认值: %s", l.Level)
}
if l.Type == "" {
l.Type = "text"
}
if l.File.Name == "" {
l.File.Name = "mayfly-go.log"
}
}
type LogFile struct {
Name string `yaml:"name"`
Path string `yaml:"path"`
MaxSize int `yaml:"max-size"`
MaxAge int `yaml:"max-age"`
Compress bool `yaml:"compress"`
}

View File

@@ -1,35 +0,0 @@
package config
import "mayfly-go/pkg/logx"
type Mysql struct {
Host string `mapstructure:"path" json:"host" yaml:"host"`
Config string `mapstructure:"config" json:"config" yaml:"config"`
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"`
Username string `mapstructure:"username" json:"username" yaml:"username"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
LogMode bool `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"`
LogZap string `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"`
}
func (m *Mysql) Default() {
if m.Host == "" {
m.Host = "localhost:3306"
logx.Warnf("[使用sqlite可忽略]未配置mysql.host, 默认值: %s", m.Host)
}
if m.Config == "" {
m.Config = "charset=utf8&loc=Local&parseTime=true"
}
if m.MaxIdleConns == 0 {
m.MaxIdleConns = 5
}
if m.MaxOpenConns == 0 {
m.MaxOpenConns = m.MaxIdleConns
}
}
func (m *Mysql) Dsn() string {
return m.Username + ":" + m.Password + "@tcp(" + m.Host + ")/" + m.Dbname + "?" + m.Config
}

View File

@@ -1,8 +0,0 @@
package config
type Redis struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Password string `yaml:"password"`
Db int `yaml:"db"`
}

View File

@@ -1,49 +0,0 @@
package config
import (
"fmt"
"mayfly-go/pkg/i18n"
)
type Server struct {
Lang string `yaml:"lang"`
Port int `yaml:"port"`
Model string `yaml:"model"`
ContextPath string `yaml:"context-path"` // 请求路径上下文
Cors bool `yaml:"cors"`
Tls *Tls `yaml:"tls"`
Static *[]*Static `yaml:"static"`
StaticFile *[]*StaticFile `yaml:"static-file"`
}
func (s *Server) Default() {
if s.Lang == "" {
s.Lang = i18n.Zh_CN
}
if s.Model == "" {
s.Model = "release"
}
if s.Port == 0 {
s.Port = 18888
}
}
func (s *Server) GetPort() string {
return fmt.Sprintf(":%d", s.Port)
}
type Static struct {
RelativePath string `yaml:"relative-path"`
Root string `yaml:"root"`
}
type StaticFile struct {
RelativePath string `yaml:"relative-path"`
Filepath string `yaml:"filepath"`
}
type Tls struct {
Enable bool `yaml:"enable"` // 是否启用tls
KeyFile string `yaml:"key-file"` // 私钥文件路径
CertFile string `yaml:"cert-file"` // 证书文件路径
}

View File

@@ -1,22 +0,0 @@
package config
import "mayfly-go/pkg/logx"
type Sqlite struct {
Path string `mapstructure:"path" json:"path" yaml:"path"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
}
func (m *Sqlite) Default() {
if m.Path == "" {
m.Path = "./mayfly-go.sqlite"
logx.Warnf("[使用mysql可忽略]未配置sqlite.path, 默认值: %s", m.Path)
}
if m.MaxIdleConns == 0 {
m.MaxIdleConns = 5
}
if m.MaxOpenConns == 0 {
m.MaxOpenConns = m.MaxIdleConns
}
}

View File

@@ -17,6 +17,7 @@ import (
const (
InjectTag = "inject"
InjectMethodPrefix = "Inject"
ByTypeComponentName = "T" // 根据类型注入的组件名
)
@@ -74,14 +75,13 @@ func (c *Container) Inject(obj any) error {
// 对所有组件实例执行Inject。即为实例字段注入依赖的组件实例
func (c *Container) InjectComponents() error {
componentsGroups := collx.ArraySplit[*Component](collx.MapValues(c.components), 5)
componentsGroups := collx.ArraySplit[*Component](collx.MapValues(c.components), 10)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
errGroup, _ := errgroup.WithContext(ctx)
for _, components := range componentsGroups {
components := components // 创建局部变量以在闭包中使用
errGroup.Go(func() error {
for _, v := range components {
if err := c.Inject(v.Value); err != nil {
@@ -165,7 +165,7 @@ func (c *Container) GetComponentsByType(fieldType reflect.Type) []*Component {
return components
}
// injectWithField 根据实例字段的inject:"xxx"或injectByType:""标签进行依赖注入
// injectWithField 根据实例字段的inject:"xxx"标签进行依赖注入
func (c *Container) injectWithField(context context.Context, objValue reflect.Value) error {
objValue = structx.Indirect(objValue)
objType := objValue.Type()
@@ -224,7 +224,7 @@ func (c *Container) injectByName(context context.Context, structType reflect.Typ
return fmt.Errorf("%s error: injection types are inconsistent(Expected type -> %s.%s, Component type -> %s.%s)", injectInfo, field.Type.PkgPath(), field.Type.Name(), indirectComponentType.PkgPath(), indirectComponentType.Name())
}
logx.DebugfContext(context, fmt.Sprintf("ioc field inject by name => [%s (%s) -> %s.%s#%s]", componentName, getComponentValueDesc(componentType), structType.PkgPath(), structType.Name(), field.Name))
logx.DebugfContext(context, "ioc field inject by name => [%s (%s) -> %s.%s#%s]", componentName, getComponentValueDesc(componentType), structType.PkgPath(), structType.Name(), field.Name)
if err := setFieldValue(fieldValue, component.Value); err != nil {
return fmt.Errorf("%s error: %s", injectInfo, err.Error())
@@ -244,7 +244,7 @@ func (c *Container) injectByType(context context.Context, structType reflect.Typ
return fmt.Errorf("%s error: %s", injectInfo, err.Error())
}
logx.DebugfContext(context, fmt.Sprintf("ioc field inject by type => [%s.%s (%s) -> %s.%s#%s]", fieldType.PkgPath(), fieldType.Name(), getComponentValueDesc(component.GetType()), structType.PkgPath(), structType.Name(), field.Name))
logx.DebugfContext(context, "ioc field inject by type => [%s.%s (%s) -> %s.%s#%s]", fieldType.PkgPath(), fieldType.Name(), getComponentValueDesc(component.GetType()), structType.PkgPath(), structType.Name(), field.Name)
if err := setFieldValue(fieldValue, component.Value); err != nil {
return fmt.Errorf("%s error: %s", injectInfo, err.Error())
@@ -261,8 +261,8 @@ func (c *Container) injectWithMethod(context context.Context, objValue reflect.V
method := objType.Method(i)
methodName := method.Name
// 不是以Inject开头的函数,则默认跳过
if !strings.HasPrefix(methodName, "Inject") {
// 不是以指定方法名前缀开头的函数,则默认跳过
if !strings.HasPrefix(methodName, InjectMethodPrefix) {
continue
}

View File

@@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"mayfly-go/pkg/cache"
"mayfly-go/pkg/config"
"mayfly-go/pkg/contextx"
"mayfly-go/pkg/errorx"
"mayfly-go/pkg/model"
@@ -107,7 +106,7 @@ type DefaultPermissionCodeRegistry struct {
func (r *DefaultPermissionCodeRegistry) SaveCodes(userId uint64, codes []string) {
if r.cache == nil {
r.cache = cache.NewTimedCache(time.Minute*time.Duration(config.Conf.Jwt.ExpireTime), 5*time.Second)
r.cache = cache.NewTimedCache(time.Minute*time.Duration(jwtConf.ExpireTime), 5*time.Second)
}
r.cache.Put(fmt.Sprintf("%v", userId), codes)
}
@@ -138,7 +137,7 @@ type RedisPermissionCodeRegistry struct {
}
func (r *RedisPermissionCodeRegistry) SaveCodes(userId uint64, codes []string) {
rediscli.Set(fmt.Sprintf("mayfly:%v:codes", userId), anyx.ToString(codes), time.Minute*time.Duration(config.Conf.Jwt.ExpireTime))
rediscli.Set(fmt.Sprintf("mayfly:%v:codes", userId), anyx.ToString(codes), time.Minute*time.Duration(jwtConf.ExpireTime))
}
func (r *RedisPermissionCodeRegistry) HasCode(userId uint64, code string) bool {

View File

@@ -2,15 +2,33 @@ package req
import (
"errors"
"mayfly-go/pkg/config"
"mayfly-go/pkg/utils/stringx"
"time"
"github.com/golang-jwt/jwt/v5"
)
// JwtConf jwt配置
type JwtConf struct {
Key string
ExpireTime uint64 // 过期时间,单位分钟
RefreshTokenExpireTime uint64 // 刷新token的过期时间单位分钟
}
// 默认jwt配置
var jwtConf = JwtConf{
Key: stringx.RandUUID(),
ExpireTime: 60,
RefreshTokenExpireTime: 360,
}
// SetJwtConf 设置jwt配置
func SetJwtConf(conf JwtConf) {
jwtConf = conf
}
// 创建用户token
func CreateToken(userId uint64, username string) (accessToken string, refreshToken string, err error) {
jwtConf := config.Conf.Jwt
now := time.Now()
// 带权限创建令牌
@@ -46,7 +64,7 @@ func ParseToken(tokenStr string) (uint64, string, error) {
// Parse token
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (any, error) {
return []byte(config.Conf.Jwt.Key), nil
return []byte(jwtConf.Key), nil
})
if err != nil || token == nil {
return 0, "", err

View File

@@ -1,20 +0,0 @@
package starter
import (
"fmt"
"mayfly-go/pkg/config"
"mayfly-go/pkg/logx"
"os"
"runtime/debug"
)
func printBanner() {
buildInfo, _ := debug.ReadBuildInfo()
logx.Print(fmt.Sprintf(`
__ _
_ __ ___ __ _ _ _ / _| |_ _ __ _ ___
| '_ ' _ \ / _' | | | | |_| | | | |_____ / _' |/ _ \
| | | | | | (_| | |_| | _| | |_| |_____| (_| | (_) | version: %s | go_version: %s | pid: %d
|_| |_| |_|\__,_|\__, |_| |_|\__, | \__, |\___/
|___/ |___/ |___/ `, config.Version, buildInfo.GoVersion, os.Getpid()))
}

View File

@@ -1,88 +0,0 @@
package starter
import (
"log"
"mayfly-go/pkg/config"
"mayfly-go/pkg/global"
"mayfly-go/pkg/logx"
"time"
"github.com/glebarez/sqlite"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
)
func initDb() {
global.Db = initGormDb()
}
func initGormDb() *gorm.DB {
m := config.Conf.Mysql
// 存在msyql数据库名则优先使用mysql
if m.Dbname != "" {
return initMysql(m)
}
return initSqlite(config.Conf.Sqlite)
}
func initMysql(m config.Mysql) *gorm.DB {
logx.Infof("connecting to mysql [%s]", m.Host)
mysqlConfig := mysql.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
DisableDatetimePrecision: true, // 禁用 datetime 精度MySQL 5.6 之前的数据库不支持
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
DontSupportRenameColumn: true, // 用 `change` 重命名列MySQL 8 之前的数据库和 MariaDB 不支持重命名列
SkipInitializeWithVersion: false, // 根据版本自动配置
}
if db, err := gorm.Open(mysql.New(mysqlConfig), getGormConfig()); err != nil {
logx.Panicf("failed to connect to mysql! [%s]", err.Error())
return nil
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
return db
}
}
func initSqlite(sc config.Sqlite) *gorm.DB {
logx.Infof("connecting to sqlite [%s]", sc.Path)
if db, err := gorm.Open(sqlite.Open(sc.Path), getGormConfig()); err != nil {
logx.Panicf("failed to connect to sqlite! [%s]", err.Error())
return nil
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(sc.MaxIdleConns)
sqlDB.SetMaxOpenConns(sc.MaxOpenConns)
return db
}
}
func getGormConfig() *gorm.Config {
sqlLogLevel := logger.Error
logConf := logx.GetConfig()
// 如果为配置文件中配置的系统日志级别为debug则打印gorm执行的sql信息
if logConf.IsDebug() {
sqlLogLevel = logger.Info
}
gormLogger := logger.New(
log.New(logConf.GetLogOut(), "\r\n", log.LstdFlags), // io writer日志输出的目标前缀和日志包含的内容——译者注
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: sqlLogLevel, // 日志级别, 改为logger.Info即可显示sql语句
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: false, // 禁用彩色打印
},
)
return &gorm.Config{NamingStrategy: schema.NamingStrategy{
TablePrefix: "t_",
SingularTable: true,
}, Logger: gormLogger}
}

View File

@@ -1,36 +0,0 @@
package starter
import (
"context"
"fmt"
"mayfly-go/pkg/config"
"mayfly-go/pkg/logx"
"mayfly-go/pkg/rediscli"
"github.com/redis/go-redis/v9"
)
func initRedis() {
rediscli.SetCli(connRedis())
}
func connRedis() *redis.Client {
// 设置redis客户端
redisConf := config.Conf.Redis
if redisConf.Host == "" {
// logx.Panic("未找到redis配置信息")
return nil
}
logx.Infof("连接redis [%s:%d]", redisConf.Host, redisConf.Port)
rdb := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", redisConf.Host, redisConf.Port),
Password: redisConf.Password, // no password set
DB: redisConf.Db, // use default DB
})
// 测试连接
_, e := rdb.Ping(context.TODO()).Result()
if e != nil {
logx.Panicf("连接redis失败! [%s:%d][%s]", redisConf.Host, redisConf.Port, e.Error())
}
return rdb
}

View File

@@ -1,52 +0,0 @@
package starter
import (
"context"
"mayfly-go/initialize"
"mayfly-go/migration"
"mayfly-go/pkg/config"
"mayfly-go/pkg/global"
"mayfly-go/pkg/logx"
"mayfly-go/pkg/validatorx"
"os"
"os/signal"
"syscall"
)
func RunWebServer() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
cancel()
}()
// 初始化config.yml配置文件映射信息或使用环境变量。并初始化系统日志相关配置
config.Init()
// 打印banner
printBanner()
// 初始化并赋值数据库全局变量
initDb()
// 有配置redis信息则初始化redis。多台机器部署需要使用redis存储验证码、权限、公私钥等
initRedis()
// 数据库升级操作
if err := migration.RunMigrations(global.Db); err != nil {
logx.Panicf("db migration failed: %v", err)
}
// 参数校验器初始化、如错误提示中文转译等
validatorx.Init()
// 初始化其他需要启动时运行的方法
initialize.InitOther()
// 运行web服务
runWebServer(ctx)
}

View File

@@ -1,66 +0,0 @@
package starter
import (
"context"
"errors"
"mayfly-go/initialize"
"mayfly-go/pkg/config"
"mayfly-go/pkg/i18n"
"mayfly-go/pkg/logx"
"mayfly-go/pkg/req"
"net/http"
"time"
sysapp "mayfly-go/internal/sys/application"
"github.com/gin-gonic/gin"
)
func runWebServer(ctx context.Context) {
// 设置gin日志输出器
logOut := logx.GetConfig().GetLogOut()
gin.DefaultErrorWriter = logOut
gin.DefaultWriter = logOut
// 权限处理器
req.UseBeforeHandlerInterceptor(req.PermissionHandler)
// 日志处理器
req.UseAfterHandlerInterceptor(req.LogHandler)
// 设置日志保存函数
req.SetSaveLogFunc(sysapp.GetSyslogApp().SaveFromReq)
i18n.SetLang(config.Conf.Server.Lang)
srv := http.Server{
Addr: config.Conf.Server.GetPort(),
// 注册路由
Handler: initialize.InitRouter(),
}
go func() {
<-ctx.Done()
logx.Info("Shutdown HTTP Server ...")
timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err := srv.Shutdown(timeout)
if err != nil {
logx.Errorf("failed to Shutdown HTTP Server: %v", err)
}
initialize.Terminate()
}()
confSrv := config.Conf.Server
logx.Infof("Listening and serving HTTP on %s", srv.Addr+confSrv.ContextPath)
var err error
if confSrv.Tls != nil && confSrv.Tls.Enable {
err = srv.ListenAndServeTLS(confSrv.Tls.CertFile, confSrv.Tls.KeyFile)
} else {
err = srv.ListenAndServe()
}
if errors.Is(err, http.ErrServerClosed) {
logx.Info("HTTP Server Shutdown")
} else if err != nil {
logx.Errorf("Failed to Start HTTP Server: %v", err)
}
}

View File

@@ -14,13 +14,6 @@ var (
patternErrMsg map[string]string
)
// 注册自定义正则表达式校验规则
func RegisterCustomPatterns() {
// 账号用户名校验
RegisterPattern("account_username", "^[a-zA-Z0-9_]{5,20}$", "只允许输入5-20位大小写字母、数字、下划线")
RegisterPattern("resource_code", "^[a-zA-Z0-9_\\-.:]{1,32}$", "只允许输入1-32位大小写字母、数字、_-.:")
}
// 注册自定义正则表达式
func RegisterPattern(patternName string, regexpStr string, errMsg string) {
if regexpMap == nil {

View File

@@ -50,9 +50,6 @@ func Init() {
// 注册自定义校验器
validate.RegisterValidation(CustomPatternTagName, patternValidFunc)
// 注册自定义正则校验规则
RegisterCustomPatterns()
}
// Translate 翻译错误信息