初始化
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