初始化
This commit is contained in:
24
consul/consul.go
Normal file
24
consul/consul.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package consul
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||||
|
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||||
|
"github.com/gogf/gf/contrib/registry/consul/v2"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/net/gsvc"
|
||||||
|
_ "go.mongodb.org/mongo-driver/mongo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
consulCfg, err := g.Cfg().Get(context.Background(), "consul.address")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
consulAddr := consulCfg.String()
|
||||||
|
registry, err := consul.New(consul.WithAddress(consulAddr))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
gsvc.SetRegistry(registry)
|
||||||
|
}
|
||||||
77
http/http.go
Normal file
77
http/http.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"gitee.com/red-future---jilin-g/common/utils"
|
||||||
|
"github.com/gogf/gf/contrib/registry/consul/v2"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/net/gclient"
|
||||||
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
|
"github.com/gogf/gf/v2/net/gsel"
|
||||||
|
"github.com/gogf/gf/v2/net/gsvc"
|
||||||
|
"github.com/gogf/gf/v2/os/glog"
|
||||||
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResponseEmpty struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
const PageSize = 20
|
||||||
|
|
||||||
|
type Page struct {
|
||||||
|
PageNum int `p:"pageNum"` //当前页码
|
||||||
|
PageSize int `p:"pageSize"` //每页数
|
||||||
|
Total int //总页数
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHttpClient(ctx context.Context) (client *gclient.Client, err error) {
|
||||||
|
consulCfg, _ := g.Cfg().Get(context.Background(), "consul.address")
|
||||||
|
consulAddr := consulCfg.String()
|
||||||
|
registry, err := consul.New(consul.WithAddress(consulAddr))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
gsvc.SetRegistry(registry)
|
||||||
|
gsel.SetBuilder(gsel.NewBuilderRoundRobin())
|
||||||
|
client = g.Client()
|
||||||
|
client.SetHeader("Authorization", g.RequestFromCtx(ctx).GetHeader("Authorization"))
|
||||||
|
client.SetDiscovery(gsvc.GetRegistry())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func doRequest(ctx context.Context, method string, url string, target any, data ...any) (err error) {
|
||||||
|
err = utils.ValidStructPtr(target)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
client, err := getHttpClient(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response, err := client.Get(ctx, method, url, data)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err = response.Close(); err != nil {
|
||||||
|
glog.Errorf(ctx, `%+v`, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
result := response.ReadAll()
|
||||||
|
resultStrut := &ghttp.DefaultHandlerResponse{}
|
||||||
|
if gconv.Struct(result, resultStrut); resultStrut.Code != 200 {
|
||||||
|
err = errors.New(resultStrut.Message)
|
||||||
|
} else {
|
||||||
|
gconv.Struct(resultStrut.Data, target)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func Get(ctx context.Context, url string, target any, data ...any) (err error) {
|
||||||
|
err = doRequest(ctx, http.MethodGet, url, target, data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func Post(ctx context.Context, url string, target any, data ...any) (err error) {
|
||||||
|
err = doRequest(ctx, http.MethodPost, url, target, data)
|
||||||
|
return
|
||||||
|
}
|
||||||
75
jaeger/jaeger.go
Normal file
75
jaeger/jaeger.go
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package jaeger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
|
"go.opentelemetry.io/otel"
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
"go.opentelemetry.io/otel/exporters/jaeger"
|
||||||
|
"go.opentelemetry.io/otel/sdk/resource"
|
||||||
|
"go.opentelemetry.io/otel/sdk/trace"
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Tp = new(trace.TracerProvider)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
jaegerAgent, err := g.Cfg().Get(context.Background(), "jaeger.addr")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(gconv.String(jaegerAgent))))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
serverName, err := g.Cfg().Get(context.Background(), "consul.Name")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// 创建一个 TracerProvider,并将 Jaeger exporter 设置为其处理器
|
||||||
|
Tp = trace.NewTracerProvider(
|
||||||
|
// 使用 BatchSpanProcessor 可以提高性能,它会批量发送 span
|
||||||
|
trace.WithBatcher(exp),
|
||||||
|
// 设置资源属性,这些属性会附加到所有导出的 span 上
|
||||||
|
trace.WithResource(resource.NewWithAttributes(
|
||||||
|
semconv.SchemaURL,
|
||||||
|
semconv.ServiceName(gconv.String(serverName)), // 服务名称,在 Jaeger UI 中会显示
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
// 将 TracerProvider 设置为全局,方便在应用的任何地方通过 otel.Tracer() 获取
|
||||||
|
otel.SetTracerProvider(Tp)
|
||||||
|
}
|
||||||
|
func NewTracer(r *ghttp.Request) {
|
||||||
|
// 从传入的上下文中获取 Tracer,或者直接使用全局的
|
||||||
|
tracer := otel.Tracer(r.GetServeHandler().GetMetaTag("summary"))
|
||||||
|
_, span := tracer.Start(r.Context(), r.GetServeHandler().GetMetaTag("summary"))
|
||||||
|
defer span.End() // 非常重要:确保 span 在函数结束时被关闭
|
||||||
|
span.SetAttributes(attribute.String("request", getParams(r)))
|
||||||
|
r.Middleware.Next()
|
||||||
|
span.SetAttributes(attribute.String("response", r.Response.BufferString()))
|
||||||
|
//span.AddEvent("Saying hello is done")
|
||||||
|
}
|
||||||
|
func getParams(r *ghttp.Request) string {
|
||||||
|
params := map[string]interface{}{}
|
||||||
|
if r.Method == "POST" {
|
||||||
|
json.Unmarshal(r.GetBody(), ¶ms) //获取raw传参
|
||||||
|
}
|
||||||
|
if r.Method == "GET" {
|
||||||
|
r.Request.ParseForm()
|
||||||
|
form := r.Form
|
||||||
|
for k, v := range form {
|
||||||
|
if vl, e := strconv.Atoi(v[0]); e == nil {
|
||||||
|
params[k] = vl
|
||||||
|
} else {
|
||||||
|
params[k] = v[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rp, _ := json.Marshal(¶ms)
|
||||||
|
return string(rp)
|
||||||
|
}
|
||||||
96
mongo/mongo.go
Normal file
96
mongo/mongo.go
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package mongo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"gitee.com/red-future---jilin-g/common/utils"
|
||||||
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/os/glog"
|
||||||
|
"github.com/gogf/gf/v2/text/gstr"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
)
|
||||||
|
|
||||||
|
var db = new(mongo.Database)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
link, _ := g.Cfg().Get(context.Background(), "mongo.address")
|
||||||
|
mongoAddr := link.String()
|
||||||
|
client, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoAddr))
|
||||||
|
if err != nil {
|
||||||
|
glog.Error(ctx, "mongodb连接失败")
|
||||||
|
}
|
||||||
|
dbName := gstr.SubStr(mongoAddr, strings.LastIndex(mongoAddr, "/")+1, len(mongoAddr))
|
||||||
|
db = client.Database(dbName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find 查询多条记录
|
||||||
|
func Find(ctx context.Context, filter *primitive.M, result interface{}, collection string, opts ...*options.FindOptions) (err error) {
|
||||||
|
if err = utils.ValidStructPtr(result); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cur, err := db.Collection(collection).Find(ctx, filter, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = cur.All(ctx, result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOne 查询1条记录
|
||||||
|
func FindOne(ctx context.Context, filter *primitive.M, result interface{}, collection string, opts ...*options.FindOneOptions) (err error) {
|
||||||
|
if len(*filter) == 0 {
|
||||||
|
err = gerror.New("缺少查询条件")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = utils.ValidStructPtr(result); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cur := db.Collection(collection).FindOne(ctx, filter, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = cur.Decode(result)
|
||||||
|
if err == mongo.ErrNoDocuments {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 删除记录
|
||||||
|
func Delete(ctx context.Context, filter *primitive.M, collection string, opts ...*options.DeleteOptions) (count int64, err error) {
|
||||||
|
r, err := db.Collection(collection).DeleteMany(ctx, filter, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
count = r.DeletedCount
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update 修改记录
|
||||||
|
func Update(ctx context.Context, filter *primitive.M, update interface{}, result *mongo.UpdateResult, collection string, opts ...*options.UpdateOptions) (err error) {
|
||||||
|
if err = utils.ValidStructPtr(result); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err = db.Collection(collection).UpdateMany(ctx, filter, update, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 修改记录
|
||||||
|
func Insert(ctx context.Context, documents []interface{}, collection string, opts ...*options.InsertManyOptions) (ids []interface{}, err error) {
|
||||||
|
r, err := db.Collection(collection).InsertMany(ctx, documents, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ids = r.InsertedIDs
|
||||||
|
return
|
||||||
|
}
|
||||||
53
utils/utils.go
Normal file
53
utils/utils.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gogf/gf/v2/errors/gcode"
|
||||||
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValidStructPtr 验证是否为结构体指针
|
||||||
|
func ValidStructPtr(req any) (err error) {
|
||||||
|
//验证请求参数必须为指针
|
||||||
|
var (
|
||||||
|
reflectValue reflect.Value
|
||||||
|
reflectKind reflect.Kind
|
||||||
|
)
|
||||||
|
if v, ok := req.(reflect.Value); ok {
|
||||||
|
reflectValue = v
|
||||||
|
} else {
|
||||||
|
reflectValue = reflect.ValueOf(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
reflectKind = reflectValue.Kind()
|
||||||
|
if reflectKind != reflect.Ptr {
|
||||||
|
err = gerror.NewCode(gcode.CodeInvalidParameter, `the parameter "req" for function Find should type of *struct/*[]struct`)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMonthToday 获取N个月前的某日
|
||||||
|
func GetMonthToday(t time.Time, month int) time.Time {
|
||||||
|
// today
|
||||||
|
fmt.Printf("today: [%s]\n", t)
|
||||||
|
// 判断天数范围 小于等于28天的计算,覆盖大多数情况
|
||||||
|
if t.Day() <= 28 {
|
||||||
|
return t.AddDate(0, -month, 0)
|
||||||
|
}
|
||||||
|
// 月份的天数数组
|
||||||
|
monthDay := [13]int{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
||||||
|
// 计算目标所在日期
|
||||||
|
target := t.AddDate(0, 0, 1-t.Day()).AddDate(0, -month, 0)
|
||||||
|
// 计算当月最大天数
|
||||||
|
targetDay := monthDay[target.Month()]
|
||||||
|
// 计算闰年
|
||||||
|
if target.Month() == time.February && (target.Year()%400 == 0 || (target.Year()%100 != 0 && target.Year()%4 == 0)) {
|
||||||
|
targetDay++
|
||||||
|
}
|
||||||
|
if t.Day() > targetDay {
|
||||||
|
return target.AddDate(0, 0, targetDay-1)
|
||||||
|
}
|
||||||
|
return target.AddDate(0, 0, t.Day()-1)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user