完成基本的创建使用功能
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package gormx
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type LimitHandler func(db *gorm.DB) *gorm.DB
|
||||
|
||||
func Finder[T any](model T, db *gorm.DB, objs ...LimitHandler) (int64, []T, error) {
|
||||
for _, obj := range objs {
|
||||
db = obj(db)
|
||||
}
|
||||
var models []T
|
||||
err := db.Model(&model).Find(&models).Error
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
var sum int64
|
||||
err = db.Model(&model).Count(&sum).Error
|
||||
return sum, models, err
|
||||
}
|
||||
|
||||
// FinderPage 分页查找
|
||||
func FinderPage[T any](db *gorm.DB, page, limit int, objs ...LimitHandler) (int64, []T, error) {
|
||||
return pageFinder[T](db, pageHandle(page, limit), objs...)
|
||||
}
|
||||
|
||||
func pageFinder[T any](db *gorm.DB, limit LimitHandler, objs ...LimitHandler) (int64, []T, error) {
|
||||
// 定义表
|
||||
var model T
|
||||
db = db.Model(&model)
|
||||
for _, obj := range objs {
|
||||
db = obj(db)
|
||||
}
|
||||
// 查找全部数量
|
||||
var sum int64
|
||||
if err := db.Model(&model).Count(&sum).Error; err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
// 分页查找
|
||||
db = limit(db)
|
||||
var models []T
|
||||
if err := db.Find(&models).Error; err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
return sum, models, nil
|
||||
}
|
||||
|
||||
func pageHandle(page, limit int) LimitHandler {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
// 用户输入起始位
|
||||
var beginIndex int
|
||||
if page < 0 {
|
||||
beginIndex = -1
|
||||
} else {
|
||||
beginIndex = (page - 1) * limit
|
||||
}
|
||||
return db.Offset(beginIndex).Limit(limit)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package gormx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Type string `ini:"type"`
|
||||
DSN string `ini:"dsn"`
|
||||
}
|
||||
|
||||
func New(cfg Config) (db *gorm.DB, err error) {
|
||||
switch cfg.Type {
|
||||
case "sqlite3":
|
||||
// dsn := "exe.db"
|
||||
db, err = gorm.Open(sqlite.Open(cfg.DSN), &gorm.Config{})
|
||||
case "mysql":
|
||||
// dsn := "userRepo:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
db, err = gorm.Open(mysql.Open(cfg.DSN), &gorm.Config{})
|
||||
default:
|
||||
err = errors.New("mode not supported")
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package gormx
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ListInt64 []int64
|
||||
|
||||
// Value 接口,Value 返回 json value any -> string
|
||||
func (j ListInt64) Value() (driver.Value, error) {
|
||||
return json.Marshal(j)
|
||||
}
|
||||
|
||||
// Scan 接口,Scan 将 value 扫描至 Jsonb
|
||||
func (j *ListInt64) Scan(value interface{}) error {
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
|
||||
}
|
||||
err := json.Unmarshal(bytes, j)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListUint []uint
|
||||
|
||||
// Value 接口,Value 返回 json value any -> string
|
||||
func (j ListUint) Value() (driver.Value, error) {
|
||||
return json.Marshal(j)
|
||||
}
|
||||
|
||||
// Scan 接口,Scan 将 value 扫描至 Jsonb
|
||||
func (j *ListUint) Scan(value interface{}) error {
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
|
||||
}
|
||||
err := json.Unmarshal(bytes, j)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListInt []int
|
||||
|
||||
// Value 接口,Value 返回 json value any -> string
|
||||
func (j ListInt) Value() (driver.Value, error) {
|
||||
return json.Marshal(j)
|
||||
}
|
||||
|
||||
// Scan 接口,Scan 将 value 扫描至 Jsonb
|
||||
func (j *ListInt) Scan(value interface{}) error {
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
|
||||
}
|
||||
err := json.Unmarshal(bytes, j)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListString []string
|
||||
|
||||
// Value 接口,Value 返回 json value any -> string
|
||||
func (j ListString) Value() (driver.Value, error) {
|
||||
return json.Marshal(j)
|
||||
}
|
||||
|
||||
// Scan 接口,Scan 将 value 扫描至 Jsonb
|
||||
func (j *ListString) Scan(value interface{}) error {
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
|
||||
}
|
||||
err := json.Unmarshal(bytes, j)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MapString map[string]string
|
||||
|
||||
// Value 接口,Value 返回 json value any -> string
|
||||
func (j MapString) Value() (driver.Value, error) {
|
||||
return json.Marshal(j)
|
||||
}
|
||||
|
||||
// Scan 接口,Scan 将 value 扫描至 Jsonb
|
||||
func (j *MapString) Scan(value interface{}) error {
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
|
||||
}
|
||||
err := json.Unmarshal(bytes, j)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
|
||||
"github.com/rifflock/lfshook"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func Init() {
|
||||
// 添加日志切割输出
|
||||
var hook = NewLfsHook("glogs", time.Hour*12, 6)
|
||||
logrus.AddHook(hook)
|
||||
// 忽略控制台打印
|
||||
logrus.SetOutput(io.Discard)
|
||||
// 展示日志行数
|
||||
logrus.SetReportCaller(true)
|
||||
}
|
||||
|
||||
// NewLfsHook 日志钩子(日志拦截,并重定向)
|
||||
func NewLfsHook(logName string, rotationTime time.Duration, leastDay uint) logrus.Hook {
|
||||
_ = os.Mkdir(logName, os.ModeDir)
|
||||
// 可设置按不同level创建不同的文件名,咱们把6中日志都写到同一个writer中
|
||||
lfsHook := lfshook.NewHook(lfshook.WriterMap{
|
||||
logrus.DebugLevel: NewWriter(filepath.Join(logName, "debug"), rotationTime, leastDay),
|
||||
logrus.InfoLevel: NewWriter(filepath.Join(logName, "info"), rotationTime, leastDay),
|
||||
logrus.WarnLevel: NewWriter(filepath.Join(logName, "warn"), rotationTime, leastDay),
|
||||
logrus.ErrorLevel: NewWriter(filepath.Join(logName, "error"), rotationTime, leastDay),
|
||||
logrus.FatalLevel: NewWriter(filepath.Join(logName, "fatal"), rotationTime, leastDay),
|
||||
logrus.PanicLevel: NewWriter(filepath.Join(logName, "panic"), rotationTime, leastDay),
|
||||
}, nil) //&logrus.JSONFormatter{TimestampFormat: "2006-01-02 15:04:05"}
|
||||
return lfsHook
|
||||
}
|
||||
|
||||
func NewWriter(logName string, rotationTime time.Duration, leastDay uint) io.Writer {
|
||||
writer, err := rotatelogs.New(
|
||||
// 1 日志文件名字
|
||||
logName+".%Y-%m-%d_%H_%M", // _%S
|
||||
// 2 日志周期(默认每86400秒/一天旋转一次)
|
||||
rotatelogs.WithRotationTime(rotationTime),
|
||||
// 3 清除历史 (WithMaxAge和WithRotationCount只能选其一)
|
||||
//rotatelogs.WithMaxAge(time.Hour*24*7), //默认每7天清除下日志文件
|
||||
rotatelogs.WithRotationCount(leastDay), //只保留最近的N个日志文件
|
||||
)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
return writer
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func TestLogger(t *testing.T) {
|
||||
Init()
|
||||
logrus.Infoln("asdadsasd")
|
||||
time.Sleep(5 * time.Second)
|
||||
logrus.Infoln(string(debug.Stack()))
|
||||
logrus.WithFields(logrus.Fields{"RoleUid": "12313123123"}).Warn("asdasd")
|
||||
}
|
||||
|
||||
func TestLogger2(t *testing.T) {
|
||||
str := "goroutine 68 [running]:\\nruntime/debug.Stack()\\n\\tD:/work/environment/GO/src/runtime/debug/stack.go:24 +0x65\\ncolly_v2/pkg/zlib.Try.func1()\\n\\tE:/gopackage2/2023.10/colly_v2/pkg/zlib/try.go:12 "
|
||||
fmt.Println(len([]byte(str)))
|
||||
}
|
||||
|
||||
func TestLogger3(t *testing.T) {
|
||||
fmt.Println(time.Now().Unix() - 259200)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package hash
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// MD5 MD5哈希值
|
||||
func MD5(b []byte) string {
|
||||
h := md5.New()
|
||||
_, _ = h.Write(b)
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
// MD5String MD5哈希值
|
||||
func MD5String(s string) string {
|
||||
return MD5([]byte(s))
|
||||
}
|
||||
|
||||
// SHA1 SHA1哈希值
|
||||
func SHA1(b []byte) string {
|
||||
h := sha1.New()
|
||||
_, _ = h.Write(b)
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
// SHA1String SHA1哈希值
|
||||
func SHA1String(s string) string {
|
||||
return SHA1([]byte(s))
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var uuidint = 0
|
||||
var lock sync.Mutex
|
||||
|
||||
func CreateUUID() string {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
// 生成基于字符串的 UUID
|
||||
key := fmt.Sprintln(Get192Ip(), time.Now().Format("2006-01-02_15-04-05"), uuidint)
|
||||
uuidint++
|
||||
u1 := uuid.NewSHA1(uuid.Nil, []byte(key))
|
||||
return u1.String()
|
||||
}
|
||||
|
||||
func Get192Ip() string {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
for _, iface := range interfaces {
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
ip, _, _ := net.ParseCIDR(addr.String())
|
||||
if ip != nil {
|
||||
ipStr := ip.String()
|
||||
if strings.HasPrefix(ipStr, "192") {
|
||||
return ipStr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user