@@ -38,6 +38,7 @@ require ( | |||
github.com/golang/glog v1.0.0 // indirect | |||
github.com/google/gnostic v0.5.7-v3refs // indirect | |||
github.com/google/gofuzz v1.1.0 // indirect | |||
github.com/gookit/color v1.3.6 // indirect | |||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect | |||
github.com/jinzhu/inflection v1.0.0 // indirect | |||
github.com/josharian/intern v1.0.0 // indirect | |||
@@ -48,12 +49,14 @@ require ( | |||
github.com/modern-go/reflect2 v1.0.2 // indirect | |||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect | |||
github.com/onsi/ginkgo v1.16.5 // indirect | |||
github.com/qiniu/api.v7/v7 v7.8.2 // indirect | |||
github.com/ugorji/go/codec v1.1.7 // indirect | |||
go.uber.org/atomic v1.7.0 // indirect | |||
go.uber.org/multierr v1.6.0 // indirect | |||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect | |||
golang.org/x/net v0.1.0 // indirect | |||
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect | |||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect | |||
golang.org/x/sys v0.1.0 // indirect | |||
golang.org/x/term v0.1.0 // indirect | |||
golang.org/x/text v0.4.0 // indirect | |||
@@ -235,6 +235,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ | |||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= | |||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= | |||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= | |||
github.com/gookit/color v1.3.6 h1:Rgbazd4JO5AgSTVGS3o0nvaSdwdrS8bzvIXwtK6OiMk= | |||
github.com/gookit/color v1.3.6/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= | |||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= | |||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= | |||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | |||
@@ -320,6 +322,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE | |||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | |||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | |||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | |||
github.com/qiniu/api.v7/v7 v7.8.2 h1:f08kI0MmsJNzK4sUS8bG3HDH67ktwd/ji23Gkiy2ra4= | |||
github.com/qiniu/api.v7/v7 v7.8.2/go.mod h1:FPsIqxh1Ym3X01sANE5ZwXfLZSWoCUp5+jNI8cLo3l0= | |||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= | |||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | |||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= | |||
@@ -486,6 +490,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ | |||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= | |||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |||
@@ -3,8 +3,11 @@ package api | |||
import ( | |||
"context" | |||
"gim/internal/business/app" | |||
comm "gim/internal/business/comm" | |||
"gim/internal/business/comm/utils" | |||
"gim/pkg/grpclib" | |||
"gim/pkg/pb" | |||
"strconv" | |||
) | |||
type BusinessExtServer struct{} | |||
@@ -45,3 +48,21 @@ func (s *BusinessExtServer) SearchUser(ctx context.Context, req *pb.SearchUserRe | |||
users, err := app.UserApp.Search(ctx, req.Key, req.MasterId) | |||
return &pb.SearchUserResp{Users: users}, err | |||
} | |||
func (s *BusinessExtServer) CloudUploadFile(ctx context.Context, req *pb.CloudUploadFileReq) (*pb.CloudUploadFileResp, error) { | |||
userId, _, err := grpclib.GetCtxData(ctx) | |||
if err != nil { | |||
return nil, err | |||
} | |||
upload, err := comm.CloudUpload.FileReqUpload(ctx, strconv.FormatInt(userId, 10), req.Dir, req.FileName, utils.StrToInt64(req.FileSize)) | |||
data := utils.SerializeStr(upload) | |||
var result map[string]string | |||
utils.Unserialize([]byte(data), &result) | |||
return &pb.CloudUploadFileResp{ | |||
Method: result["method"], | |||
Host: result["host"], | |||
Key: result["key"], | |||
Token: result["token"], | |||
}, err | |||
} |
@@ -0,0 +1,20 @@ | |||
package app | |||
import ( | |||
"context" | |||
svc "gim/internal/business/comm/service" | |||
"gim/pkg/grpclib" | |||
) | |||
type cloudUpload struct{} | |||
var CloudUpload = new(cloudUpload) | |||
// FileReqUpload 请求文件上传 | |||
func (*cloudUpload) FileReqUpload(ctx context.Context, uid, dirName, fName string, fSize int64) (interface{}, error) { | |||
masterId, _ := grpclib.GetCtxMasterId(ctx) | |||
callbackUrl := svc.SysCfgGet("-1", "cloud_file_upload_call_back_url") | |||
callbackUrl = callbackUrl + masterId | |||
return svc.FileReqUpload(ctx, uid, dirName, fName, callbackUrl, fSize) | |||
} |
@@ -0,0 +1,119 @@ | |||
package db | |||
import ( | |||
"fmt" | |||
"gim/internal/business/comm/db/model" | |||
"gim/internal/business/comm/md" | |||
"gim/internal/business/comm/utils" | |||
"gim/internal/business/comm/utils/logx" | |||
"gim/pkg/db" | |||
"gim/pkg/gerrors" | |||
) | |||
type dbSysCfg struct{} | |||
var DbSysCfg = new(dbSysCfg) | |||
// SysCfgGetAll 获取系统配置 | |||
func (*dbSysCfg) SysCfgGetAll(masterId int64) (*[]model.SysCfg, error) { | |||
var cfgList []model.SysCfg | |||
if err := db.DB.Where("`master_id`=?", masterId).Find(&cfgList).Error; err != nil { | |||
return nil, gerrors.WrapError(err) | |||
} | |||
return &cfgList, nil | |||
} | |||
// SysCfgGetOne 获取一条记录 | |||
func (*dbSysCfg) SysCfgGetOne(key string, masterId int64) (*model.SysCfg, error) { | |||
var cfgList model.SysCfg | |||
if err := db.DB.Where("`key` = ? and `master_id` = ?", key, masterId).First(&cfgList).Error; err != nil { | |||
return nil, gerrors.WrapError(err) | |||
} | |||
return &cfgList, nil | |||
} | |||
// SysCfgInsert 插入一条配置信息 | |||
func (*dbSysCfg) SysCfgInsert(key, val, memo string, masterId int64) bool { | |||
cfg := model.SysCfg{Key: key, Val: val, Memo: memo, MasterId: masterId} | |||
err := db.DB.Create(&cfg).Error | |||
if err != nil { | |||
logx.Error(err) | |||
return false | |||
} | |||
return true | |||
} | |||
// SysCfgUpdate 修改某条配置信息 | |||
func (*dbSysCfg) SysCfgUpdate(key, val, memo string, masterId int64) bool { | |||
cfg := model.SysCfg{Key: key, Val: val, Memo: memo} | |||
err := db.DB.Where("`key` = ? and `master_id` = ?", key, masterId).Update(&cfg).Error | |||
if err != nil { | |||
logx.Error(err) | |||
return false | |||
} | |||
return true | |||
} | |||
// SysCfgGetWithDb 单条记录获取 | |||
func (*dbSysCfg) SysCfgGetWithDb(masterId string, HKey string) string { | |||
cacheKey := fmt.Sprintf(md.AppCfgCacheKey, masterId, HKey[0:1]) | |||
get, err := db.RedisUtil.HGetString(cacheKey, HKey) | |||
if err != nil || get == "" { | |||
cfg, err := DbSysCfg.SysCfgGetOne(HKey, utils.StrToInt64(masterId)) | |||
if err != nil || cfg == nil { | |||
_ = logx.Error(err) | |||
return "" | |||
} | |||
// key是否存在 | |||
cacheKeyExist := false | |||
if db.RedisUtil.Exists(cacheKey) { | |||
cacheKeyExist = true | |||
} | |||
// 设置缓存 | |||
_, err = db.RedisUtil.HSet(cacheKey, HKey, cfg.Val) | |||
if err != nil { | |||
_ = logx.Error(err) | |||
return "" | |||
} | |||
if !cacheKeyExist { // 如果是首次设置 设置过期时间 | |||
_, err := db.RedisUtil.Expire(cacheKey, md.CfgCacheTime) | |||
if err != nil { | |||
_ = logx.Error(err) | |||
return "" | |||
} | |||
} | |||
return cfg.Val | |||
} | |||
return get | |||
} | |||
// SysCfgFindWithDb 多条记录获取 | |||
func (*dbSysCfg) SysCfgFindWithDb(masterId string, keys ...string) map[string]string { | |||
res := map[string]string{} | |||
cacheKey := fmt.Sprintf(md.AppCfgCacheKey, masterId) | |||
err := db.RedisUtil.GetJson(cacheKey, &res) | |||
if err != nil || len(res) == 0 { | |||
cfgList, _ := DbSysCfg.SysCfgGetAll(utils.StrToInt64(masterId)) | |||
if cfgList == nil { | |||
return nil | |||
} | |||
for _, v := range *cfgList { | |||
res[v.Key] = v.Val | |||
} | |||
db.RedisUtil.SetJson(cacheKey, res, md.CfgCacheTime) | |||
} | |||
if len(keys) == 0 { | |||
return res | |||
} | |||
tmp := map[string]string{} | |||
for _, v := range keys { | |||
if val, ok := res[v]; ok { | |||
tmp[v] = val | |||
} else { | |||
tmp[v] = "" | |||
} | |||
} | |||
return tmp | |||
} |
@@ -0,0 +1,8 @@ | |||
package model | |||
type SysCfg struct { | |||
Key string // 键 | |||
Val string // 值 | |||
Memo string // 备注 | |||
MasterId int64 // 站长id | |||
} |
@@ -0,0 +1,7 @@ | |||
package md | |||
// 缓存key统一管理, %s格式化为masterId | |||
const ( | |||
AppCfgCacheKey = "%s:gim_cfg_cache:%s" // 占位符: masterId, key的第一个字母 | |||
CfgCacheTime = 86400 | |||
) |
@@ -0,0 +1,17 @@ | |||
package md | |||
// 获取用户的缓存key | |||
const ( | |||
KEY_SYS_CFG_CACHE = "gim_sys_cfg_cache" | |||
// 文件缓存的key | |||
KEY_CFG_FILE_PVD = "file_provider" // 文件供应商 | |||
KEY_CFG_FILE_BUCKET = "file_bucket" | |||
KEY_CFG_FILE_REGION = "file_bucket_region" | |||
KEY_CFG_FILE_HOST = "file_bucket_host" | |||
KEY_CFG_FILE_SCHEME = "file_bucket_scheme" | |||
KEY_CFG_FILE_AK = "file_access_key" | |||
KEY_CFG_FILE_SK = "file_secret_key" | |||
KEY_CFG_FILE_MAX_SIZE = "file_user_upload_max_size" | |||
KEY_CFG_FILE_EXT = "file_ext" | |||
) |
@@ -0,0 +1,33 @@ | |||
package md | |||
// 用户拥有上传权限的目录, 目录ID | |||
const ( | |||
FILE_DIR_IMAGE = "image" | |||
FILE_DIR_VIDEO = "video" | |||
FILE_DIR_FILE = "file" | |||
) | |||
var ( | |||
FileUserDir = map[string]string{ | |||
FILE_DIR_IMAGE: "1", // 图片上传 | |||
FILE_DIR_VIDEO: "2", // 视频上传 | |||
FILE_DIR_FILE: "3", // 文件上传 | |||
} | |||
) | |||
// 文件回调信息 | |||
type FileCallback struct { | |||
Uid string `json:"uid"` | |||
DirId string `json:"dir_id"` | |||
Provider string `json:"provider"` // 供应商 | |||
FileName string `json:"fname"` // 原文件名 | |||
FileSize string `json:"fsize"` | |||
Hash string `json:"hash"` | |||
Bucket string `json:"bucket"` | |||
Mime string `json:"mime"` | |||
Width string `json:"w,omitempty"` | |||
Height string `json:"h,omitempty"` | |||
Time string `json:"time"` // 默认一个小时内要上传完毕,否则超时 | |||
Sign string `json:"sign"` // 签名 | |||
} |
@@ -0,0 +1,16 @@ | |||
package qiniu | |||
import ( | |||
"github.com/qiniu/api.v7/v7/auth" | |||
"github.com/qiniu/api.v7/v7/storage" | |||
) | |||
func BucketCreate() error { | |||
mac := auth.New(AK, SK) | |||
cfg := storage.Config{ | |||
// 是否使用https域名进行资源管理 | |||
UseHTTPS: false, | |||
} | |||
bucketManager := storage.NewBucketManager(mac, &cfg) | |||
return bucketManager.CreateBucket("", storage.RIDHuanan) | |||
} |
@@ -0,0 +1,18 @@ | |||
package qiniu | |||
import ( | |||
"github.com/qiniu/api.v7/v7/auth" | |||
"github.com/qiniu/api.v7/v7/storage" | |||
) | |||
func BucketDelete(bucketName string) error { | |||
mac := auth.New(AK, SK) | |||
cfg := storage.Config{ | |||
// 是否使用https域名进行资源管理 | |||
UseHTTPS: false, | |||
} | |||
bucketManager := storage.NewBucketManager(mac, &cfg) | |||
return bucketManager.DropBucket(bucketName) | |||
} |
@@ -0,0 +1,18 @@ | |||
package qiniu | |||
import ( | |||
"github.com/qiniu/api.v7/v7/auth" | |||
"github.com/qiniu/api.v7/v7/storage" | |||
) | |||
func BucketGetDomain(bucketName string) (string, error) { | |||
mac := auth.New(AK, SK) | |||
cfg := storage.Config{UseHTTPS: false} | |||
bucketManager := storage.NewBucketManager(mac, &cfg) | |||
b, err := bucketManager.ListBucketDomains(bucketName) | |||
if err != nil { | |||
return "", err | |||
} | |||
return b[0].Domain, nil | |||
} |
@@ -0,0 +1,22 @@ | |||
package qiniu | |||
import ( | |||
"gim/internal/business/comm/utils" | |||
) | |||
var ( | |||
AK = "MmxNdai23egjNUHjdzEVaTPdPCIbWzENz9BQuak3" | |||
SK = "mElaFlM9O16rXp-ihoQdJ9KOH56naKm3MoyQBA59" | |||
BUCKET = "dev-fnuoos" // 桶子名称 | |||
BUCKET_SCHEME = "http" | |||
BUCKET_REGION = "up-z2.qiniup.com" | |||
Expires uint64 = 3600 | |||
) | |||
func Init(ak, sk, bucket, region, scheme string) { | |||
AK, SK, BUCKET, BUCKET_REGION, BUCKET_SCHEME = ak, sk, bucket, region, scheme | |||
} | |||
func Sign(t string) string { | |||
return utils.Md5(AK + SK + t) | |||
} |
@@ -0,0 +1,42 @@ | |||
package qiniu | |||
import ( | |||
"gim/internal/business/comm/md" | |||
"gim/internal/business/comm/utils" | |||
"time" | |||
"github.com/qiniu/api.v7/v7/auth/qbox" | |||
_ "github.com/qiniu/api.v7/v7/conf" | |||
"github.com/qiniu/api.v7/v7/storage" | |||
) | |||
// 请求图片上传地址信息 | |||
func ReqImgUpload(f *md.FileCallback, callbackUrl string) interface{} { | |||
if ext := utils.FileExt(f.FileName); ext == "png" || ext == "jpg" || ext == "jpeg" || ext == "gif" || ext == "bmp" || ext == "webp" { | |||
f.Width = "$(imageInfo.width)" | |||
f.Height = "$(imageInfo.height)" | |||
} | |||
f.Provider = "qiniu" | |||
f.FileSize = "$(fsize)" | |||
f.Hash = "$(etag)" | |||
f.Bucket = "$(bucket)" | |||
f.Mime = "$(mimeType)" | |||
f.Time = utils.Int64ToStr(time.Now().Unix()) | |||
f.Sign = Sign(f.Time) | |||
putPolicy := storage.PutPolicy{ | |||
Scope: BUCKET + ":" + f.FileName, // 使用覆盖方式时候必须请求里面有key,否则报错 | |||
Expires: Expires, | |||
ForceSaveKey: true, | |||
SaveKey: f.FileName, | |||
//MimeLimit: "image/*", // 只允许上传图片 | |||
CallbackURL: callbackUrl, | |||
CallbackBody: utils.SerializeStr(f), | |||
CallbackBodyType: "application/json", | |||
} | |||
return &struct { | |||
Method string `json:"method"` | |||
Key string `json:"key"` | |||
Host string `json:"host"` | |||
Token string `json:"token"` | |||
}{Key: f.FileName, Method: "POST", Host: BUCKET_SCHEME + "://" + BUCKET_REGION, Token: putPolicy.UploadToken(qbox.NewMac(AK, SK))} | |||
} |
@@ -0,0 +1,92 @@ | |||
package svc | |||
import ( | |||
"context" | |||
"errors" | |||
"fmt" | |||
"gim/internal/business/comm/md" | |||
"gim/internal/business/comm/service/qiniu" | |||
"gim/internal/business/comm/utils" | |||
"gim/internal/business/comm/utils/logx" | |||
"strings" | |||
) | |||
// 请求文件上传 | |||
func FileReqUpload(ctx context.Context, uid, dirName, fName, callbackUrl string, fSize int64) (interface{}, error) { | |||
ext := utils.FileExt(fName) | |||
if err := initStg(ctx, fSize, ext); err != nil { | |||
return nil, err | |||
} | |||
newName := dirName + "_" + fmt.Sprintf("%010s", uid) | |||
// 默认都加时间戳 | |||
newName += "_" + utils.FormatNanoUnix() + utils.RandString(4, "0123456789") | |||
newName += "." + ext | |||
f := &md.FileCallback{ | |||
Uid: uid, | |||
DirId: md.FileUserDir[dirName], | |||
FileName: newName, | |||
} | |||
return qiniu.ReqImgUpload(f, callbackUrl), nil | |||
} | |||
func initStg(ctx context.Context, fSize int64, ext string) error { | |||
// 获取上传配置 | |||
stgInfo := SysCfgFind( | |||
ctx, | |||
md.KEY_CFG_FILE_BUCKET, | |||
md.KEY_CFG_FILE_HOST, | |||
md.KEY_CFG_FILE_AK, | |||
md.KEY_CFG_FILE_SK, | |||
md.KEY_CFG_FILE_PVD, | |||
md.KEY_CFG_FILE_REGION, | |||
md.KEY_CFG_FILE_MAX_SIZE, | |||
md.KEY_CFG_FILE_EXT, | |||
md.KEY_CFG_FILE_SCHEME, | |||
) | |||
if stgInfo == nil { | |||
return errors.New("获取配置信息出错") | |||
} | |||
// todo 目前仅支持七牛 | |||
if v, ok := stgInfo[md.KEY_CFG_FILE_PVD]; !ok || v != "qiniu" { | |||
return errors.New("file_provider error") | |||
} | |||
if v, ok := stgInfo[md.KEY_CFG_FILE_REGION]; !ok || v == "" { | |||
return errors.New("file_bucket_region error") | |||
} | |||
if v, ok := stgInfo[md.KEY_CFG_FILE_AK]; !ok || v == "" { | |||
return errors.New("file_access_key error") | |||
} | |||
if v, ok := stgInfo[md.KEY_CFG_FILE_SK]; !ok || v == "" { | |||
return errors.New("file_secret_key error") | |||
} | |||
if v, ok := stgInfo[md.KEY_CFG_FILE_BUCKET]; !ok || v == "" { | |||
return errors.New("file_bucket error") | |||
} | |||
if v, ok := stgInfo[md.KEY_CFG_FILE_SCHEME]; !ok || v == "" { | |||
stgInfo[md.KEY_CFG_FILE_SCHEME] = "http" | |||
SysCfgSet(ctx, md.KEY_CFG_FILE_SCHEME, stgInfo[md.KEY_CFG_FILE_SCHEME], "文件域名HTTP协议") | |||
} | |||
qiniu.Init(stgInfo[md.KEY_CFG_FILE_AK], stgInfo[md.KEY_CFG_FILE_SK], stgInfo[md.KEY_CFG_FILE_BUCKET], stgInfo[md.KEY_CFG_FILE_REGION], stgInfo[md.KEY_CFG_FILE_SCHEME]) | |||
if v, ok := stgInfo[md.KEY_CFG_FILE_HOST]; !ok || v == "" { | |||
var err error | |||
stgInfo[md.KEY_CFG_FILE_HOST], err = qiniu.BucketGetDomain(stgInfo[md.KEY_CFG_FILE_BUCKET]) | |||
if err != nil { | |||
logx.Error(err) | |||
return errors.New("服务器配置错误") | |||
} | |||
SysCfgSet(ctx, md.KEY_CFG_FILE_HOST, stgInfo[md.KEY_CFG_FILE_HOST], "文件域名地址") | |||
} | |||
// 检查文件大小限制 | |||
if v, ok := stgInfo[md.KEY_CFG_FILE_MAX_SIZE]; ok && v != "" && utils.StrToInt64(v) < fSize { | |||
return errors.New("file_user_upload_max_size error") | |||
} | |||
// 检查文件后缀 | |||
if v, ok := stgInfo[md.KEY_CFG_FILE_EXT]; ok && v != "" && !strings.Contains(v, ext) { | |||
return errors.New("file_ext error") | |||
} | |||
return nil | |||
} |
@@ -0,0 +1,106 @@ | |||
package svc | |||
import ( | |||
"context" | |||
"fmt" | |||
"gim/internal/business/comm/db" | |||
"gim/internal/business/comm/md" | |||
"gim/internal/business/comm/utils" | |||
db2 "gim/pkg/db" | |||
"gim/pkg/grpclib" | |||
) | |||
// 单挑记录获取 | |||
func SysCfgGet(masterId, key string) string { | |||
return db.DbSysCfg.SysCfgGetWithDb(masterId, key) | |||
} | |||
// 多条记录获取 | |||
func SysCfgFind(ctx context.Context, keys ...string) map[string]string { | |||
masterId, _ := grpclib.GetCtxMasterId(ctx) | |||
tmp := SysCfgFindComm(masterId, keys...) | |||
return tmp | |||
} | |||
// SysCfgGetByMasterId get one config by master id | |||
func SysCfgGetByMasterId(masterId, key string) string { | |||
res := SysCfgFindComm(masterId, key) | |||
if _, ok := res[key]; !ok { | |||
return "" | |||
} | |||
return res[key] | |||
} | |||
// SysCfgFindComm get cfg by master id | |||
func SysCfgFindComm(masterId string, keys ...string) map[string]string { | |||
res := map[string]string{} | |||
cfgKey := fmt.Sprintf("%s:gim_cfg_cache", masterId) | |||
err := db2.RedisUtil.GetJson(cfgKey, &res) | |||
if err != nil || len(res) == 0 { | |||
cfgList, _ := db.DbSysCfg.SysCfgGetAll(utils.StrToInt64(masterId)) | |||
if cfgList == nil { | |||
return nil | |||
} | |||
for _, v := range *cfgList { | |||
res[v.Key] = v.Val | |||
} | |||
db2.RedisUtil.SetJson(cfgKey, res, 1800) | |||
} | |||
if len(keys) == 0 { | |||
return res | |||
} | |||
tmp := map[string]string{} | |||
for _, v := range keys { | |||
if val, ok := res[v]; ok { | |||
tmp[v] = val | |||
} else { | |||
tmp[v] = "" | |||
} | |||
} | |||
return tmp | |||
} | |||
// EgSysCfgFind 多条记录获取 | |||
func EgSysCfgFind(masterId string, keys ...string) map[string]string { | |||
res := map[string]string{} | |||
if len(res) == 0 { | |||
cfgList, _ := db.DbSysCfg.SysCfgGetAll(utils.StrToInt64(masterId)) | |||
if cfgList == nil { | |||
return nil | |||
} | |||
for _, v := range *cfgList { | |||
res[v.Key] = v.Val | |||
} | |||
} | |||
if len(keys) == 0 { | |||
return res | |||
} | |||
tmp := map[string]string{} | |||
for _, v := range keys { | |||
if val, ok := res[v]; ok { | |||
tmp[v] = val | |||
} else { | |||
tmp[v] = "" | |||
} | |||
} | |||
return tmp | |||
} | |||
// SysCfgCleanCache 清理系统配置信息 | |||
func SysCfgCleanCache() { | |||
db2.RedisUtil.Del(md.KEY_SYS_CFG_CACHE) | |||
} | |||
// SysCfgSet 写入系统设置 | |||
func SysCfgSet(ctx context.Context, key, val, memo string) bool { | |||
masterId, _ := grpclib.GetCtxMasterId(ctx) | |||
cfg, err := db.DbSysCfg.SysCfgGetOne(key, utils.StrToInt64(masterId)) | |||
if err != nil || cfg == nil { | |||
return db.DbSysCfg.SysCfgInsert(key, val, memo, utils.StrToInt64(masterId)) | |||
} | |||
if memo != "" && cfg.Memo != memo { | |||
cfg.Memo = memo | |||
} | |||
SysCfgCleanCache() | |||
return db.DbSysCfg.SysCfgUpdate(key, val, cfg.Memo, utils.StrToInt64(masterId)) | |||
} |
@@ -0,0 +1,117 @@ | |||
package utils | |||
import ( | |||
"encoding/base64" | |||
"fmt" | |||
"regexp" | |||
) | |||
const ( | |||
Base64Std = iota | |||
Base64Url | |||
Base64RawStd | |||
Base64RawUrl | |||
) | |||
func Base64StdEncode(str interface{}) string { | |||
return Base64Encode(str, Base64Std) | |||
} | |||
func Base64StdDecode(str interface{}) string { | |||
return Base64Decode(str, Base64Std) | |||
} | |||
func Base64UrlEncode(str interface{}) string { | |||
return Base64Encode(str, Base64Url) | |||
} | |||
func Base64UrlDecode(str interface{}) string { | |||
return Base64Decode(str, Base64Url) | |||
} | |||
func Base64RawStdEncode(str interface{}) string { | |||
return Base64Encode(str, Base64RawStd) | |||
} | |||
func Base64RawStdDecode(str interface{}) string { | |||
return Base64Decode(str, Base64RawStd) | |||
} | |||
func Base64RawUrlEncode(str interface{}) string { | |||
return Base64Encode(str, Base64RawUrl) | |||
} | |||
func Base64RawUrlDecode(str interface{}) string { | |||
return Base64Decode(str, Base64RawUrl) | |||
} | |||
func Base64Encode(str interface{}, encode int) string { | |||
newEncode := base64Encode(encode) | |||
if newEncode == nil { | |||
return "" | |||
} | |||
switch v := str.(type) { | |||
case string: | |||
return newEncode.EncodeToString([]byte(v)) | |||
case []byte: | |||
return newEncode.EncodeToString(v) | |||
} | |||
return newEncode.EncodeToString([]byte(fmt.Sprint(str))) | |||
} | |||
func Base64Decode(str interface{}, encode int) string { | |||
var err error | |||
var b []byte | |||
newEncode := base64Encode(encode) | |||
if newEncode == nil { | |||
return "" | |||
} | |||
switch v := str.(type) { | |||
case string: | |||
b, err = newEncode.DecodeString(v) | |||
case []byte: | |||
b, err = newEncode.DecodeString(string(v)) | |||
default: | |||
return "" | |||
} | |||
if err != nil { | |||
return "" | |||
} | |||
return string(b) | |||
} | |||
func base64Encode(encode int) *base64.Encoding { | |||
switch encode { | |||
case Base64Std: | |||
return base64.StdEncoding | |||
case Base64Url: | |||
return base64.URLEncoding | |||
case Base64RawStd: | |||
return base64.RawStdEncoding | |||
case Base64RawUrl: | |||
return base64.RawURLEncoding | |||
default: | |||
return nil | |||
} | |||
} | |||
func JudgeBase64(str string) bool { | |||
pattern := "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$" | |||
matched, err := regexp.MatchString(pattern, str) | |||
if err != nil { | |||
return false | |||
} | |||
if !(len(str)%4 == 0 && matched) { | |||
return false | |||
} | |||
unCodeStr, err := base64.StdEncoding.DecodeString(str) | |||
if err != nil { | |||
return false | |||
} | |||
tranStr := base64.StdEncoding.EncodeToString(unCodeStr) | |||
//return str==base64.StdEncoding.EncodeToString(unCodeStr) | |||
if str == tranStr { | |||
return true | |||
} | |||
return false | |||
} |
@@ -0,0 +1,369 @@ | |||
package utils | |||
import ( | |||
"encoding/binary" | |||
"encoding/json" | |||
"fmt" | |||
"math" | |||
"strconv" | |||
"strings" | |||
) | |||
func ToString(raw interface{}, e error) (res string) { | |||
if e != nil { | |||
return "" | |||
} | |||
return AnyToString(raw) | |||
} | |||
func ToInt64(raw interface{}, e error) int64 { | |||
if e != nil { | |||
return 0 | |||
} | |||
return AnyToInt64(raw) | |||
} | |||
func Float64ToStrPrec4(f float64) string { | |||
return strconv.FormatFloat(f, 'f', 4, 64) | |||
} | |||
func AnyToBool(raw interface{}) bool { | |||
switch i := raw.(type) { | |||
case float32, float64, int, int64, uint, uint8, uint16, uint32, uint64, int8, int16, int32: | |||
return i != 0 | |||
case []byte: | |||
return i != nil | |||
case string: | |||
if i == "false" { | |||
return false | |||
} | |||
return i != "" | |||
case error: | |||
return false | |||
case nil: | |||
return true | |||
} | |||
val := fmt.Sprint(raw) | |||
val = strings.TrimLeft(val, "&") | |||
if strings.TrimLeft(val, "{}") == "" { | |||
return false | |||
} | |||
if strings.TrimLeft(val, "[]") == "" { | |||
return false | |||
} | |||
// ptr type | |||
b, err := json.Marshal(raw) | |||
if err != nil { | |||
return false | |||
} | |||
if strings.TrimLeft(string(b), "\"\"") == "" { | |||
return false | |||
} | |||
if strings.TrimLeft(string(b), "{}") == "" { | |||
return false | |||
} | |||
return true | |||
} | |||
func AnyToInt64(raw interface{}) int64 { | |||
switch i := raw.(type) { | |||
case string: | |||
res, _ := strconv.ParseInt(i, 10, 64) | |||
return res | |||
case []byte: | |||
return BytesToInt64(i) | |||
case int: | |||
return int64(i) | |||
case int64: | |||
return i | |||
case uint: | |||
return int64(i) | |||
case uint8: | |||
return int64(i) | |||
case uint16: | |||
return int64(i) | |||
case uint32: | |||
return int64(i) | |||
case uint64: | |||
return int64(i) | |||
case int8: | |||
return int64(i) | |||
case int16: | |||
return int64(i) | |||
case int32: | |||
return int64(i) | |||
case float32: | |||
return int64(i) | |||
case float64: | |||
return int64(i) | |||
case error: | |||
return 0 | |||
case bool: | |||
if i { | |||
return 1 | |||
} | |||
return 0 | |||
} | |||
return 0 | |||
} | |||
func AnyToString(raw interface{}) string { | |||
switch i := raw.(type) { | |||
case []byte: | |||
return string(i) | |||
case int: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int64: | |||
return strconv.FormatInt(i, 10) | |||
case float32: | |||
return Float64ToStr(float64(i)) | |||
case float64: | |||
return Float64ToStr(i) | |||
case uint: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint8: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint16: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint32: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint64: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int8: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int16: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int32: | |||
return strconv.FormatInt(int64(i), 10) | |||
case string: | |||
return i | |||
case error: | |||
return i.Error() | |||
case bool: | |||
return strconv.FormatBool(i) | |||
} | |||
return fmt.Sprintf("%#v", raw) | |||
} | |||
func AnyToFloat64(raw interface{}) float64 { | |||
switch i := raw.(type) { | |||
case []byte: | |||
f, _ := strconv.ParseFloat(string(i), 64) | |||
return f | |||
case int: | |||
return float64(i) | |||
case int64: | |||
return float64(i) | |||
case float32: | |||
return float64(i) | |||
case float64: | |||
return i | |||
case uint: | |||
return float64(i) | |||
case uint8: | |||
return float64(i) | |||
case uint16: | |||
return float64(i) | |||
case uint32: | |||
return float64(i) | |||
case uint64: | |||
return float64(i) | |||
case int8: | |||
return float64(i) | |||
case int16: | |||
return float64(i) | |||
case int32: | |||
return float64(i) | |||
case string: | |||
f, _ := strconv.ParseFloat(i, 64) | |||
return f | |||
case bool: | |||
if i { | |||
return 1 | |||
} | |||
} | |||
return 0 | |||
} | |||
func ToByte(raw interface{}, e error) []byte { | |||
if e != nil { | |||
return []byte{} | |||
} | |||
switch i := raw.(type) { | |||
case string: | |||
return []byte(i) | |||
case int: | |||
return Int64ToBytes(int64(i)) | |||
case int64: | |||
return Int64ToBytes(i) | |||
case float32: | |||
return Float32ToByte(i) | |||
case float64: | |||
return Float64ToByte(i) | |||
case uint: | |||
return Int64ToBytes(int64(i)) | |||
case uint8: | |||
return Int64ToBytes(int64(i)) | |||
case uint16: | |||
return Int64ToBytes(int64(i)) | |||
case uint32: | |||
return Int64ToBytes(int64(i)) | |||
case uint64: | |||
return Int64ToBytes(int64(i)) | |||
case int8: | |||
return Int64ToBytes(int64(i)) | |||
case int16: | |||
return Int64ToBytes(int64(i)) | |||
case int32: | |||
return Int64ToBytes(int64(i)) | |||
case []byte: | |||
return i | |||
case error: | |||
return []byte(i.Error()) | |||
case bool: | |||
if i { | |||
return []byte("true") | |||
} | |||
return []byte("false") | |||
} | |||
return []byte(fmt.Sprintf("%#v", raw)) | |||
} | |||
func Int64ToBytes(i int64) []byte { | |||
var buf = make([]byte, 8) | |||
binary.BigEndian.PutUint64(buf, uint64(i)) | |||
return buf | |||
} | |||
func BytesToInt64(buf []byte) int64 { | |||
return int64(binary.BigEndian.Uint64(buf)) | |||
} | |||
func StrToInt(s string) int { | |||
res, _ := strconv.Atoi(s) | |||
return res | |||
} | |||
func StrToInt64(s string) int64 { | |||
res, _ := strconv.ParseInt(s, 10, 64) | |||
return res | |||
} | |||
func Float32ToByte(float float32) []byte { | |||
bits := math.Float32bits(float) | |||
bytes := make([]byte, 4) | |||
binary.LittleEndian.PutUint32(bytes, bits) | |||
return bytes | |||
} | |||
func ByteToFloat32(bytes []byte) float32 { | |||
bits := binary.LittleEndian.Uint32(bytes) | |||
return math.Float32frombits(bits) | |||
} | |||
func Float64ToByte(float float64) []byte { | |||
bits := math.Float64bits(float) | |||
bytes := make([]byte, 8) | |||
binary.LittleEndian.PutUint64(bytes, bits) | |||
return bytes | |||
} | |||
func ByteToFloat64(bytes []byte) float64 { | |||
bits := binary.LittleEndian.Uint64(bytes) | |||
return math.Float64frombits(bits) | |||
} | |||
func Float64ToStr(f float64) string { | |||
return strconv.FormatFloat(f, 'f', 2, 64) | |||
} | |||
func Float64ToStrPrec1(f float64) string { | |||
return strconv.FormatFloat(f, 'f', 1, 64) | |||
} | |||
func Float64ToStrByPrec(f float64, prec int) string { | |||
return strconv.FormatFloat(f, 'f', prec, 64) | |||
} | |||
func Float32ToStr(f float32) string { | |||
return Float64ToStr(float64(f)) | |||
} | |||
func StrToFloat64(s string) float64 { | |||
res, err := strconv.ParseFloat(s, 64) | |||
if err != nil { | |||
return 0 | |||
} | |||
return res | |||
} | |||
func StrToFormat(s string, prec int) string { | |||
ex := strings.Split(s, ".") | |||
if len(ex) == 2 { | |||
if StrToFloat64(ex[1]) == 0 { //小数点后面为空就是不要小数点了 | |||
return ex[0] | |||
} | |||
//看取多少位 | |||
str := ex[1] | |||
str1 := str | |||
if prec < len(str) { | |||
str1 = str[0:prec] | |||
} else { | |||
for i := 0; i < prec-len(str); i++ { | |||
str1 += "0" | |||
} | |||
} | |||
if prec > 0 { | |||
return ex[0] + "." + str1 | |||
} else { | |||
return ex[0] | |||
} | |||
} | |||
return s | |||
} | |||
func StrToFloat32(s string) float32 { | |||
res, err := strconv.ParseFloat(s, 32) | |||
if err != nil { | |||
return 0 | |||
} | |||
return float32(res) | |||
} | |||
func StrToBool(s string) bool { | |||
b, _ := strconv.ParseBool(s) | |||
return b | |||
} | |||
func BoolToStr(b bool) string { | |||
if b { | |||
return "true" | |||
} | |||
return "false" | |||
} | |||
func FloatToInt64(f float64) int64 { | |||
return int64(f) | |||
} | |||
func IntToStr(i int) string { | |||
return strconv.Itoa(i) | |||
} | |||
func Int64ToStr(i int64) string { | |||
return strconv.FormatInt(i, 10) | |||
} | |||
func IntToFloat64(i int) float64 { | |||
s := strconv.Itoa(i) | |||
res, err := strconv.ParseFloat(s, 64) | |||
if err != nil { | |||
return 0 | |||
} | |||
return res | |||
} | |||
func Int64ToFloat64(i int64) float64 { | |||
s := strconv.FormatInt(i, 10) | |||
res, err := strconv.ParseFloat(s, 64) | |||
if err != nil { | |||
return 0 | |||
} | |||
return res | |||
} |
@@ -0,0 +1,209 @@ | |||
package utils | |||
import ( | |||
"bytes" | |||
"crypto/tls" | |||
"fmt" | |||
"io" | |||
"io/ioutil" | |||
"net/http" | |||
"net/url" | |||
"sort" | |||
"strings" | |||
"time" | |||
) | |||
var CurlDebug bool | |||
func CurlGet(router string, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodGet, router, nil, header) | |||
} | |||
func CurlGetJson(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl_new(http.MethodGet, router, body, header) | |||
} | |||
// 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string | |||
func CurlPost(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodPost, router, body, header) | |||
} | |||
func CurlPut(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodPut, router, body, header) | |||
} | |||
// 只支持form 与json 提交, 请留意body的类型, 支持string, []byte, map[string]string | |||
func CurlPatch(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodPatch, router, body, header) | |||
} | |||
// CurlDelete is curl delete | |||
func CurlDelete(router string, body interface{}, header map[string]string) ([]byte, error) { | |||
return curl(http.MethodDelete, router, body, header) | |||
} | |||
func curl(method, router string, body interface{}, header map[string]string) ([]byte, error) { | |||
var reqBody io.Reader | |||
contentType := "application/json" | |||
switch v := body.(type) { | |||
case string: | |||
reqBody = strings.NewReader(v) | |||
case []byte: | |||
reqBody = bytes.NewReader(v) | |||
case map[string]string: | |||
val := url.Values{} | |||
for k, v := range v { | |||
val.Set(k, v) | |||
} | |||
reqBody = strings.NewReader(val.Encode()) | |||
contentType = "application/x-www-form-urlencoded" | |||
case map[string]interface{}: | |||
val := url.Values{} | |||
for k, v := range v { | |||
val.Set(k, v.(string)) | |||
} | |||
reqBody = strings.NewReader(val.Encode()) | |||
contentType = "application/x-www-form-urlencoded" | |||
} | |||
if header == nil { | |||
header = map[string]string{"Content-Type": contentType} | |||
} | |||
if _, ok := header["Content-Type"]; !ok { | |||
header["Content-Type"] = contentType | |||
} | |||
resp, er := CurlReq(method, router, reqBody, header) | |||
if er != nil { | |||
return nil, er | |||
} | |||
res, err := ioutil.ReadAll(resp.Body) | |||
if CurlDebug { | |||
blob := SerializeStr(body) | |||
if contentType != "application/json" { | |||
blob = HttpBuild(body) | |||
} | |||
fmt.Printf("\n\n=====================\n[url]: %s\n[time]: %s\n[method]: %s\n[content-type]: %v\n[req_header]: %s\n[req_body]: %#v\n[resp_err]: %v\n[resp_header]: %v\n[resp_body]: %v\n=====================\n\n", | |||
router, | |||
time.Now().Format("2006-01-02 15:04:05.000"), | |||
method, | |||
contentType, | |||
HttpBuildQuery(header), | |||
blob, | |||
err, | |||
SerializeStr(resp.Header), | |||
string(res), | |||
) | |||
} | |||
resp.Body.Close() | |||
return res, err | |||
} | |||
func curl_new(method, router string, body interface{}, header map[string]string) ([]byte, error) { | |||
var reqBody io.Reader | |||
contentType := "application/json" | |||
if header == nil { | |||
header = map[string]string{"Content-Type": contentType} | |||
} | |||
if _, ok := header["Content-Type"]; !ok { | |||
header["Content-Type"] = contentType | |||
} | |||
resp, er := CurlReq(method, router, reqBody, header) | |||
if er != nil { | |||
return nil, er | |||
} | |||
res, err := ioutil.ReadAll(resp.Body) | |||
if CurlDebug { | |||
blob := SerializeStr(body) | |||
if contentType != "application/json" { | |||
blob = HttpBuild(body) | |||
} | |||
fmt.Printf("\n\n=====================\n[url]: %s\n[time]: %s\n[method]: %s\n[content-type]: %v\n[req_header]: %s\n[req_body]: %#v\n[resp_err]: %v\n[resp_header]: %v\n[resp_body]: %v\n=====================\n\n", | |||
router, | |||
time.Now().Format("2006-01-02 15:04:05.000"), | |||
method, | |||
contentType, | |||
HttpBuildQuery(header), | |||
blob, | |||
err, | |||
SerializeStr(resp.Header), | |||
string(res), | |||
) | |||
} | |||
resp.Body.Close() | |||
return res, err | |||
} | |||
func CurlReq(method, router string, reqBody io.Reader, header map[string]string) (*http.Response, error) { | |||
req, _ := http.NewRequest(method, router, reqBody) | |||
if header != nil { | |||
for k, v := range header { | |||
req.Header.Set(k, v) | |||
} | |||
} | |||
// 绕过github等可能因为特征码返回503问题 | |||
// https://www.imwzk.com/posts/2021-03-14-why-i-always-get-503-with-golang/ | |||
defaultCipherSuites := []uint16{0xc02f, 0xc030, 0xc02b, 0xc02c, 0xcca8, 0xcca9, 0xc013, 0xc009, | |||
0xc014, 0xc00a, 0x009c, 0x009d, 0x002f, 0x0035, 0xc012, 0x000a} | |||
client := &http.Client{ | |||
Transport: &http.Transport{ | |||
TLSClientConfig: &tls.Config{ | |||
InsecureSkipVerify: true, | |||
CipherSuites: append(defaultCipherSuites[8:], defaultCipherSuites[:8]...), | |||
}, | |||
}, | |||
// 获取301重定向 | |||
CheckRedirect: func(req *http.Request, via []*http.Request) error { | |||
return http.ErrUseLastResponse | |||
}, | |||
} | |||
return client.Do(req) | |||
} | |||
// 组建get请求参数,sortAsc true为小到大,false为大到小,nil不排序 a=123&b=321 | |||
func HttpBuildQuery(args map[string]string, sortAsc ...bool) string { | |||
str := "" | |||
if len(args) == 0 { | |||
return str | |||
} | |||
if len(sortAsc) > 0 { | |||
keys := make([]string, 0, len(args)) | |||
for k := range args { | |||
keys = append(keys, k) | |||
} | |||
if sortAsc[0] { | |||
sort.Strings(keys) | |||
} else { | |||
sort.Sort(sort.Reverse(sort.StringSlice(keys))) | |||
} | |||
for _, k := range keys { | |||
str += "&" + k + "=" + args[k] | |||
} | |||
} else { | |||
for k, v := range args { | |||
str += "&" + k + "=" + v | |||
} | |||
} | |||
return str[1:] | |||
} | |||
func HttpBuild(body interface{}, sortAsc ...bool) string { | |||
params := map[string]string{} | |||
if args, ok := body.(map[string]interface{}); ok { | |||
for k, v := range args { | |||
params[k] = AnyToString(v) | |||
} | |||
return HttpBuildQuery(params, sortAsc...) | |||
} | |||
if args, ok := body.(map[string]string); ok { | |||
for k, v := range args { | |||
params[k] = AnyToString(v) | |||
} | |||
return HttpBuildQuery(params, sortAsc...) | |||
} | |||
if args, ok := body.(map[string]int); ok { | |||
for k, v := range args { | |||
params[k] = AnyToString(v) | |||
} | |||
return HttpBuildQuery(params, sortAsc...) | |||
} | |||
return AnyToString(body) | |||
} |
@@ -0,0 +1,22 @@ | |||
package utils | |||
import ( | |||
"os" | |||
"path" | |||
"strings" | |||
"time" | |||
) | |||
// 获取文件后缀 | |||
func FileExt(fname string) string { | |||
return strings.ToLower(strings.TrimLeft(path.Ext(fname), ".")) | |||
} | |||
func FilePutContents(fileName string, content string) { | |||
fd, _ := os.OpenFile("./tmp/"+fileName+".log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) | |||
fd_time := time.Now().Format("2006-01-02 15:04:05") | |||
fd_content := strings.Join([]string{"[", fd_time, "] ", content, "\n"}, "") | |||
buf := []byte(fd_content) | |||
fd.Write(buf) | |||
fd.Close() | |||
} |
@@ -0,0 +1,245 @@ | |||
package logx | |||
import ( | |||
"os" | |||
"strings" | |||
"time" | |||
"go.uber.org/zap" | |||
"go.uber.org/zap/zapcore" | |||
) | |||
type LogConfig struct { | |||
AppName string `yaml:"app_name" json:"app_name" toml:"app_name"` | |||
Level string `yaml:"level" json:"level" toml:"level"` | |||
StacktraceLevel string `yaml:"stacktrace_level" json:"stacktrace_level" toml:"stacktrace_level"` | |||
IsStdOut bool `yaml:"is_stdout" json:"is_stdout" toml:"is_stdout"` | |||
TimeFormat string `yaml:"time_format" json:"time_format" toml:"time_format"` // second, milli, nano, standard, iso, | |||
Encoding string `yaml:"encoding" json:"encoding" toml:"encoding"` // console, json | |||
Skip int `yaml:"skip" json:"skip" toml:"skip"` | |||
IsFileOut bool `yaml:"is_file_out" json:"is_file_out" toml:"is_file_out"` | |||
FileDir string `yaml:"file_dir" json:"file_dir" toml:"file_dir"` | |||
FileName string `yaml:"file_name" json:"file_name" toml:"file_name"` | |||
FileMaxSize int `yaml:"file_max_size" json:"file_max_size" toml:"file_max_size"` | |||
FileMaxAge int `yaml:"file_max_age" json:"file_max_age" toml:"file_max_age"` | |||
} | |||
var ( | |||
l *LogX = defaultLogger() | |||
conf *LogConfig | |||
) | |||
// default logger setting | |||
func defaultLogger() *LogX { | |||
conf = &LogConfig{ | |||
Level: "debug", | |||
StacktraceLevel: "error", | |||
IsStdOut: true, | |||
TimeFormat: "standard", | |||
Encoding: "console", | |||
Skip: 2, | |||
} | |||
writers := []zapcore.WriteSyncer{os.Stdout} | |||
lg, lv := newZapLogger(setLogLevel(conf.Level), setLogLevel(conf.StacktraceLevel), conf.Encoding, conf.TimeFormat, conf.Skip, zapcore.NewMultiWriteSyncer(writers...)) | |||
zap.RedirectStdLog(lg) | |||
return &LogX{logger: lg, atomLevel: lv} | |||
} | |||
// initial standard log, if you don't init, it will use default logger setting | |||
func InitDefaultLogger(cfg *LogConfig) { | |||
var writers []zapcore.WriteSyncer | |||
if cfg.IsStdOut || (!cfg.IsStdOut && !cfg.IsFileOut) { | |||
writers = append(writers, os.Stdout) | |||
} | |||
if cfg.IsFileOut { | |||
writers = append(writers, NewRollingFile(cfg.FileDir, cfg.FileName, cfg.FileMaxSize, cfg.FileMaxAge)) | |||
} | |||
lg, lv := newZapLogger(setLogLevel(cfg.Level), setLogLevel(cfg.StacktraceLevel), cfg.Encoding, cfg.TimeFormat, cfg.Skip, zapcore.NewMultiWriteSyncer(writers...)) | |||
zap.RedirectStdLog(lg) | |||
if cfg.AppName != "" { | |||
lg = lg.With(zap.String("app", cfg.AppName)) // 加上应用名称 | |||
} | |||
l = &LogX{logger: lg, atomLevel: lv} | |||
} | |||
// create a new logger | |||
func NewLogger(cfg *LogConfig) *LogX { | |||
var writers []zapcore.WriteSyncer | |||
if cfg.IsStdOut || (!cfg.IsStdOut && !cfg.IsFileOut) { | |||
writers = append(writers, os.Stdout) | |||
} | |||
if cfg.IsFileOut { | |||
writers = append(writers, NewRollingFile(cfg.FileDir, cfg.FileName, cfg.FileMaxSize, cfg.FileMaxAge)) | |||
} | |||
lg, lv := newZapLogger(setLogLevel(cfg.Level), setLogLevel(cfg.StacktraceLevel), cfg.Encoding, cfg.TimeFormat, cfg.Skip, zapcore.NewMultiWriteSyncer(writers...)) | |||
zap.RedirectStdLog(lg) | |||
if cfg.AppName != "" { | |||
lg = lg.With(zap.String("app", cfg.AppName)) // 加上应用名称 | |||
} | |||
return &LogX{logger: lg, atomLevel: lv} | |||
} | |||
// create a new zaplog logger | |||
func newZapLogger(level, stacktrace zapcore.Level, encoding, timeType string, skip int, output zapcore.WriteSyncer) (*zap.Logger, *zap.AtomicLevel) { | |||
encCfg := zapcore.EncoderConfig{ | |||
TimeKey: "T", | |||
LevelKey: "L", | |||
NameKey: "N", | |||
CallerKey: "C", | |||
MessageKey: "M", | |||
StacktraceKey: "S", | |||
LineEnding: zapcore.DefaultLineEnding, | |||
EncodeCaller: zapcore.ShortCallerEncoder, | |||
EncodeDuration: zapcore.NanosDurationEncoder, | |||
EncodeLevel: zapcore.LowercaseLevelEncoder, | |||
} | |||
setTimeFormat(timeType, &encCfg) // set time type | |||
atmLvl := zap.NewAtomicLevel() // set level | |||
atmLvl.SetLevel(level) | |||
encoder := zapcore.NewJSONEncoder(encCfg) // 确定encoder格式 | |||
if encoding == "console" { | |||
encoder = zapcore.NewConsoleEncoder(encCfg) | |||
} | |||
return zap.New(zapcore.NewCore(encoder, output, atmLvl), zap.AddCaller(), zap.AddStacktrace(stacktrace), zap.AddCallerSkip(skip)), &atmLvl | |||
} | |||
// set log level | |||
func setLogLevel(lvl string) zapcore.Level { | |||
switch strings.ToLower(lvl) { | |||
case "panic": | |||
return zapcore.PanicLevel | |||
case "fatal": | |||
return zapcore.FatalLevel | |||
case "error": | |||
return zapcore.ErrorLevel | |||
case "warn", "warning": | |||
return zapcore.WarnLevel | |||
case "info": | |||
return zapcore.InfoLevel | |||
default: | |||
return zapcore.DebugLevel | |||
} | |||
} | |||
// set time format | |||
func setTimeFormat(timeType string, z *zapcore.EncoderConfig) { | |||
switch strings.ToLower(timeType) { | |||
case "iso": // iso8601 standard | |||
z.EncodeTime = zapcore.ISO8601TimeEncoder | |||
case "sec": // only for unix second, without millisecond | |||
z.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | |||
enc.AppendInt64(t.Unix()) | |||
} | |||
case "second": // unix second, with millisecond | |||
z.EncodeTime = zapcore.EpochTimeEncoder | |||
case "milli", "millisecond": // millisecond | |||
z.EncodeTime = zapcore.EpochMillisTimeEncoder | |||
case "nano", "nanosecond": // nanosecond | |||
z.EncodeTime = zapcore.EpochNanosTimeEncoder | |||
default: // standard format | |||
z.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | |||
enc.AppendString(t.Format("2006-01-02 15:04:05.000")) | |||
} | |||
} | |||
} | |||
func GetLevel() string { | |||
switch l.atomLevel.Level() { | |||
case zapcore.PanicLevel: | |||
return "panic" | |||
case zapcore.FatalLevel: | |||
return "fatal" | |||
case zapcore.ErrorLevel: | |||
return "error" | |||
case zapcore.WarnLevel: | |||
return "warn" | |||
case zapcore.InfoLevel: | |||
return "info" | |||
default: | |||
return "debug" | |||
} | |||
} | |||
func SetLevel(lvl string) { | |||
l.atomLevel.SetLevel(setLogLevel(lvl)) | |||
} | |||
// temporary add call skip | |||
func AddCallerSkip(skip int) *LogX { | |||
l.logger.WithOptions(zap.AddCallerSkip(skip)) | |||
return l | |||
} | |||
// permanent add call skip | |||
func AddDepth(skip int) *LogX { | |||
l.logger = l.logger.WithOptions(zap.AddCallerSkip(skip)) | |||
return l | |||
} | |||
// permanent add options | |||
func AddOptions(opts ...zap.Option) *LogX { | |||
l.logger = l.logger.WithOptions(opts...) | |||
return l | |||
} | |||
func AddField(k string, v interface{}) { | |||
l.logger.With(zap.Any(k, v)) | |||
} | |||
func AddFields(fields map[string]interface{}) *LogX { | |||
for k, v := range fields { | |||
l.logger.With(zap.Any(k, v)) | |||
} | |||
return l | |||
} | |||
// Normal log | |||
func Debug(e interface{}, args ...interface{}) error { | |||
return l.Debug(e, args...) | |||
} | |||
func Info(e interface{}, args ...interface{}) error { | |||
return l.Info(e, args...) | |||
} | |||
func Warn(e interface{}, args ...interface{}) error { | |||
return l.Warn(e, args...) | |||
} | |||
func Error(e interface{}, args ...interface{}) error { | |||
return l.Error(e, args...) | |||
} | |||
func Panic(e interface{}, args ...interface{}) error { | |||
return l.Panic(e, args...) | |||
} | |||
func Fatal(e interface{}, args ...interface{}) error { | |||
return l.Fatal(e, args...) | |||
} | |||
// Format logs | |||
func Debugf(format string, args ...interface{}) error { | |||
return l.Debugf(format, args...) | |||
} | |||
func Infof(format string, args ...interface{}) error { | |||
return l.Infof(format, args...) | |||
} | |||
func Warnf(format string, args ...interface{}) error { | |||
return l.Warnf(format, args...) | |||
} | |||
func Errorf(format string, args ...interface{}) error { | |||
return l.Errorf(format, args...) | |||
} | |||
func Panicf(format string, args ...interface{}) error { | |||
return l.Panicf(format, args...) | |||
} | |||
func Fatalf(format string, args ...interface{}) error { | |||
return l.Fatalf(format, args...) | |||
} | |||
func formatFieldMap(m FieldMap) []Field { | |||
var res []Field | |||
for k, v := range m { | |||
res = append(res, zap.Any(k, v)) | |||
} | |||
return res | |||
} |
@@ -0,0 +1,105 @@ | |||
package logx | |||
import ( | |||
"bytes" | |||
"io" | |||
"os" | |||
"path/filepath" | |||
"time" | |||
"gopkg.in/natefinch/lumberjack.v2" | |||
) | |||
// output interface | |||
type WriteSyncer interface { | |||
io.Writer | |||
Sync() error | |||
} | |||
// split writer | |||
func NewRollingFile(dir, filename string, maxSize, MaxAge int) WriteSyncer { | |||
s, err := os.Stat(dir) | |||
if err != nil || !s.IsDir() { | |||
os.RemoveAll(dir) | |||
if err := os.MkdirAll(dir, 0766); err != nil { | |||
panic(err) | |||
} | |||
} | |||
return newLumberjackWriteSyncer(&lumberjack.Logger{ | |||
Filename: filepath.Join(dir, filename), | |||
MaxSize: maxSize, // megabytes, MB | |||
MaxAge: MaxAge, // days | |||
LocalTime: true, | |||
Compress: false, | |||
}) | |||
} | |||
type lumberjackWriteSyncer struct { | |||
*lumberjack.Logger | |||
buf *bytes.Buffer | |||
logChan chan []byte | |||
closeChan chan interface{} | |||
maxSize int | |||
} | |||
func newLumberjackWriteSyncer(l *lumberjack.Logger) *lumberjackWriteSyncer { | |||
ws := &lumberjackWriteSyncer{ | |||
Logger: l, | |||
buf: bytes.NewBuffer([]byte{}), | |||
logChan: make(chan []byte, 5000), | |||
closeChan: make(chan interface{}), | |||
maxSize: 1024, | |||
} | |||
go ws.run() | |||
return ws | |||
} | |||
func (l *lumberjackWriteSyncer) run() { | |||
ticker := time.NewTicker(1 * time.Second) | |||
for { | |||
select { | |||
case <-ticker.C: | |||
if l.buf.Len() > 0 { | |||
l.sync() | |||
} | |||
case bs := <-l.logChan: | |||
_, err := l.buf.Write(bs) | |||
if err != nil { | |||
continue | |||
} | |||
if l.buf.Len() > l.maxSize { | |||
l.sync() | |||
} | |||
case <-l.closeChan: | |||
l.sync() | |||
return | |||
} | |||
} | |||
} | |||
func (l *lumberjackWriteSyncer) Stop() { | |||
close(l.closeChan) | |||
} | |||
func (l *lumberjackWriteSyncer) Write(bs []byte) (int, error) { | |||
b := make([]byte, len(bs)) | |||
for i, c := range bs { | |||
b[i] = c | |||
} | |||
l.logChan <- b | |||
return 0, nil | |||
} | |||
func (l *lumberjackWriteSyncer) Sync() error { | |||
return nil | |||
} | |||
func (l *lumberjackWriteSyncer) sync() error { | |||
defer l.buf.Reset() | |||
_, err := l.Logger.Write(l.buf.Bytes()) | |||
if err != nil { | |||
return err | |||
} | |||
return nil | |||
} |
@@ -0,0 +1,192 @@ | |||
package logx | |||
import ( | |||
"errors" | |||
"fmt" | |||
"strconv" | |||
"go.uber.org/zap" | |||
) | |||
type LogX struct { | |||
logger *zap.Logger | |||
atomLevel *zap.AtomicLevel | |||
} | |||
type Field = zap.Field | |||
type FieldMap map[string]interface{} | |||
// 判断其他类型--start | |||
func getFields(msg string, format bool, args ...interface{}) (string, []Field) { | |||
var str []interface{} | |||
var fields []zap.Field | |||
if len(args) > 0 { | |||
for _, v := range args { | |||
if f, ok := v.(Field); ok { | |||
fields = append(fields, f) | |||
} else if f, ok := v.(FieldMap); ok { | |||
fields = append(fields, formatFieldMap(f)...) | |||
} else { | |||
str = append(str, AnyToString(v)) | |||
} | |||
} | |||
if format { | |||
return fmt.Sprintf(msg, str...), fields | |||
} | |||
str = append([]interface{}{msg}, str...) | |||
return fmt.Sprintln(str...), fields | |||
} | |||
return msg, []Field{} | |||
} | |||
func (l *LogX) Debug(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Debug(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Info(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Info(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Warn(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Warn(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Error(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Error(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) DPanic(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.DPanic(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Panic(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Panic(msg, field...) | |||
} | |||
return e | |||
} | |||
func (l *LogX) Fatal(s interface{}, args ...interface{}) error { | |||
es, e := checkErr(s) | |||
if es != "" { | |||
msg, field := getFields(es, false, args...) | |||
l.logger.Fatal(msg, field...) | |||
} | |||
return e | |||
} | |||
func checkErr(s interface{}) (string, error) { | |||
switch e := s.(type) { | |||
case error: | |||
return e.Error(), e | |||
case string: | |||
return e, errors.New(e) | |||
case []byte: | |||
return string(e), nil | |||
default: | |||
return "", nil | |||
} | |||
} | |||
func (l *LogX) LogError(err error) error { | |||
return l.Error(err.Error()) | |||
} | |||
func (l *LogX) Debugf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Debug(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Infof(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Info(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Warnf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Warn(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Errorf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Error(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) DPanicf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.DPanic(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Panicf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Panic(s, f...) | |||
return errors.New(s) | |||
} | |||
func (l *LogX) Fatalf(msg string, args ...interface{}) error { | |||
s, f := getFields(msg, true, args...) | |||
l.logger.Fatal(s, f...) | |||
return errors.New(s) | |||
} | |||
func AnyToString(raw interface{}) string { | |||
switch i := raw.(type) { | |||
case []byte: | |||
return string(i) | |||
case int: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int64: | |||
return strconv.FormatInt(i, 10) | |||
case float32: | |||
return strconv.FormatFloat(float64(i), 'f', 2, 64) | |||
case float64: | |||
return strconv.FormatFloat(i, 'f', 2, 64) | |||
case uint: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint8: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint16: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint32: | |||
return strconv.FormatInt(int64(i), 10) | |||
case uint64: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int8: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int16: | |||
return strconv.FormatInt(int64(i), 10) | |||
case int32: | |||
return strconv.FormatInt(int64(i), 10) | |||
case string: | |||
return i | |||
case error: | |||
return i.Error() | |||
} | |||
return fmt.Sprintf("%#v", raw) | |||
} |
@@ -0,0 +1,12 @@ | |||
package utils | |||
import ( | |||
"crypto/md5" | |||
"encoding/hex" | |||
) | |||
func Md5(str string) string { | |||
h := md5.New() | |||
h.Write([]byte(str)) | |||
return hex.EncodeToString(h.Sum(nil)) | |||
} |
@@ -0,0 +1,46 @@ | |||
package utils | |||
import ( | |||
crand "crypto/rand" | |||
"fmt" | |||
"math/big" | |||
"math/rand" | |||
"time" | |||
) | |||
func RandString(l int, c ...string) string { | |||
var ( | |||
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | |||
str string | |||
num *big.Int | |||
) | |||
if len(c) > 0 { | |||
chars = c[0] | |||
} | |||
chrLen := int64(len(chars)) | |||
for len(str) < l { | |||
num, _ = crand.Int(crand.Reader, big.NewInt(chrLen)) | |||
str += string(chars[num.Int64()]) | |||
} | |||
return str | |||
} | |||
func RandNum() string { | |||
seed := time.Now().UnixNano() + rand.Int63() | |||
return fmt.Sprintf("%05v", rand.New(rand.NewSource(seed)).Int31n(1000000)) | |||
} | |||
//x的y次方 | |||
func RandPow(l int) string { | |||
var i = "1" | |||
for j := 0; j < l; j++ { | |||
i += "0" | |||
} | |||
k := StrToInt64(i) | |||
n := rand.New(rand.NewSource(time.Now().UnixNano())).Int63n(k) | |||
ls := "%0" + IntToStr(l) + "v" | |||
str := fmt.Sprintf(ls, n) | |||
//min := int(math.Pow10(l - 1)) | |||
//max := int(math.Pow10(l) - 1) | |||
return str | |||
} |
@@ -0,0 +1,29 @@ | |||
package utils | |||
import ( | |||
"errors" | |||
"fmt" | |||
) | |||
type Error string | |||
func (err Error) Error() string { return string(err) } | |||
var ErrNil = errors.New("redigo: nil returned") | |||
func Bytes(reply interface{}, err error) ([]byte, error) { | |||
if err != nil { | |||
return nil, err | |||
} | |||
switch reply := reply.(type) { | |||
case []byte: | |||
return reply, nil | |||
case string: | |||
return []byte(reply), nil | |||
case nil: | |||
return nil, ErrNil | |||
case Error: | |||
return nil, reply | |||
} | |||
return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply) | |||
} |
@@ -0,0 +1,23 @@ | |||
package utils | |||
import ( | |||
"encoding/json" | |||
) | |||
func Serialize(data interface{}) []byte { | |||
res, err := json.Marshal(data) | |||
if err != nil { | |||
return []byte{} | |||
} | |||
return res | |||
} | |||
func Unserialize(b []byte, dst interface{}) { | |||
if err := json.Unmarshal(b, dst); err != nil { | |||
dst = nil | |||
} | |||
} | |||
func SerializeStr(data interface{}, arg ...interface{}) string { | |||
return string(Serialize(data)) | |||
} |
@@ -0,0 +1,208 @@ | |||
package utils | |||
import ( | |||
"errors" | |||
"fmt" | |||
"strconv" | |||
"strings" | |||
"time" | |||
) | |||
func StrToTime(s string) (int64, error) { | |||
// delete all not int characters | |||
if s == "" { | |||
return time.Now().Unix(), nil | |||
} | |||
r := make([]rune, 14) | |||
l := 0 | |||
// 过滤除数字以外的字符 | |||
for _, v := range s { | |||
if '0' <= v && v <= '9' { | |||
r[l] = v | |||
l++ | |||
if l == 14 { | |||
break | |||
} | |||
} | |||
} | |||
for l < 14 { | |||
r[l] = '0' // 补0 | |||
l++ | |||
} | |||
t, err := time.Parse("20060102150405", string(r)) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return t.Unix(), nil | |||
} | |||
func TimeToStr(unixSecTime interface{}, layout ...string) string { | |||
i := AnyToInt64(unixSecTime) | |||
if i == 0 { | |||
return "" | |||
} | |||
f := "2006-01-02 15:04:05" | |||
if len(layout) > 0 { | |||
f = layout[0] | |||
} | |||
return time.Unix(i, 0).Format(f) | |||
} | |||
func FormatNanoUnix() string { | |||
return strings.Replace(time.Now().Format("20060102150405.0000000"), ".", "", 1) | |||
} | |||
func TimeParse(format, src string) (time.Time, error) { | |||
return time.ParseInLocation(format, src, time.Local) | |||
} | |||
func TimeParseStd(src string) time.Time { | |||
t, _ := TimeParse("2006-01-02 15:04:05", src) | |||
return t | |||
} | |||
func TimeStdParseUnix(src string) int64 { | |||
t, err := TimeParse("2006-01-02 15:04:05", src) | |||
if err != nil { | |||
return 0 | |||
} | |||
return t.Unix() | |||
} | |||
// 获取一个当前时间 时间间隔 时间戳 | |||
func GetTimeInterval(unit string, amount int) (startTime, endTime int64) { | |||
t := time.Now() | |||
nowTime := t.Unix() | |||
tmpTime := int64(0) | |||
switch unit { | |||
case "years": | |||
tmpTime = time.Date(t.Year()+amount, t.Month(), t.Day(), t.Hour(), 0, 0, 0, t.Location()).Unix() | |||
case "months": | |||
tmpTime = time.Date(t.Year(), t.Month()+time.Month(amount), t.Day(), t.Hour(), 0, 0, 0, t.Location()).Unix() | |||
case "days": | |||
tmpTime = time.Date(t.Year(), t.Month(), t.Day()+amount, t.Hour(), 0, 0, 0, t.Location()).Unix() | |||
case "hours": | |||
tmpTime = time.Date(t.Year(), t.Month(), t.Day(), t.Hour()+amount, 0, 0, 0, t.Location()).Unix() | |||
} | |||
if amount > 0 { | |||
startTime = nowTime | |||
endTime = tmpTime | |||
} else { | |||
startTime = tmpTime | |||
endTime = nowTime | |||
} | |||
return | |||
} | |||
// 几天前 | |||
func TimeInterval(newTime int) string { | |||
now := time.Now().Unix() | |||
newTime64 := AnyToInt64(newTime) | |||
if newTime64 >= now { | |||
return "刚刚" | |||
} | |||
interval := now - newTime64 | |||
switch { | |||
case interval < 60: | |||
return AnyToString(interval) + "秒前" | |||
case interval < 60*60: | |||
return AnyToString(interval/60) + "分前" | |||
case interval < 60*60*24: | |||
return AnyToString(interval/60/60) + "小时前" | |||
case interval < 60*60*24*30: | |||
return AnyToString(interval/60/60/24) + "天前" | |||
case interval < 60*60*24*30*12: | |||
return AnyToString(interval/60/60/24/30) + "月前" | |||
default: | |||
return AnyToString(interval/60/60/24/30/12) + "年前" | |||
} | |||
} | |||
// 时分秒字符串转时间戳,传入示例:8:40 or 8:40:10 | |||
func HmsToUnix(str string) (int64, error) { | |||
t := time.Now() | |||
arr := strings.Split(str, ":") | |||
if len(arr) < 2 { | |||
return 0, errors.New("Time format error") | |||
} | |||
h, _ := strconv.Atoi(arr[0]) | |||
m, _ := strconv.Atoi(arr[1]) | |||
s := 0 | |||
if len(arr) == 3 { | |||
s, _ = strconv.Atoi(arr[3]) | |||
} | |||
formatted1 := fmt.Sprintf("%d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(), h, m, s) | |||
res, err := time.ParseInLocation("20060102150405", formatted1, time.Local) | |||
if err != nil { | |||
return 0, err | |||
} else { | |||
return res.Unix(), nil | |||
} | |||
} | |||
// 获取特定时间范围 | |||
func GetTimeRange(s string) map[string]int64 { | |||
t := time.Now() | |||
var stime, etime time.Time | |||
switch s { | |||
case "today": | |||
stime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "yesterday": | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-1, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
case "within_seven_days": | |||
// 前6天0点 | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-6, 0, 0, 0, 0, t.Location()) | |||
// 明天 0点 | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "current_month": | |||
stime = GetFirstDateOfMonth(t) | |||
etime = time.Now() | |||
case "last_month": | |||
etime = GetFirstDateOfMonth(t) | |||
monthTimes := TimeStdParseUnix(etime.Format("2006-01-02 15:04:05")) - 86400 | |||
times, _ := UnixToTime(Int64ToStr(monthTimes)) | |||
stime = GetFirstDateOfMonth(times) | |||
} | |||
return map[string]int64{ | |||
"start": stime.Unix(), | |||
"end": etime.Unix(), | |||
} | |||
} | |||
//时间戳转时间格式 | |||
func UnixToTime(e string) (datatime time.Time, err error) { | |||
data, err := strconv.ParseInt(e, 10, 64) | |||
datatime = time.Unix(data, 0) | |||
return | |||
} | |||
//获取传入的时间所在月份的第一天,即某月第一天的0点。如传入time.Now(), 返回当前月份的第一天0点时间。 | |||
func GetFirstDateOfMonth(d time.Time) time.Time { | |||
d = d.AddDate(0, 0, -d.Day()+1) | |||
return GetZeroTime(d) | |||
} | |||
//获取传入的时间所在月份的最后一天,即某月最后一天的0点。如传入time.Now(), 返回当前月份的最后一天0点时间。 | |||
func GetLastDateOfMonth(d time.Time) time.Time { | |||
return GetFirstDateOfMonth(d).AddDate(0, 1, -1) | |||
} | |||
//获取某一天的0点时间 | |||
func GetZeroTime(d time.Time) time.Time { | |||
return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location()) | |||
} | |||
//获取当月某天的某个时间的时间 | |||
func GetDayToTime(day, timeStr string) string { | |||
if timeStr == "" { | |||
timeStr = "00:00:00" | |||
} | |||
year := time.Now().Year() | |||
month := time.Now().Format("01") | |||
times := fmt.Sprintf("%s-%s-%s %s", IntToStr(year), month, day, timeStr) | |||
return times | |||
} |
@@ -0,0 +1,24 @@ | |||
package model | |||
import "time" | |||
type ImPackage struct { | |||
Id int64 // 自增主键 | |||
Name string // 套餐名 | |||
Price string // 价格 | |||
ValidityDay int64 // 有效期(天/月/年) | |||
ValidityDayType int32 // 有效期类型(1:天 2:月 3:年) | |||
FriendsTotalNum int64 // 好友总数 | |||
FriendsSingleNum int64 // 单用户可添加好友数 | |||
GroupTotalNum int64 // 群组总数 | |||
GroupSingleNum int64 // 单用户可创建群组总数 | |||
GroupNum int64 // 群人员数量 | |||
SingleChatNumsEveryDay int64 // 每日单聊消息数 | |||
GroupChatNumsEveryDay int64 // 每日群聊消息数 | |||
LivingNumsEveryDay int64 // 日活数 | |||
MessageCloudStorageDay int64 // 消息云端存储(天) | |||
Sort int64 // 排序(天) | |||
isUse int32 // 是否启用(1:启用 2:禁用) | |||
CreateTime time.Time // 创建时间 | |||
UpdateTime time.Time // 更新时间 | |||
} |
@@ -0,0 +1,17 @@ | |||
package model | |||
import "time" | |||
type Master struct { | |||
Id int64 // 自增主键 | |||
Phone string // 手机号 | |||
MasterId int64 // 站长id | |||
MasterName string // 站长名称 | |||
AvatarUrl string // 站长头像链接 | |||
Extra string // 附加属性 | |||
PackageId int64 // 套餐id(0:未购买套餐) | |||
PackageExpireTime string // 套餐到期时间 | |||
IsUse int32 // 是否可用(1:可用 2:禁用) | |||
CreateTime time.Time // 创建时间 | |||
UpdateTime time.Time // 更新时间 | |||
} |
@@ -0,0 +1,25 @@ | |||
package repo | |||
import ( | |||
"gim/internal/business/domain/user/model" | |||
"gim/pkg/db" | |||
"gim/pkg/gerrors" | |||
"github.com/jinzhu/gorm" | |||
) | |||
type imPackageDao struct{} | |||
var ImPackageDao = new(imPackageDao) | |||
// Get 获取套餐包详情 | |||
func (*imPackageDao) Get(id int64) (*model.ImPackage, error) { | |||
var imPackage = model.ImPackage{Id: id} | |||
err := db.DB.First(&imPackage).Error | |||
if err != nil && err != gorm.ErrRecordNotFound { | |||
return nil, gerrors.WrapError(err) | |||
} | |||
if err == gorm.ErrRecordNotFound { | |||
return nil, nil | |||
} | |||
return &imPackage, err | |||
} |
@@ -0,0 +1,18 @@ | |||
package repo | |||
import ( | |||
"gim/internal/business/domain/user/model" | |||
) | |||
type imPackageRepo struct{} | |||
var ImPackageRepo = new(imPackageRepo) | |||
// Get 获取单个套餐包 | |||
func (*imPackageRepo) Get(masterId int64) (*model.ImPackage, error) { | |||
imPackage, err := ImPackageDao.Get(masterId) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return imPackage, err | |||
} |
@@ -0,0 +1,51 @@ | |||
package repo | |||
import ( | |||
"gim/internal/business/domain/user/model" | |||
"gim/pkg/db" | |||
"gim/pkg/gerrors" | |||
"strconv" | |||
"time" | |||
"github.com/go-redis/redis" | |||
) | |||
const ( | |||
MasterKey = "master:" | |||
MasterExpire = 24 * time.Hour | |||
) | |||
type masterCache struct{} | |||
var MasterCache = new(masterCache) | |||
// Get 获取用户缓存 | |||
func (c *masterCache) Get(masterId int64) (*model.Master, error) { | |||
var master model.Master | |||
err := db.RedisUtil.Get(MasterKey+strconv.FormatInt(masterId, 10), &master) | |||
if err != nil && err != redis.Nil { | |||
return nil, gerrors.WrapError(err) | |||
} | |||
if err == redis.Nil { | |||
return nil, nil | |||
} | |||
return &master, nil | |||
} | |||
// Set 设置用户缓存 | |||
func (c *masterCache) Set(master model.Master) error { | |||
err := db.RedisUtil.Set(MasterKey+strconv.FormatInt(master.MasterId, 10), master, MasterExpire) | |||
if err != nil { | |||
return gerrors.WrapError(err) | |||
} | |||
return nil | |||
} | |||
// Del 删除用户缓存 | |||
func (c *masterCache) Del(masterId int64) error { | |||
_, err := db.RedisCli.Del(MasterKey + strconv.FormatInt(masterId, 10)).Result() | |||
if err != nil { | |||
return gerrors.WrapError(err) | |||
} | |||
return nil | |||
} |
@@ -0,0 +1,38 @@ | |||
package repo | |||
import ( | |||
"gim/internal/business/domain/user/model" | |||
"gim/pkg/db" | |||
"gim/pkg/gerrors" | |||
"github.com/jinzhu/gorm" | |||
) | |||
type masterDao struct{} | |||
var MasterDao = new(masterDao) | |||
// Get 获取站长信息 | |||
func (*masterDao) Get(masterId int64) (*model.Master, error) { | |||
var master = model.Master{MasterId: masterId} | |||
err := db.DB.First(&master).Error | |||
if err != nil && err != gorm.ErrRecordNotFound { | |||
return nil, gerrors.WrapError(err) | |||
} | |||
if err == gorm.ErrRecordNotFound { | |||
return nil, nil | |||
} | |||
return &master, err | |||
} | |||
// GetByPhone 根据手机号获取用户信息 | |||
func (*masterDao) GetByPhone(phone string) (*model.Master, error) { | |||
var master model.Master | |||
err := db.DB.First(&master, "phone_number = ?", phone).Error | |||
if err != nil && err != gorm.ErrRecordNotFound { | |||
return nil, gerrors.WrapError(err) | |||
} | |||
if err == gorm.ErrRecordNotFound { | |||
return nil, nil | |||
} | |||
return &master, err | |||
} |
@@ -0,0 +1,37 @@ | |||
package repo | |||
import ( | |||
"gim/internal/business/domain/user/model" | |||
) | |||
type masterRepo struct{} | |||
var MasterRepo = new(masterRepo) | |||
// Get 获取单个站长 | |||
func (*masterRepo) Get(masterId int64) (*model.Master, error) { | |||
master, err := MasterCache.Get(masterId) | |||
if err != nil { | |||
return nil, err | |||
} | |||
if master != nil { | |||
return master, nil | |||
} | |||
master, err = MasterDao.Get(masterId) | |||
if err != nil { | |||
return nil, err | |||
} | |||
if master != nil { | |||
err = MasterCache.Set(*master) | |||
if err != nil { | |||
return nil, err | |||
} | |||
} | |||
return master, err | |||
} | |||
func (*masterRepo) GetByPhone(phone string, masterId int64) (*model.Master, error) { | |||
return MasterDao.GetByPhone(phone) | |||
} |
@@ -26,10 +26,10 @@ func getLogicExtClient() pb.LogicExtClient { | |||
// deprecated: | |||
func getCtx() context.Context { | |||
token := "VRZWQVPFXHPUCCKFOANEYOLCDSFMKEAVYVMAZQWQ" | |||
token := "AYBVKGSIFENYDKKOPBYVONZWTCZAQEDGHLAKZLXT" | |||
return metadata.NewOutgoingContext(context.TODO(), metadata.Pairs( | |||
"user_id", "2", | |||
"device_id", "2", | |||
"user_id", "13", | |||
"device_id", "10", | |||
"token", token, | |||
"request_id", strconv.FormatInt(time.Now().UnixNano(), 10))) | |||
} | |||
@@ -208,3 +208,17 @@ func TestLogicExtServer_GetGroupMembers(t *testing.T) { | |||
} | |||
fmt.Printf("%+v\n", resp) | |||
} | |||
func TestLogicExtServer_AddFriend(t *testing.T) { | |||
resp, err := getLogicExtClient().AddFriend(getCtx(), | |||
&pb.AddFriendReq{ | |||
FriendId: 2, | |||
Remarks: "weihan", | |||
Description: "hello", | |||
}) | |||
if err != nil { | |||
fmt.Println(err) | |||
return | |||
} | |||
fmt.Printf("%+v\n", resp) | |||
} |
@@ -13,6 +13,7 @@ const ( | |||
CtxUserId = "user_id" | |||
CtxDeviceId = "device_id" | |||
CtxToken = "token" | |||
CtxMasterId = "master_id" | |||
CtxRequestId = "request_id" | |||
) | |||
@@ -107,6 +108,21 @@ func GetCtxToken(ctx context.Context) (string, error) { | |||
return tokens[0], nil | |||
} | |||
// GetCtxMasterId 获取ctx的masterId | |||
func GetCtxMasterId(ctx context.Context) (string, error) { | |||
md, ok := metadata.FromIncomingContext(ctx) | |||
if !ok { | |||
return "", gerrors.ErrUnauthorized | |||
} | |||
masterId, ok := md[CtxMasterId] | |||
if !ok && len(masterId) == 0 { | |||
return "", gerrors.ErrUnauthorized | |||
} | |||
return masterId[0], nil | |||
} | |||
// NewAndCopyRequestId 创建一个context,并且复制RequestId | |||
func NewAndCopyRequestId(ctx context.Context) context.Context { | |||
newCtx := context.TODO() | |||
@@ -1,8 +1,8 @@ | |||
// Code generated by protoc-gen-go. DO NOT EDIT. | |||
// versions: | |||
// protoc-gen-go v1.26.0 | |||
// protoc v3.14.0 | |||
// source: business.ext.proto_back | |||
// protoc-gen-go v1.28.1 | |||
// protoc v3.20.0--rc1 | |||
// source: business.ext.proto | |||
package pb | |||
@@ -166,6 +166,140 @@ func (x *SignInResp) GetMasterId() int64 { | |||
return 0 | |||
} | |||
type CloudUploadFileReq struct { | |||
state protoimpl.MessageState | |||
sizeCache protoimpl.SizeCache | |||
unknownFields protoimpl.UnknownFields | |||
Dir string `protobuf:"bytes,1,opt,name=dir,proto3" json:"dir,omitempty"` // 目录名 | |||
FileName string `protobuf:"bytes,2,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` // 上传原文件名称 | |||
FileSize string `protobuf:"bytes,3,opt,name=file_size,json=fileSize,proto3" json:"file_size,omitempty"` // 文件大小 | |||
} | |||
func (x *CloudUploadFileReq) Reset() { | |||
*x = CloudUploadFileReq{} | |||
if protoimpl.UnsafeEnabled { | |||
mi := &file_business_ext_proto_msgTypes[2] | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
ms.StoreMessageInfo(mi) | |||
} | |||
} | |||
func (x *CloudUploadFileReq) String() string { | |||
return protoimpl.X.MessageStringOf(x) | |||
} | |||
func (*CloudUploadFileReq) ProtoMessage() {} | |||
func (x *CloudUploadFileReq) ProtoReflect() protoreflect.Message { | |||
mi := &file_business_ext_proto_msgTypes[2] | |||
if protoimpl.UnsafeEnabled && x != nil { | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
if ms.LoadMessageInfo() == nil { | |||
ms.StoreMessageInfo(mi) | |||
} | |||
return ms | |||
} | |||
return mi.MessageOf(x) | |||
} | |||
// Deprecated: Use CloudUploadFileReq.ProtoReflect.Descriptor instead. | |||
func (*CloudUploadFileReq) Descriptor() ([]byte, []int) { | |||
return file_business_ext_proto_rawDescGZIP(), []int{2} | |||
} | |||
func (x *CloudUploadFileReq) GetDir() string { | |||
if x != nil { | |||
return x.Dir | |||
} | |||
return "" | |||
} | |||
func (x *CloudUploadFileReq) GetFileName() string { | |||
if x != nil { | |||
return x.FileName | |||
} | |||
return "" | |||
} | |||
func (x *CloudUploadFileReq) GetFileSize() string { | |||
if x != nil { | |||
return x.FileSize | |||
} | |||
return "" | |||
} | |||
type CloudUploadFileResp struct { | |||
state protoimpl.MessageState | |||
sizeCache protoimpl.SizeCache | |||
unknownFields protoimpl.UnknownFields | |||
Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` // 请求方式 | |||
Host string `protobuf:"bytes,2,opt,name=host,proto3" json:"host,omitempty"` // 域名 | |||
Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // key | |||
Token string `protobuf:"bytes,4,opt,name=token,proto3" json:"token,omitempty"` // token | |||
} | |||
func (x *CloudUploadFileResp) Reset() { | |||
*x = CloudUploadFileResp{} | |||
if protoimpl.UnsafeEnabled { | |||
mi := &file_business_ext_proto_msgTypes[3] | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
ms.StoreMessageInfo(mi) | |||
} | |||
} | |||
func (x *CloudUploadFileResp) String() string { | |||
return protoimpl.X.MessageStringOf(x) | |||
} | |||
func (*CloudUploadFileResp) ProtoMessage() {} | |||
func (x *CloudUploadFileResp) ProtoReflect() protoreflect.Message { | |||
mi := &file_business_ext_proto_msgTypes[3] | |||
if protoimpl.UnsafeEnabled && x != nil { | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
if ms.LoadMessageInfo() == nil { | |||
ms.StoreMessageInfo(mi) | |||
} | |||
return ms | |||
} | |||
return mi.MessageOf(x) | |||
} | |||
// Deprecated: Use CloudUploadFileResp.ProtoReflect.Descriptor instead. | |||
func (*CloudUploadFileResp) Descriptor() ([]byte, []int) { | |||
return file_business_ext_proto_rawDescGZIP(), []int{3} | |||
} | |||
func (x *CloudUploadFileResp) GetMethod() string { | |||
if x != nil { | |||
return x.Method | |||
} | |||
return "" | |||
} | |||
func (x *CloudUploadFileResp) GetHost() string { | |||
if x != nil { | |||
return x.Host | |||
} | |||
return "" | |||
} | |||
func (x *CloudUploadFileResp) GetKey() string { | |||
if x != nil { | |||
return x.Key | |||
} | |||
return "" | |||
} | |||
func (x *CloudUploadFileResp) GetToken() string { | |||
if x != nil { | |||
return x.Token | |||
} | |||
return "" | |||
} | |||
type User struct { | |||
state protoimpl.MessageState | |||
sizeCache protoimpl.SizeCache | |||
@@ -184,7 +318,7 @@ type User struct { | |||
func (x *User) Reset() { | |||
*x = User{} | |||
if protoimpl.UnsafeEnabled { | |||
mi := &file_business_ext_proto_msgTypes[2] | |||
mi := &file_business_ext_proto_msgTypes[4] | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
ms.StoreMessageInfo(mi) | |||
} | |||
@@ -197,7 +331,7 @@ func (x *User) String() string { | |||
func (*User) ProtoMessage() {} | |||
func (x *User) ProtoReflect() protoreflect.Message { | |||
mi := &file_business_ext_proto_msgTypes[2] | |||
mi := &file_business_ext_proto_msgTypes[4] | |||
if protoimpl.UnsafeEnabled && x != nil { | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
if ms.LoadMessageInfo() == nil { | |||
@@ -210,7 +344,7 @@ func (x *User) ProtoReflect() protoreflect.Message { | |||
// Deprecated: Use User.ProtoReflect.Descriptor instead. | |||
func (*User) Descriptor() ([]byte, []int) { | |||
return file_business_ext_proto_rawDescGZIP(), []int{2} | |||
return file_business_ext_proto_rawDescGZIP(), []int{4} | |||
} | |||
func (x *User) GetUserId() int64 { | |||
@@ -280,7 +414,7 @@ type GetUserReq struct { | |||
func (x *GetUserReq) Reset() { | |||
*x = GetUserReq{} | |||
if protoimpl.UnsafeEnabled { | |||
mi := &file_business_ext_proto_msgTypes[3] | |||
mi := &file_business_ext_proto_msgTypes[5] | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
ms.StoreMessageInfo(mi) | |||
} | |||
@@ -293,7 +427,7 @@ func (x *GetUserReq) String() string { | |||
func (*GetUserReq) ProtoMessage() {} | |||
func (x *GetUserReq) ProtoReflect() protoreflect.Message { | |||
mi := &file_business_ext_proto_msgTypes[3] | |||
mi := &file_business_ext_proto_msgTypes[5] | |||
if protoimpl.UnsafeEnabled && x != nil { | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
if ms.LoadMessageInfo() == nil { | |||
@@ -306,7 +440,7 @@ func (x *GetUserReq) ProtoReflect() protoreflect.Message { | |||
// Deprecated: Use GetUserReq.ProtoReflect.Descriptor instead. | |||
func (*GetUserReq) Descriptor() ([]byte, []int) { | |||
return file_business_ext_proto_rawDescGZIP(), []int{3} | |||
return file_business_ext_proto_rawDescGZIP(), []int{5} | |||
} | |||
func (x *GetUserReq) GetUserId() int64 { | |||
@@ -327,7 +461,7 @@ type GetUserResp struct { | |||
func (x *GetUserResp) Reset() { | |||
*x = GetUserResp{} | |||
if protoimpl.UnsafeEnabled { | |||
mi := &file_business_ext_proto_msgTypes[4] | |||
mi := &file_business_ext_proto_msgTypes[6] | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
ms.StoreMessageInfo(mi) | |||
} | |||
@@ -340,7 +474,7 @@ func (x *GetUserResp) String() string { | |||
func (*GetUserResp) ProtoMessage() {} | |||
func (x *GetUserResp) ProtoReflect() protoreflect.Message { | |||
mi := &file_business_ext_proto_msgTypes[4] | |||
mi := &file_business_ext_proto_msgTypes[6] | |||
if protoimpl.UnsafeEnabled && x != nil { | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
if ms.LoadMessageInfo() == nil { | |||
@@ -353,7 +487,7 @@ func (x *GetUserResp) ProtoReflect() protoreflect.Message { | |||
// Deprecated: Use GetUserResp.ProtoReflect.Descriptor instead. | |||
func (*GetUserResp) Descriptor() ([]byte, []int) { | |||
return file_business_ext_proto_rawDescGZIP(), []int{4} | |||
return file_business_ext_proto_rawDescGZIP(), []int{6} | |||
} | |||
func (x *GetUserResp) GetUser() *User { | |||
@@ -377,7 +511,7 @@ type UpdateUserReq struct { | |||
func (x *UpdateUserReq) Reset() { | |||
*x = UpdateUserReq{} | |||
if protoimpl.UnsafeEnabled { | |||
mi := &file_business_ext_proto_msgTypes[5] | |||
mi := &file_business_ext_proto_msgTypes[7] | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
ms.StoreMessageInfo(mi) | |||
} | |||
@@ -390,7 +524,7 @@ func (x *UpdateUserReq) String() string { | |||
func (*UpdateUserReq) ProtoMessage() {} | |||
func (x *UpdateUserReq) ProtoReflect() protoreflect.Message { | |||
mi := &file_business_ext_proto_msgTypes[5] | |||
mi := &file_business_ext_proto_msgTypes[7] | |||
if protoimpl.UnsafeEnabled && x != nil { | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
if ms.LoadMessageInfo() == nil { | |||
@@ -403,7 +537,7 @@ func (x *UpdateUserReq) ProtoReflect() protoreflect.Message { | |||
// Deprecated: Use UpdateUserReq.ProtoReflect.Descriptor instead. | |||
func (*UpdateUserReq) Descriptor() ([]byte, []int) { | |||
return file_business_ext_proto_rawDescGZIP(), []int{5} | |||
return file_business_ext_proto_rawDescGZIP(), []int{7} | |||
} | |||
func (x *UpdateUserReq) GetNickname() string { | |||
@@ -446,7 +580,7 @@ type SearchUserReq struct { | |||
func (x *SearchUserReq) Reset() { | |||
*x = SearchUserReq{} | |||
if protoimpl.UnsafeEnabled { | |||
mi := &file_business_ext_proto_msgTypes[6] | |||
mi := &file_business_ext_proto_msgTypes[8] | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
ms.StoreMessageInfo(mi) | |||
} | |||
@@ -459,7 +593,7 @@ func (x *SearchUserReq) String() string { | |||
func (*SearchUserReq) ProtoMessage() {} | |||
func (x *SearchUserReq) ProtoReflect() protoreflect.Message { | |||
mi := &file_business_ext_proto_msgTypes[6] | |||
mi := &file_business_ext_proto_msgTypes[8] | |||
if protoimpl.UnsafeEnabled && x != nil { | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
if ms.LoadMessageInfo() == nil { | |||
@@ -472,7 +606,7 @@ func (x *SearchUserReq) ProtoReflect() protoreflect.Message { | |||
// Deprecated: Use SearchUserReq.ProtoReflect.Descriptor instead. | |||
func (*SearchUserReq) Descriptor() ([]byte, []int) { | |||
return file_business_ext_proto_rawDescGZIP(), []int{6} | |||
return file_business_ext_proto_rawDescGZIP(), []int{8} | |||
} | |||
func (x *SearchUserReq) GetKey() string { | |||
@@ -500,7 +634,7 @@ type SearchUserResp struct { | |||
func (x *SearchUserResp) Reset() { | |||
*x = SearchUserResp{} | |||
if protoimpl.UnsafeEnabled { | |||
mi := &file_business_ext_proto_msgTypes[7] | |||
mi := &file_business_ext_proto_msgTypes[9] | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
ms.StoreMessageInfo(mi) | |||
} | |||
@@ -513,7 +647,7 @@ func (x *SearchUserResp) String() string { | |||
func (*SearchUserResp) ProtoMessage() {} | |||
func (x *SearchUserResp) ProtoReflect() protoreflect.Message { | |||
mi := &file_business_ext_proto_msgTypes[7] | |||
mi := &file_business_ext_proto_msgTypes[9] | |||
if protoimpl.UnsafeEnabled && x != nil { | |||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
if ms.LoadMessageInfo() == nil { | |||
@@ -526,7 +660,7 @@ func (x *SearchUserResp) ProtoReflect() protoreflect.Message { | |||
// Deprecated: Use SearchUserResp.ProtoReflect.Descriptor instead. | |||
func (*SearchUserResp) Descriptor() ([]byte, []int) { | |||
return file_business_ext_proto_rawDescGZIP(), []int{7} | |||
return file_business_ext_proto_rawDescGZIP(), []int{9} | |||
} | |||
func (x *SearchUserResp) GetUsers() []*User { | |||
@@ -556,55 +690,72 @@ var file_business_ext_proto_rawDesc = []byte{ | |||
0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, | |||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, | |||
0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, | |||
0x08, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0xe1, 0x01, 0x0a, 0x04, 0x55, 0x73, | |||
0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, | |||
0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6e, | |||
0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, | |||
0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x78, 0x18, 0x03, | |||
0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x73, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x76, 0x61, | |||
0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, | |||
0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, | |||
0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x12, 0x1f, | |||
0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, | |||
0x01, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, | |||
0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, | |||
0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, | |||
0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, | |||
0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x25, 0x0a, | |||
0x0a, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, | |||
0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, | |||
0x65, 0x72, 0x49, 0x64, 0x22, 0x2b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, | |||
0x65, 0x73, 0x70, 0x12, 0x1c, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, | |||
0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, | |||
0x72, 0x22, 0x72, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, | |||
0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, | |||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, | |||
0x0a, 0x03, 0x73, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x73, 0x65, 0x78, | |||
0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, | |||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, | |||
0x14, 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, | |||
0x65, 0x78, 0x74, 0x72, 0x61, 0x22, 0x3e, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, | |||
0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, | |||
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x73, 0x74, | |||
0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x73, | |||
0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x30, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, | |||
0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1e, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, | |||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, | |||
0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x32, 0xc3, 0x01, 0x0a, 0x0b, 0x42, 0x75, 0x73, 0x69, | |||
0x6e, 0x65, 0x73, 0x73, 0x45, 0x78, 0x74, 0x12, 0x27, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x49, | |||
0x6e, 0x12, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x52, 0x65, 0x71, | |||
0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, | |||
0x12, 0x2a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x2e, 0x70, 0x62, | |||
0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x70, 0x62, | |||
0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2a, 0x0a, 0x0a, | |||
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x11, 0x2e, 0x70, 0x62, 0x2e, | |||
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x09, 0x2e, | |||
0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x33, 0x0a, 0x0a, 0x53, 0x65, 0x61, 0x72, | |||
0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x12, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x61, 0x72, | |||
0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x53, | |||
0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x42, 0x0d, 0x5a, | |||
0x0b, 0x67, 0x69, 0x6d, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x62, 0x06, 0x70, 0x72, | |||
0x6f, 0x74, 0x6f, 0x33, | |||
0x08, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x60, 0x0a, 0x12, 0x43, 0x6c, 0x6f, | |||
0x75, 0x64, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, | |||
0x10, 0x0a, 0x03, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, | |||
0x72, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, | |||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, | |||
0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, | |||
0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x69, 0x0a, 0x13, 0x43, | |||
0x6c, 0x6f, 0x75, 0x64, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, | |||
0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, | |||
0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, | |||
0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x10, | |||
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, | |||
0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, | |||
0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xe1, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, | |||
0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, | |||
0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, | |||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, | |||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, | |||
0x05, 0x52, 0x03, 0x73, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, | |||
0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, | |||
0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x18, 0x05, | |||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x78, 0x74, 0x72, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x63, | |||
0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, | |||
0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, | |||
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, | |||
0x03, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, | |||
0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, | |||
0x52, 0x08, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x25, 0x0a, 0x0a, 0x47, 0x65, | |||
0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, | |||
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, | |||
0x64, 0x22, 0x2b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, | |||
0x12, 0x1c, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, | |||
0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x72, | |||
0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, | |||
0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, | |||
0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, | |||
0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x73, 0x65, 0x78, 0x12, 0x1d, 0x0a, | |||
0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, | |||
0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, | |||
0x65, 0x78, 0x74, 0x72, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x78, 0x74, | |||
0x72, 0x61, 0x22, 0x3e, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, | |||
0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, | |||
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, | |||
0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, | |||
0x49, 0x64, 0x22, 0x30, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, | |||
0x52, 0x65, 0x73, 0x70, 0x12, 0x1e, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, | |||
0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, | |||
0x73, 0x65, 0x72, 0x73, 0x32, 0x87, 0x02, 0x0a, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, | |||
0x73, 0x45, 0x78, 0x74, 0x12, 0x27, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x12, 0x0d, | |||
0x2e, 0x70, 0x62, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, | |||
0x70, 0x62, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2a, 0x0a, | |||
0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, | |||
0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, | |||
0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2a, 0x0a, 0x0a, 0x55, 0x70, 0x64, | |||
0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, | |||
0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x09, 0x2e, 0x70, 0x62, 0x2e, | |||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x33, 0x0a, 0x0a, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, | |||
0x73, 0x65, 0x72, 0x12, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, | |||
0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x61, 0x72, | |||
0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x42, 0x0a, 0x0f, 0x43, 0x6c, | |||
0x6f, 0x75, 0x64, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x16, 0x2e, | |||
0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, | |||
0x6c, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, | |||
0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x42, 0x0d, | |||
0x5a, 0x0b, 0x67, 0x69, 0x6d, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x62, 0x06, 0x70, | |||
0x72, 0x6f, 0x74, 0x6f, 0x33, | |||
} | |||
var ( | |||
@@ -619,34 +770,38 @@ func file_business_ext_proto_rawDescGZIP() []byte { | |||
return file_business_ext_proto_rawDescData | |||
} | |||
var file_business_ext_proto_msgTypes = make([]protoimpl.MessageInfo, 8) | |||
var file_business_ext_proto_msgTypes = make([]protoimpl.MessageInfo, 10) | |||
var file_business_ext_proto_goTypes = []interface{}{ | |||
(*SignInReq)(nil), // 0: pb.SignInReq | |||
(*SignInResp)(nil), // 1: pb.SignInResp | |||
(*User)(nil), // 2: pb.User | |||
(*GetUserReq)(nil), // 3: pb.GetUserReq | |||
(*GetUserResp)(nil), // 4: pb.GetUserResp | |||
(*UpdateUserReq)(nil), // 5: pb.UpdateUserReq | |||
(*SearchUserReq)(nil), // 6: pb.SearchUserReq | |||
(*SearchUserResp)(nil), // 7: pb.SearchUserResp | |||
(*Empty)(nil), // 8: pb.Empty | |||
(*SignInReq)(nil), // 0: pb.SignInReq | |||
(*SignInResp)(nil), // 1: pb.SignInResp | |||
(*CloudUploadFileReq)(nil), // 2: pb.CloudUploadFileReq | |||
(*CloudUploadFileResp)(nil), // 3: pb.CloudUploadFileResp | |||
(*User)(nil), // 4: pb.User | |||
(*GetUserReq)(nil), // 5: pb.GetUserReq | |||
(*GetUserResp)(nil), // 6: pb.GetUserResp | |||
(*UpdateUserReq)(nil), // 7: pb.UpdateUserReq | |||
(*SearchUserReq)(nil), // 8: pb.SearchUserReq | |||
(*SearchUserResp)(nil), // 9: pb.SearchUserResp | |||
(*Empty)(nil), // 10: pb.Empty | |||
} | |||
var file_business_ext_proto_depIdxs = []int32{ | |||
2, // 0: pb.GetUserResp.user:type_name -> pb.User | |||
2, // 1: pb.SearchUserResp.users:type_name -> pb.User | |||
0, // 2: pb.BusinessExt.SignIn:input_type -> pb.SignInReq | |||
3, // 3: pb.BusinessExt.GetUser:input_type -> pb.GetUserReq | |||
5, // 4: pb.BusinessExt.UpdateUser:input_type -> pb.UpdateUserReq | |||
6, // 5: pb.BusinessExt.SearchUser:input_type -> pb.SearchUserReq | |||
1, // 6: pb.BusinessExt.SignIn:output_type -> pb.SignInResp | |||
4, // 7: pb.BusinessExt.GetUser:output_type -> pb.GetUserResp | |||
8, // 8: pb.BusinessExt.UpdateUser:output_type -> pb.Empty | |||
7, // 9: pb.BusinessExt.SearchUser:output_type -> pb.SearchUserResp | |||
6, // [6:10] is the sub-list for method output_type | |||
2, // [2:6] is the sub-list for method input_type | |||
2, // [2:2] is the sub-list for extension type_name | |||
2, // [2:2] is the sub-list for extension extendee | |||
0, // [0:2] is the sub-list for field type_name | |||
4, // 0: pb.GetUserResp.user:type_name -> pb.User | |||
4, // 1: pb.SearchUserResp.users:type_name -> pb.User | |||
0, // 2: pb.BusinessExt.SignIn:input_type -> pb.SignInReq | |||
5, // 3: pb.BusinessExt.GetUser:input_type -> pb.GetUserReq | |||
7, // 4: pb.BusinessExt.UpdateUser:input_type -> pb.UpdateUserReq | |||
8, // 5: pb.BusinessExt.SearchUser:input_type -> pb.SearchUserReq | |||
2, // 6: pb.BusinessExt.CloudUploadFile:input_type -> pb.CloudUploadFileReq | |||
1, // 7: pb.BusinessExt.SignIn:output_type -> pb.SignInResp | |||
6, // 8: pb.BusinessExt.GetUser:output_type -> pb.GetUserResp | |||
10, // 9: pb.BusinessExt.UpdateUser:output_type -> pb.Empty | |||
9, // 10: pb.BusinessExt.SearchUser:output_type -> pb.SearchUserResp | |||
3, // 11: pb.BusinessExt.CloudUploadFile:output_type -> pb.CloudUploadFileResp | |||
7, // [7:12] is the sub-list for method output_type | |||
2, // [2:7] is the sub-list for method input_type | |||
2, // [2:2] is the sub-list for extension type_name | |||
2, // [2:2] is the sub-list for extension extendee | |||
0, // [0:2] is the sub-list for field type_name | |||
} | |||
func init() { file_business_ext_proto_init() } | |||
@@ -681,7 +836,7 @@ func file_business_ext_proto_init() { | |||
} | |||
} | |||
file_business_ext_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { | |||
switch v := v.(*User); i { | |||
switch v := v.(*CloudUploadFileReq); i { | |||
case 0: | |||
return &v.state | |||
case 1: | |||
@@ -693,7 +848,7 @@ func file_business_ext_proto_init() { | |||
} | |||
} | |||
file_business_ext_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { | |||
switch v := v.(*GetUserReq); i { | |||
switch v := v.(*CloudUploadFileResp); i { | |||
case 0: | |||
return &v.state | |||
case 1: | |||
@@ -705,7 +860,7 @@ func file_business_ext_proto_init() { | |||
} | |||
} | |||
file_business_ext_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { | |||
switch v := v.(*GetUserResp); i { | |||
switch v := v.(*User); i { | |||
case 0: | |||
return &v.state | |||
case 1: | |||
@@ -717,7 +872,7 @@ func file_business_ext_proto_init() { | |||
} | |||
} | |||
file_business_ext_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { | |||
switch v := v.(*UpdateUserReq); i { | |||
switch v := v.(*GetUserReq); i { | |||
case 0: | |||
return &v.state | |||
case 1: | |||
@@ -729,7 +884,7 @@ func file_business_ext_proto_init() { | |||
} | |||
} | |||
file_business_ext_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { | |||
switch v := v.(*SearchUserReq); i { | |||
switch v := v.(*GetUserResp); i { | |||
case 0: | |||
return &v.state | |||
case 1: | |||
@@ -741,6 +896,30 @@ func file_business_ext_proto_init() { | |||
} | |||
} | |||
file_business_ext_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { | |||
switch v := v.(*UpdateUserReq); i { | |||
case 0: | |||
return &v.state | |||
case 1: | |||
return &v.sizeCache | |||
case 2: | |||
return &v.unknownFields | |||
default: | |||
return nil | |||
} | |||
} | |||
file_business_ext_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { | |||
switch v := v.(*SearchUserReq); i { | |||
case 0: | |||
return &v.state | |||
case 1: | |||
return &v.sizeCache | |||
case 2: | |||
return &v.unknownFields | |||
default: | |||
return nil | |||
} | |||
} | |||
file_business_ext_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { | |||
switch v := v.(*SearchUserResp); i { | |||
case 0: | |||
return &v.state | |||
@@ -759,7 +938,7 @@ func file_business_ext_proto_init() { | |||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | |||
RawDescriptor: file_business_ext_proto_rawDesc, | |||
NumEnums: 0, | |||
NumMessages: 8, | |||
NumMessages: 10, | |||
NumExtensions: 0, | |||
NumServices: 1, | |||
}, | |||
@@ -773,17 +952,14 @@ func file_business_ext_proto_init() { | |||
file_business_ext_proto_depIdxs = nil | |||
} | |||
// Reference imports to suppress errors if they are not otherwise used. | |||
var _ context.Context | |||
var _ grpc.ClientConnInterface | |||
// This is a compile-time assertion to ensure that this generated file | |||
// is compatible with the grpc package it is being compiled against. | |||
const _ = grpc.SupportPackageIsVersion6 | |||
// Requires gRPC-Go v1.32.0 or later. | |||
const _ = grpc.SupportPackageIsVersion7 | |||
// BusinessExtClient is the client API for BusinessExt service. | |||
// | |||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. | |||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. | |||
type BusinessExtClient interface { | |||
// 登录 | |||
SignIn(ctx context.Context, in *SignInReq, opts ...grpc.CallOption) (*SignInResp, error) | |||
@@ -793,6 +969,8 @@ type BusinessExtClient interface { | |||
UpdateUser(ctx context.Context, in *UpdateUserReq, opts ...grpc.CallOption) (*Empty, error) | |||
// 搜索用户(这里简单数据库实现,生产环境建议使用ES) | |||
SearchUser(ctx context.Context, in *SearchUserReq, opts ...grpc.CallOption) (*SearchUserResp, error) | |||
// 上传文件至云端 | |||
CloudUploadFile(ctx context.Context, in *CloudUploadFileReq, opts ...grpc.CallOption) (*CloudUploadFileResp, error) | |||
} | |||
type businessExtClient struct { | |||
@@ -839,7 +1017,18 @@ func (c *businessExtClient) SearchUser(ctx context.Context, in *SearchUserReq, o | |||
return out, nil | |||
} | |||
func (c *businessExtClient) CloudUploadFile(ctx context.Context, in *CloudUploadFileReq, opts ...grpc.CallOption) (*CloudUploadFileResp, error) { | |||
out := new(CloudUploadFileResp) | |||
err := c.cc.Invoke(ctx, "/pb.BusinessExt/CloudUploadFile", in, out, opts...) | |||
if err != nil { | |||
return nil, err | |||
} | |||
return out, nil | |||
} | |||
// BusinessExtServer is the server API for BusinessExt service. | |||
// All implementations must embed UnimplementedBusinessExtServer | |||
// for forward compatibility | |||
type BusinessExtServer interface { | |||
// 登录 | |||
SignIn(context.Context, *SignInReq) (*SignInResp, error) | |||
@@ -849,27 +1038,32 @@ type BusinessExtServer interface { | |||
UpdateUser(context.Context, *UpdateUserReq) (*Empty, error) | |||
// 搜索用户(这里简单数据库实现,生产环境建议使用ES) | |||
SearchUser(context.Context, *SearchUserReq) (*SearchUserResp, error) | |||
// 上传文件至云端 | |||
CloudUploadFile(context.Context, *CloudUploadFileReq) (*CloudUploadFileResp, error) | |||
} | |||
// UnimplementedBusinessExtServer can be embedded to have forward compatible implementations. | |||
// UnimplementedBusinessExtServer must be embedded to have forward compatible implementations. | |||
type UnimplementedBusinessExtServer struct { | |||
} | |||
func (*UnimplementedBusinessExtServer) SignIn(context.Context, *SignInReq) (*SignInResp, error) { | |||
func (UnimplementedBusinessExtServer) SignIn(context.Context, *SignInReq) (*SignInResp, error) { | |||
return nil, status.Errorf(codes.Unimplemented, "method SignIn not implemented") | |||
} | |||
func (*UnimplementedBusinessExtServer) GetUser(context.Context, *GetUserReq) (*GetUserResp, error) { | |||
func (UnimplementedBusinessExtServer) GetUser(context.Context, *GetUserReq) (*GetUserResp, error) { | |||
return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented") | |||
} | |||
func (*UnimplementedBusinessExtServer) UpdateUser(context.Context, *UpdateUserReq) (*Empty, error) { | |||
func (UnimplementedBusinessExtServer) UpdateUser(context.Context, *UpdateUserReq) (*Empty, error) { | |||
return nil, status.Errorf(codes.Unimplemented, "method UpdateUser not implemented") | |||
} | |||
func (*UnimplementedBusinessExtServer) SearchUser(context.Context, *SearchUserReq) (*SearchUserResp, error) { | |||
func (UnimplementedBusinessExtServer) SearchUser(context.Context, *SearchUserReq) (*SearchUserResp, error) { | |||
return nil, status.Errorf(codes.Unimplemented, "method SearchUser not implemented") | |||
} | |||
func (UnimplementedBusinessExtServer) CloudUploadFile(context.Context, *CloudUploadFileReq) (*CloudUploadFileResp, error) { | |||
return nil, status.Errorf(codes.Unimplemented, "method CloudUploadFile not implemented") | |||
} | |||
func RegisterBusinessExtServer(s *grpc.Server, srv BusinessExtServer) { | |||
s.RegisterService(&_BusinessExt_serviceDesc, srv) | |||
func RegisterBusinessExtServer(s grpc.ServiceRegistrar, srv BusinessExtServer) { | |||
s.RegisterService(&BusinessExt_ServiceDesc, srv) | |||
} | |||
func _BusinessExt_SignIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | |||
@@ -944,7 +1138,28 @@ func _BusinessExt_SearchUser_Handler(srv interface{}, ctx context.Context, dec f | |||
return interceptor(ctx, in, info, handler) | |||
} | |||
var _BusinessExt_serviceDesc = grpc.ServiceDesc{ | |||
func _BusinessExt_CloudUploadFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | |||
in := new(CloudUploadFileReq) | |||
if err := dec(in); err != nil { | |||
return nil, err | |||
} | |||
if interceptor == nil { | |||
return srv.(BusinessExtServer).CloudUploadFile(ctx, in) | |||
} | |||
info := &grpc.UnaryServerInfo{ | |||
Server: srv, | |||
FullMethod: "/pb.BusinessExt/CloudUploadFile", | |||
} | |||
handler := func(ctx context.Context, req interface{}) (interface{}, error) { | |||
return srv.(BusinessExtServer).CloudUploadFile(ctx, req.(*CloudUploadFileReq)) | |||
} | |||
return interceptor(ctx, in, info, handler) | |||
} | |||
// BusinessExt_ServiceDesc is the grpc.ServiceDesc for BusinessExt service. | |||
// It's only intended for direct use with grpc.RegisterService, | |||
// and not to be introspected or modified (even as a copy) | |||
var BusinessExt_ServiceDesc = grpc.ServiceDesc{ | |||
ServiceName: "pb.BusinessExt", | |||
HandlerType: (*BusinessExtServer)(nil), | |||
Methods: []grpc.MethodDesc{ | |||
@@ -964,7 +1179,11 @@ var _BusinessExt_serviceDesc = grpc.ServiceDesc{ | |||
MethodName: "SearchUser", | |||
Handler: _BusinessExt_SearchUser_Handler, | |||
}, | |||
{ | |||
MethodName: "CloudUploadFile", | |||
Handler: _BusinessExt_CloudUploadFile_Handler, | |||
}, | |||
}, | |||
Streams: []grpc.StreamDesc{}, | |||
Metadata: "business.ext.proto_back", | |||
Metadata: "business.ext.proto", | |||
} |
@@ -333,7 +333,7 @@ func file_business_int_proto_init() { | |||
var _ context.Context | |||
var _ grpc.ClientConnInterface | |||
// This is a compile-time assertion to ensure that this generated file | |||
// This is a compile-time assertion to ensure that this generated comm | |||
// is compatible with the grpc package it is being compiled against. | |||
const _ = grpc.SupportPackageIsVersion6 | |||
@@ -316,7 +316,7 @@ func file_connect_int_proto_init() { | |||
var _ context.Context | |||
var _ grpc.ClientConnInterface | |||
// This is a compile-time assertion to ensure that this generated file | |||
// This is a compile-time assertion to ensure that this generated comm | |||
// is compatible with the grpc package it is being compiled against. | |||
const _ = grpc.SupportPackageIsVersion6 | |||
@@ -2387,7 +2387,7 @@ func file_logic_ext_proto_init() { | |||
var _ context.Context | |||
var _ grpc.ClientConnInterface | |||
// This is a compile-time assertion to ensure that this generated file | |||
// This is a compile-time assertion to ensure that this generated comm | |||
// is compatible with the grpc package it is being compiled against. | |||
const _ = grpc.SupportPackageIsVersion6 | |||
@@ -1126,7 +1126,7 @@ func file_logic_int_proto_init() { | |||
var _ context.Context | |||
var _ grpc.ClientConnInterface | |||
// This is a compile-time assertion to ensure that this generated file | |||
// This is a compile-time assertion to ensure that this generated comm | |||
// is compatible with the grpc package it is being compiled against. | |||
const _ = grpc.SupportPackageIsVersion6 | |||
@@ -2,7 +2,7 @@ syntax = "proto3"; | |||
package pb; | |||
option go_package = "gim/pkg/pb/"; | |||
import "common.ext.proto"; | |||
message Empty{} | |||
service BusinessExt { | |||
// 登录 | |||
@@ -13,6 +13,8 @@ service BusinessExt { | |||
rpc UpdateUser (UpdateUserReq) returns (Empty); | |||
// 搜索用户(这里简单数据库实现,生产环境建议使用ES) | |||
rpc SearchUser (SearchUserReq) returns (SearchUserResp); | |||
// 上传文件至云端 | |||
rpc CloudUploadFile (CloudUploadFileReq) returns (CloudUploadFileResp); | |||
} | |||
message SignInReq { | |||
@@ -27,6 +29,17 @@ message SignInResp { | |||
string token = 3; // token | |||
int64 master_id = 4; // 站长id | |||
} | |||
message CloudUploadFileReq { | |||
string dir = 1; // 目录名 | |||
string file_name = 2; // 上传原文件名称 | |||
string file_size = 3; // 文件大小 | |||
} | |||
message CloudUploadFileResp { | |||
string method = 1; // 请求方式 | |||
string host = 2; // 域名 | |||
string key = 3; // key | |||
string token = 4; // token | |||
} | |||
message User { | |||
int64 user_id = 1; // 用户id | |||
@@ -58,6 +58,8 @@ func initConnectIntClient() { | |||
} | |||
func initBusinessIntClient() { | |||
//conn, err := grpc.DialContext(context.TODO(), "127.0.0.1:8000", grpc.WithInsecure(), | |||
// grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, roundrobin.Name))) | |||
conn, err := grpc.DialContext(context.TODO(), k8s.GetK8STarget("gim", "business", "8000"), grpc.WithInsecure(), | |||
grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, roundrobin.Name))) | |||
if err != nil { | |||
@@ -48,8 +48,15 @@ func FormatMessage(messageType pb.MessageType, messageContent []byte) string { | |||
msg = &pb.Text{} | |||
err = proto.Unmarshal(messageContent, msg) | |||
case pb.MessageType_MT_COMMAND: | |||
msg = &pb.Text{} | |||
err = proto.Unmarshal(messageContent, msg) | |||
msgCmd := &pb.Command{ | |||
Code: 0, | |||
Data: nil, | |||
} | |||
err = proto.Unmarshal(messageContent, msgCmd) | |||
if msgCmd.Code == int32(pb.PushCode_PC_ADD_FRIEND) { | |||
msg = &pb.AddFriendPush{} | |||
err = proto.Unmarshal(messageContent, msg) | |||
} | |||
case pb.MessageType_MT_CUSTOM: | |||
msg = &pb.Text{} | |||
err = proto.Unmarshal(messageContent, msg) | |||
@@ -1,6 +1,8 @@ | |||
package util | |||
import ( | |||
"encoding/json" | |||
"gim/internal/business/comm/utils" | |||
"gim/pkg/logger" | |||
"time" | |||
@@ -45,3 +47,62 @@ func (u *RedisUtil) Get(key string, value interface{}) error { | |||
} | |||
return nil | |||
} | |||
func (u *RedisUtil) HGetString(key string, HKey string) (string, error) { | |||
return u.client.Do("HGET", key, HKey).String() | |||
} | |||
func (u *RedisUtil) Exists(key string) bool { | |||
count, err := u.client.Do("EXISTS", key).Int() | |||
if count == 0 || err != nil { | |||
return false | |||
} | |||
return true | |||
} | |||
func (u *RedisUtil) HSet(key string, HKey string, data interface{}) (interface{}, error) { | |||
return u.client.HSet(key, HKey, data).Result() | |||
} | |||
func (u *RedisUtil) Expire(key string, ttl int) (interface{}, error) { | |||
return u.client.Do("EXPIRE", key, ttl).Result() | |||
} | |||
func (u *RedisUtil) Del(key string) (interface{}, error) { | |||
return u.client.Do("DEL", key).Result() | |||
} | |||
func (u *RedisUtil) Do(args ...interface{}) (reply interface{}, err error) { | |||
return u.client.Do(args...).String() | |||
} | |||
func (u *RedisUtil) SetEx(key string, data interface{}, ttl int) (reply interface{}, err error) { | |||
return u.client.Do("SETEX", key, ttl, data).Result() | |||
} | |||
func (u *RedisUtil) GetJson(key string, dst interface{}) error { | |||
b, err := utils.Bytes(u.client.Do("GET", key).Result()) | |||
if err != nil { | |||
return err | |||
} | |||
if err = json.Unmarshal(b, dst); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func (u *RedisUtil) SetJson(key string, data interface{}, ttl int) bool { | |||
c, err := json.Marshal(data) | |||
if err != nil { | |||
return false | |||
} | |||
if ttl < 1 { | |||
err = u.Set(key, c, time.Duration(ttl)) | |||
} else { | |||
_, err = u.SetEx(key, c, ttl) | |||
} | |||
if err != nil { | |||
return false | |||
} | |||
return true | |||
} |
@@ -87,7 +87,7 @@ func (c *TcpClient) SignIn() { | |||
signIn := pb.SignInInput{ | |||
UserId: c.UserId, | |||
DeviceId: c.DeviceId, | |||
Token: "ABPIKUKGTCZZGLUSZQAGFXKCSQFEVXEMAYHNNOUZ", | |||
Token: "GPFMVIWQKIKLLPHMDYECZJONPCAAKUWKMNGXRTSP", | |||
} | |||
c.Output(pb.PackageType_PT_SIGN_IN, time.Now().UnixNano(), &signIn) | |||
} | |||
@@ -165,6 +165,10 @@ func (c *TcpClient) HandlePackage(bytes []byte) { | |||
} | |||
msg := messageSend.Message | |||
//if msg.Sender.SenderType == 1 { | |||
// //系统发送的消息 | |||
// | |||
//} | |||
log.Printf("消息:发送者类型:%d 发送者id:%d 接收者类型:%d 接收者id:%d 消息内容:%+v seq:%d \n", | |||
msg.Sender.SenderType, msg.Sender.SenderId, msg.ReceiverType, msg.ReceiverId, util.FormatMessage(msg.MessageType, msg.MessageContent), msg.Seq) | |||