Documentation ¶
Index ¶
- Constants
- Variables
- func AcquireLock(rdb rueidiscompat.Cmdable, key string, value string, expiration time.Duration) bool
- func CbcRegisterHandler[T any](route string, handler Handler[T])
- func CompareAndDiff(origin interface{}, bodyData map[string]interface{}, ...) map[string]interface{}
- func CtxGetEnv(ctx iris.Context, defaultStr ...string) string
- func DefaultModelMap() map[string]any
- func FastMsgMap(code int, msg string, pipeNames ...string) iris.Map
- func GenUUid() string
- func GetLen(input any) (float64, error)
- func GetModelAllCount(ctx context.Context, db *qmgo.Database, modelId string) (int64, error)
- func MapToSliceAny(input map[string]any) ([]any, error)
- func MapToSliceString(input map[string]any) ([]string, error)
- func MongoBulkInsert[T any](ctx context.Context, db *qmgo.Collection, accounts ...T) error
- func MongoBulkInsertCount[T any](ctx context.Context, db *qmgo.Collection, accounts ...T) (int, error)
- func MongoBulkInsertCountMustRetry[T any](ctx context.Context, db *qmgo.Collection, accounts ...T) (int, error)
- func MongoBulkInsertCountRetry[T any](ctx context.Context, db *qmgo.Collection, retryCount uint, ...) (int, error)
- func MongoFilterGetOne[T any](ctx context.Context, db *qmgo.Collection, filters bson.M) (*T, error)
- func MongoFilters[T any](ctx context.Context, db *qmgo.Collection, filters bson.M) ([]T, error)
- func MongoGetOne[T any](ctx context.Context, db *qmgo.Collection, uid string) (*T, error)
- func MongoIterateByBatch[T IMongoBase](ctx context.Context, db *qmgo.Collection, filter bson.M, selects bson.M, ...) error
- func MongoRandom[T any](ctx context.Context, db *qmgo.Collection, filters bson.D, count int) ([]T, error)
- func MongoUpdateOne(ctx context.Context, db *qmgo.Collection, uid string, pack bson.M) error
- func OpValid(input any, op string, value string) bool
- func ReleaseLock(client rueidiscompat.Cmdable, key string, value string) error
- func SchemaValidFunc(schema []byte, input map[string]any) error
- func SfNextId() string
- func ToJsonSchema[T any](origin T, omitFields ...string) *jsonschema.Schema
- func ToMap(v interface{}) (map[string]interface{}, error)
- type AccountCoin
- type AccountComm
- func (a *AccountComm) GetAvatarUrl() string
- func (a *AccountComm) GetDisable() bool
- func (a *AccountComm) GetMsg() string
- func (a *AccountComm) GetNickName() string
- func (a *AccountComm) SetAvatarUrl(uri string)
- func (a *AccountComm) SetDisable(newDisable bool)
- func (a *AccountComm) SetMsg(newMsg string)
- func (a *AccountComm) SetNickName(name string)
- type AccountPass
- func (a *AccountPass) GetEmail() string
- func (a *AccountPass) GetPassword() string
- func (a *AccountPass) GetTelPhone() string
- func (a *AccountPass) GetUserName() string
- func (a *AccountPass) PasswordMd5(rawPassword string) (m5ps string, salt string)
- func (a *AccountPass) SetEmail(newEmail string)
- func (a *AccountPass) SetPassword(newPassword string)
- func (a *AccountPass) SetTelPhone(newTelPhone string)
- func (a *AccountPass) SetUserName(newUserName string)
- func (a *AccountPass) ValidPassword(rawPassword string) bool
- type AccountPlatform
- type AccountPlatformPublic
- type Attribute
- type CbcRequestData
- type CbcService
- type GenericsAccount
- func (s *GenericsAccount) BulkInsert(ctx context.Context, db *qmgo.Collection, accounts ...*GenericsAccount) error
- func (s *GenericsAccount) Filters(ctx context.Context, db *qmgo.Collection, filters bson.M) ([]*GenericsAccount, error)
- func (s *GenericsAccount) GetAccountPass() AccountPass
- func (s *GenericsAccount) GetCoin() AccountCoin
- func (s *GenericsAccount) GetComm() AccountComm
- func (s *GenericsAccount) GetOne(ctx context.Context, db *qmgo.Collection, uid string) (*GenericsAccount, error)
- func (s *GenericsAccount) Random(ctx context.Context, db *qmgo.Collection, filters bson.D, count int) ([]*GenericsAccount, error)
- func (s *GenericsAccount) SetAccountPass(pass AccountPass)
- func (s *GenericsAccount) SetComm(comm AccountComm)
- func (s *GenericsAccount) UpdateOne(ctx context.Context, db *qmgo.Collection, uid string, pack bson.M) error
- type Handler
- type HashGenPipe
- type HttpRequestConfig
- type IAccountGenerics
- type IAccountGenericsFull
- type IAccountShortcut
- type IMongoBase
- type IMongoModel
- type JwtCheckDep
- type JwtFlatBase
- type JwtGenPipe
- type JwtHelper
- func (c *JwtHelper) GenJwtToken(userId, env string) string
- func (c *JwtHelper) JwtRedisGenKey(userId, env string) string
- func (c *JwtHelper) JwtRedisGetKey(ctx context.Context, key string) rueidis.RedisResult
- func (c *JwtHelper) JwtSaveToken(ctx context.Context, key string, token string, expired time.Duration) error
- func (c *JwtHelper) JwtShortRedisGenKey(shortToken string) string
- func (c *JwtHelper) TokenExtract(token string, m *irisJwt.Middleware) (*JwtFlatBase, error)
- type KvValidConfig
- type KvsValidPipe
- type LocalCachePipe
- type ModelBase
- type ModelCtxAddConfig
- type ModelDelConfig
- type ModelGetData
- type ModelGetDataDep
- type ModelIndex
- func (c *ModelIndex) Gen(v any) mongo.IndexModel
- func (c *ModelIndex) NewModel2dSphereIndex(fields ...string) *ModelIndex
- func (c *ModelIndex) NewModelNormalIndex(fields ...string) *ModelIndex
- func (c *ModelIndex) NewModelTextIndex(fields ...string) *ModelIndex
- func (c *ModelIndex) NewModelUniqueIndex(fields ...string) *ModelIndex
- func (c *ModelIndex) NewModelUniqueSparseIndex(fields ...string) *ModelIndex
- type ModelPutConfig
- type ParseResponse
- type PipeJwtDep
- type QueryParseConfig
- type RandomPipe
- type RateLimitPipe
- type RbacAllowPipe
- type RbacDomain
- func (c *RbacDomain) DelRead(uid string) error
- func (c *RbacDomain) DelRole(uid string, role string, domain string) (bool, error)
- func (c *RbacDomain) DelRoleDefaultDomain(uid string, role string) (bool, error)
- func (c *RbacDomain) DelRoot(uid string) error
- func (c *RbacDomain) DelStaff(uid string) error
- func (c *RbacDomain) HasRoles(uid string, roles []string) bool
- func (c *RbacDomain) IsStaffOrRoot(uid string) bool
- func (c *RbacDomain) SetRead(uid string) (bool, error)
- func (c *RbacDomain) SetRole(uid string, role string, domain string) (bool, error)
- func (c *RbacDomain) SetRoleDefaultDomain(uid string, role string) (bool, error)
- func (c *RbacDomain) SetRoot(uid string) (bool, error)
- func (c *RbacDomain) SetStaff(uid string) (bool, error)
- type RbacGetRolePipe
- type RedisKv
- type RedisOperate
- type RedisOperates
- type ReqResponse
- type RequestCachePipe
- type RuleValidate
- type RulesValidate
- type RunResp
- func (c *RunResp[T]) RaiseError(ctx iris.Context)
- func (c *RunResp[T]) Return(ctx iris.Context)
- func (c *RunResp[T]) ReturnSuccess(ctx iris.Context)
- func (c *RunResp[T]) SetBreak(b bool) *RunResp[T]
- func (c *RunResp[T]) SetBusinessCode(businessCode int) *RunResp[T]
- func (c *RunResp[T]) SetReqCode(reqCode int) *RunResp[T]
- type RunnerContext
- func (c *RunnerContext[T, P, D, R]) NewPipeErr(err error) *RunResp[R]
- func (c *RunnerContext[T, P, D, R]) Run(ctx iris.Context, origin T, params P, db D, more ...any) *RunResp[R]
- func (c *RunnerContext[T, P, D, R]) SetDesc(desc string) *RunnerContext[T, P, D, R]
- func (c *RunnerContext[T, P, D, R]) SetKey(key string) *RunnerContext[T, P, D, R]
- func (c *RunnerContext[T, P, D, R]) SetName(name string) *RunnerContext[T, P, D, R]
- type SchemaValidConfig
- type SmsClient
- func (s *SmsClient) DelKey(ctx context.Context, mobile string)
- func (s *SmsClient) Send(ctx context.Context, templateID string, mobile string) (string, error)
- func (s *SmsClient) SendBeforeCheck(ctx context.Context, templateId string, mobile string) (string, error)
- func (s *SmsClient) Valid(ctx context.Context, mobile, code string) bool
- type SmsPipe
- type StrExpand
- type StrTemplate
- type SwipeItem
- type SwipeValid
- type SwipeValidCode
- func (c *SwipeValidCode) BlockSize(half bool) int
- func (c *SwipeValidCode) Check(ctx iris.Context, raw string) (*SwipeValid, error)
- func (c *SwipeValidCode) Gen(ctx context.Context) (*SwipeItem, error)
- func (c *SwipeValidCode) RandomBlockX() int
- func (c *SwipeValidCode) RandomBlockY() int
- func (c *SwipeValidCode) SetExpireSec(newSec int64)
- func (c *SwipeValidCode) SetPrefix(prefix string)
- func (c *SwipeValidCode) SetRandomCount(newCount int8)
- type ValidResult
Constants ¶
const ( JwtPrefix = "Bearer " JwtShortPrefix = "Short " JwtShortLen = 12 )
const ( // 默认代表所有域名的通配符 RbacAllDomainDefault = "*" // 默认自身站点代号 可用于站点登录限制等 RbacSelfDomainName = "self" // 登录 RbacNotAllowLoginObj = "login" // 默认操作act RbacNormalAct = "POST" )
Variables ¶
var ( // RequestCacheGet 请求缓存获取 必传params和db RequestCacheGet = &RunnerContext[any, *RequestCachePipe, rueidis.Client, *ParseResponse]{ call: func(ctx iris.Context, origin any, params *RequestCachePipe, db rueidis.Client, more ...any) *RunResp[*ParseResponse] { if params == nil { params = new(RequestCachePipe) } cacheKey, err := params.GetCacheKey(ctx) if err != nil { return NewPipeErr[*ParseResponse](err) } resp := db.Do(ctx, db.B().Get().Key(cacheKey).Build()) if resp.Error() != nil { if resp.Error() == rueidis.Nil { return NewPipeErr[*ParseResponse](nil) } return NewPipeErr[*ParseResponse](resp.Error()) } raw, err := resp.ToString() if err != nil { return NewPipeErr[*ParseResponse](err) } var response *ParseResponse err = jsoniter.Unmarshal([]byte(raw), &response) if err != nil { return NewPipeErr[*ParseResponse](err) } return NewPipeResultErr[*ParseResponse](response, PipeCacheHasError).SetBreak(true) }, Name: "请求缓存获取", Key: "request_cache_get", } // RequestCacheSet 请求缓存设置 RequestCacheSet = &RunnerContext[*ParseResponse, *RequestCachePipe, rueidis.Client, *ParseResponse]{ call: func(ctx iris.Context, origin *ParseResponse, params *RequestCachePipe, db rueidis.Client, more ...any) *RunResp[*ParseResponse] { cacheKey, err := params.GetCacheKey(ctx) if err != nil { return NewPipeErr[*ParseResponse](err) } if _, ok := db.(rueidis.Client); !ok { return NewPipeErr[*ParseResponse](errors.New("获取rdb失败")) } rdb := db.(rueidis.Client) mpByte, _ := jsoniter.Marshal(origin) rdbResp := rdb.Do(ctx, rdb.B().Set().Key(cacheKey).Value(string(mpByte)).ExSeconds(int64(params.GetCacheTime().Seconds())).Build()) if rdbResp.Error() != nil { return NewPipeErr[*ParseResponse](rdbResp.Error()) } return NewPipeResult[*ParseResponse](nil) }, Name: "请求缓存设置", Key: "request_cache_set", } )
var ( // LocalCacheGet 本地缓存获取 使用 gcache // 必传params // 必传db 为gcache实例 LocalCacheGet = &RunnerContext[any, *LocalCachePipe, gcache.Cache, any]{ Name: "本地缓存获取", Key: "local_cache_get", call: func(ctx iris.Context, origin any, params *LocalCachePipe, db gcache.Cache, more ...any) *RunResp[any] { if params == nil { return NewPipeErr[any](PipePackParamsError) } gc := db k, err := params.KeyGen.Build() if err != nil { return NewPipeErr[any](err) } v, err := gc.Get(k) if err != nil { if err != gcache.KeyNotFoundError { return NewPipeErr[any](err) } if params.EmptyRaise { return NewPipeErr[any](err) } } else { if !params.DisWriteHeader { ctx.Header("X-Cache", "1") } } return NewPipeResult(v) }, } // LocalCacheSet 本地缓存设置 使用gcache // 必传params // 必传db 为gcache实例 LocalCacheSet = &RunnerContext[any, *LocalCachePipe, gcache.Cache, any]{ Name: "本地缓存设置", Key: "local_cache_set", call: func(ctx iris.Context, origin any, params *LocalCachePipe, db gcache.Cache, more ...any) *RunResp[any] { if params == nil { return NewPipeErr[any](PipePackParamsError) } k, err := params.KeyGen.Build() if err != nil { return NewPipeErr[any](err) } err = db.SetWithExpire(k, params.Values, params.GetExpire()) if err != nil { return NewPipeErr[any](err) } return NewPipeResult[any](params.Values) }, } )
var ( // RbacGetRoles 获取rbac的规则 // 必传params RbacGetRolePipe // 必传db 为RbacDomain的实例 RbacGetRoles = &RunnerContext[any, *RbacGetRolePipe, *RbacDomain, []string]{ Key: "rbac_get_role", Name: "rbac权限获取", call: func(ctx iris.Context, origin any, params *RbacGetRolePipe, db *RbacDomain, more ...any) *RunResp[[]string] { roles, err := db.E.GetRolesForUser(params.UserId, params.Domain) if err != nil { return NewPipeErr[[]string](err) } return NewPipeResult(roles) }, } // RbacAllow 判断rbac是否运行执行操作 // 必传params RbacAllowPipe // 必传db 为RbacDomain的实例 RbacAllow = &RunnerContext[any, *RbacAllowPipe, *RbacDomain, bool]{ Key: "rbac_allow", Name: "rbac权限允许执行", call: func(ctx iris.Context, origin any, params *RbacAllowPipe, db *RbacDomain, more ...any) *RunResp[bool] { if len(params.Sub) < 1 { return NewPipeErr[bool](errors.New("权限判断操作者不能为空")) } if len(params.Obj) < 1 { params.Obj = ctx.Path() } if len(params.Domain) < 1 { params.Domain = RbacSelfDomainName } if len(params.Act) < 1 { params.Act = ctx.Method() } pass := db.E.HasPolicy(params.Sub, params.Domain, params.Obj, params.Act) return NewPipeResult(pass) }, } )
var ( // RedisCommand redis单条操作 // 必传params RedisOperate // 必传db RedisCommand = &RunnerContext[any, *RedisOperate, rueidis.Client, any]{ Name: "redis单条操作", Key: "redis_command", call: func(ctx iris.Context, origin any, params *RedisOperate, db rueidis.Client, more ...any) *RunResp[any] { if params == nil { return NewPipeErr[any](PipePackParamsError) } ab, err := params.Build() if err != nil { return NewPipeErr[any](err) } rdb := db redisCmd := rdb.B().Arbitrary(ab.Command) for _, kv := range ab.Keys { redisCmd.Keys(kv[0]) if len(kv) >= 2 { redisCmd.Args(kv[1]) } } redisCmd.Args(ab.Args...) resp := rdb.Do(ctx, redisCmd.Build()) if resp.Error() != nil { if resp.Error() == rueidis.Nil { if !params.AllowNil { return NewPipeErr[any](resp.Error()) } return NewPipeErr[any](nil) } return NewPipeErr[any](resp.Error()) } result, err := params.RespParse(resp) return NewPipeResultErr(result, err) }, } // RedisCommands redis多条操作 // 必传params RedisOperates // 必传db RedisCommands = &RunnerContext[any, *RedisOperates, rueidis.Client, []any]{ Name: "多条redis操作", Key: "redis_commands", call: func(ctx iris.Context, origin any, params *RedisOperates, db rueidis.Client, more ...any) *RunResp[[]any] { rdb := db cmdList := make(rueidis.Commands, 0, len(params.Records)) for _, rc := range params.Records { ab, err := rc.Build() if err != nil { return NewPipeErr[[]any](err) } redisCmd := rdb.B().Arbitrary(ab.Command) for _, kv := range ab.Keys { redisCmd.Keys(kv[0]) if len(kv) >= 2 { redisCmd.Args(kv[1]) } } redisCmd.Args(ab.Args...) cmdList = append(cmdList, redisCmd.Build()) } if len(cmdList) < 1 { return NewPipeErr[[]any](errors.New("redis命令组为空")) } var result = make([]any, 0, len(cmdList)) for index, resp := range rdb.DoMulti(ctx, cmdList...) { if resp.Error() != nil { if resp.Error() == rueidis.Nil { if !params.Records[index].AllowNil { return NewPipeErr[[]any](resp.Error()) } result = append(result, nil) continue } return NewPipeErr[[]any](resp.Error()) } r, err := params.Records[index].RespParse(resp) if err != nil { return NewPipeErr[[]any](err) } result = append(result, r) } return NewPipeResult(result) }, } )
var ( // SmsSend 短信发送 // 必传params SmsPipe // 必传db SmsClient 的实例 SmsSend = &RunnerContext[any, *SmsPipe, *SmsClient, string]{ Name: "短信验证码发送", Key: "sms_send", call: func(ctx iris.Context, origin any, params *SmsPipe, db *SmsClient, more ...any) *RunResp[string] { code, err := db.SendBeforeCheck(ctx, params.TemplateId, params.Mobile) return NewPipeResultErr(code, err) }, } // SmsValid 短信验证码验证 // 必传params SmsPipe // 必传db SmsClient 的实例 SmsValid = &RunnerContext[any, *SmsPipe, *SmsClient, bool]{ Name: "短信验证码验证", Key: "sms_valid", call: func(ctx iris.Context, origin any, params *SmsPipe, db *SmsClient, more ...any) *RunResp[bool] { pass := db.Valid(ctx, params.Mobile, params.Code) if !pass { return NewPipeErr[bool](errors.New("短信验证码验证失败")) } db.DelKey(context.TODO(), params.Mobile) return NewPipeResult(pass) }, } )
var ( // SwipeValidGet 滑块验证码获取 // 必传db SwipeValidCode 的实例 SwipeValidGet = &RunnerContext[any, any, *SwipeValidCode, string]{ Name: "滑块验证码获取", Key: "swipe_valid_get", call: func(ctx iris.Context, origin any, params any, db *SwipeValidCode, more ...any) *RunResp[string] { sp, err := db.Gen(ctx) if err != nil { return NewPipeErr[string](err) } raw := sp.ToString() sEnc := base64.StdEncoding.EncodeToString([]byte(raw)) return NewPipeResult(sEnc) }, } // SwipeValidCheck 滑块验证码验证 // 必传db SwipeValidCode 的实例 SwipeValidCheck = &RunnerContext[string, any, *SwipeValidCode, *SwipeValid]{ Name: "滑块验证码验证", Key: "swipe_valid_check", call: func(ctx iris.Context, origin string, params any, db *SwipeValidCode, more ...any) *RunResp[*SwipeValid] { check, err := db.Check(ctx, origin) if err != nil { return NewPipeErr[*SwipeValid](errors.New("验证失败 请重试")) } return NewPipeResult(check) }, } )
var ( PipeSelectorParamsError = errors.New("操作序列选择器参数错误") PipeDepNotFound = errors.New("操作序列依赖项未找到") PipeSelectorNotFoundData = errors.New("操作序列获取内容为空") PipePackError = errors.New("操作序列包参数错误") PipeDepError = errors.New("操作序列依赖错误") PipeDbError = errors.New("操作序列db报错") PipeOriginError = errors.New("操作序列原始数据获取失败") PipePackParamsError = errors.New("操作序列包内容参数错误") PipeParamsError = errors.New("操作序列参数错误") PipeBreakError = errors.New("操作序列主动跳出错误") PipeCacheHasError = errors.New("有缓存主动返回") PipeRunAfterError = errors.New("操作序列包执行错误") PipeRunAfterEmptyError = errors.New("操作序列包解析后为空错误") PipeRatedError = errors.New("太快了 请慢一点~") )
var ( // HashGen hash生成 必传params Type可选b62 b58 HashGen = &RunnerContext[any, *HashGenPipe, any, string]{ Name: "hash生成", Key: "hash_gen", call: func(ctx iris.Context, origin any, params *HashGenPipe, db any, more ...any) *RunResp[string] { if len(params.Cols) < 1 { return NewPipeErr[string](PipePackParamsError) } var result string switch params.Type { case "b62": result = ut.StrToB62(strings.Join(params.Cols, "")) break case "b58": result = ut.StrToB58(strings.Join(params.Cols, "")) break default: return NewPipeErr[string](errors.New("hash生成类型错误")) } return NewPipeResult[string](result) }, } )
var ( // HttpRequest 发起http请求 必传 params HttpRequest = &RunnerContext[any, *HttpRequestConfig, any, *req.Response]{ Name: "http请求", Key: "http_request", call: func(ctx iris.Context, origin any, params *HttpRequestConfig, db any, more ...any) *RunResp[*req.Response] { if params == nil { return NewPipeErr[*req.Response](PipePackParamsError) } if len(params.Uri) < 1 { return NewPipeErr[*req.Response](PipeParamsError) } r := req.R() r.SetHeaders(params.Headers) if params.PathParams != nil { r.SetPathParams(params.PathParams) } if params.UrlParams != nil { r.SetQueryParamsAnyType(params.UrlParams) } if params.GetMethod() != http.MethodGet { if params.Body != nil { r.SetBody(params.Body) } } resp, err := r.Send(params.GetMethod(), params.Uri) if err != nil { return NewPipeErr[*req.Response](err) } if resp.StatusCode != params.GetMustCode() { return NewPipeErr[*req.Response](errors.New(fmt.Sprintf("请求需要 %d 响应码 但得到了 %d", params.GetMustCode(), resp.StatusCode))) } if resp.IsErrorState() { return NewPipeErr[*req.Response](resp.Err) } return NewPipeResult[*req.Response](resp) }, } )
var ( // ImgSafe 图像安全校验 必传 origin 是一个图像url地址 ImgSafe = &RunnerContext[string, any, any, bool]{ Name: "图片安全校验", Key: "img_safe", call: func(ctx iris.Context, origin string, params any, db any, more ...any) *RunResp[bool] { if len(origin) < 1 { return NewPipeResult[bool](false) } pass, err := contentSafe.C.AutoHitImg(origin) return NewPipeResultErr[bool](pass, err) }, } )
var ( // JwtCheck jwt验证 // 必传origin JwtCheckDep // 必传db 为redis Client JwtCheck = &RunnerContext[*JwtCheckDep, any, rueidis.Client, JwtFlatBase]{ Name: "jwt验证", Key: "jwt_check", call: func(ctx iris.Context, origin *JwtCheckDep, params any, db rueidis.Client, more ...any) *RunResp[JwtFlatBase] { if origin == nil { return NewPipeErr[JwtFlatBase](PipeDepError) } dep := origin rdb := db helper := NewJwtHelper(rdb) pack := dep.FlatMap if len(pack.UserId) < 1 { return NewPipeErr[JwtFlatBase](errors.New("jwt数据包关键参数缺失")) } if len(pack.Env) < 1 { return NewPipeErr[JwtFlatBase](errors.New("jwt数据包参数缺失")) } if len(pack.Raw) < 1 { return NewPipeErr[JwtFlatBase](errors.New("jwt数据包结构错误")) } raw := pack.Raw if pack.IsShort() { resp := rdb.Do(ctx, rdb.B().Get().Key(helper.JwtRedisGenKey(pack.UserId, dep.Env)).Build()) if resp.Error() != nil { if resp.Error() != rueidis.Nil { return NewPipeErr[JwtFlatBase](resp.Error()) } return NewPipeErr[JwtFlatBase](errors.New("jwt数据获取失败")) } st, err := resp.ToString() if err != nil { return NewPipeErr[JwtFlatBase](err) } raw = strings.TrimPrefix(raw, JwtPrefix) if raw != st { return NewPipeErr[JwtFlatBase](errors.New("jwt数据包已过期")) } return NewPipeResult(pack) } if dep.Env != pack.Env { return NewPipeErr[JwtFlatBase](errors.New("jwt数据包环境校验失败")) } return NewPipeResult[JwtFlatBase](pack) }, } )
var ( // JwtExchange jwt交换 // 必传origin JwtCheckDep jwt解析出来的内容包 // 必传params JwtGenPipe jwt的配置信息 // 必传db redis Client JwtExchange = &RunnerContext[*JwtCheckDep, *JwtGenPipe, rueidis.Client, string]{ Name: "jwt交换", Key: "jwt_exchange", call: func(ctx iris.Context, origin *JwtCheckDep, params *JwtGenPipe, db rueidis.Client, more ...any) *RunResp[string] { if params == nil { params = new(JwtGenPipe) } resp := JwtVisit.call(ctx, origin, nil, db) if resp.Err != nil { return NewPipeErr[string](resp.Err) } flatMap := resp.Result if flatMap.IsShort() { return NewPipeErr[string](errors.New("短令牌无法生成短令牌")) } helper := NewJwtHelper(db) raw := flatMap.Raw raw = strings.TrimPrefix(raw, JwtPrefix) shortToken := ut.RandomStr(JwtShortLen) shortRedisKey := helper.JwtShortRedisGenKey(shortToken) err := helper.JwtSaveToken(ctx, shortRedisKey, raw, params.GetExpire(time.Hour)) if err != nil { return NewPipeErr[string](err) } return NewPipeResult[string](shortToken) }, } )
var ( // JwtFlat jwt解构出内容包 // 必传origin 为Authorization头的字符串内容 // 必传db 为redis Client JwtFlat = &RunnerContext[string, any, rueidis.Client, JwtFlatBase]{ Name: "jwt解构", Key: "jwt_flat", call: func(ctx iris.Context, origin string, params any, rdb rueidis.Client, more ...any) *RunResp[JwtFlatBase] { if len(origin) < 1 { return NewPipeErr[JwtFlatBase](errors.New("获取token令牌错误")) } helper := NewJwtHelper(rdb) isShort := strings.HasPrefix(origin, JwtShortPrefix) auth := origin if isShort { shortToken := strings.TrimPrefix(origin, JwtShortPrefix) if len(shortToken) != JwtShortLen { return NewPipeErr[JwtFlatBase](errors.New("短token令牌格式错误")) } resp := rdb.Do(ctx, rdb.B().Get().Key(helper.JwtShortRedisGenKey(shortToken)).Build()) if resp.Error() != nil { return NewPipeErr[JwtFlatBase](resp.Error()) } st, err := resp.ToString() if err != nil { return NewPipeErr[JwtFlatBase](err) } auth = JwtPrefix + st } if !strings.HasPrefix(auth, JwtPrefix) { return NewPipeErr[JwtFlatBase](errors.New("token令牌格式错误")) } tk, err := helper.TokenExtract(auth, ctJwt) if err != nil { return NewPipeErr[JwtFlatBase](err) } tk.Raw = auth return NewPipeResult(*tk) }, } )
var ( // JwtGen jwt 结构设计 Strict模式下 用户一个env下仅可登陆一个设备 [key为userId:env]:value 为token // 必传origin jwt设置 // 必传params 生成参数 // 必传db redis Client JwtGen = &RunnerContext[*PipeJwtDep, *JwtGenPipe, rueidis.Client, string]{ Name: "jwt生成", Key: "jwt_gen", call: func(ctx iris.Context, origin *PipeJwtDep, params *JwtGenPipe, db rueidis.Client, more ...any) *RunResp[string] { if origin == nil { return NewPipeErr[string](PipeDepError) } if params == nil { params = new(JwtGenPipe) } helper := NewJwtHelper(db) redisKey := helper.JwtRedisGenKey(origin.UserId, origin.Env) if params.Strict { resp := helper.JwtRedisGetKey(ctx, redisKey) if resp.Error() != nil { if resp.Error() != rueidis.Nil { return NewPipeErr[string](resp.Error()) } } st, _ := resp.ToString() if len(st) > 0 && !params.Force { return NewPipeErr[string](errors.New("当前环境有其他设备在线")) } } token := helper.GenJwtToken(origin.UserId, origin.Env) err := helper.JwtSaveToken(ctx, redisKey, token, params.GetExpire()) if err != nil { return NewPipeErr[string](err) } return NewPipeResult[string](token) }, } )
var ( // JwtVisit jwt一整套流程整合 对jwt自动续期 // 必传origin JwtCheckDep jwt请求头包 需要有 Authorization 字段 // 必传db 为redis Client JwtVisit = &RunnerContext[*JwtCheckDep, any, rueidis.Client, JwtFlatBase]{ Name: "jwt显示", Key: "jwt_visit", call: func(ctx iris.Context, origin *JwtCheckDep, params any, db rueidis.Client, more ...any) *RunResp[JwtFlatBase] { dep := origin resp := JwtFlat.call(ctx, dep.Authorization, nil, db) if resp.Err != nil { return NewPipeErr[JwtFlatBase](errors.Wrap(resp.Err, "解析结构")) } dep.FlatMap = resp.Result resp2 := JwtCheck.call(ctx, dep, nil, db) if resp2.Err != nil { return NewPipeErr[JwtFlatBase](errors.Wrap(resp2.Err, "验证安全")) } pack := resp.Result isShort := pack.IsShort() rdb := db helper := NewJwtHelper(rdb) if isShort { shortToken := strings.TrimPrefix(pack.Raw, JwtShortPrefix) shortRedisKey := helper.JwtShortRedisGenKey(shortToken) expireSec := int64(time.Hour.Seconds()) err := rdb.Do(context.Background(), rdb.B().Expire().Key(shortRedisKey).Seconds(expireSec).Gt().Build()).Error() if err != nil { logger.J.ErrorE(err, "续期short token失败 %s ", shortToken) } } else { redisKey := helper.JwtRedisGenKey(pack.UserId, pack.Env) expireSec := int64(new(JwtGenPipe).GetExpire().Seconds()) cmdList := rdb.B().Expire().Key(redisKey).Seconds(expireSec).Gt().Build() err := rdb.Do(context.Background(), cmdList).Error() if err != nil { logger.J.ErrorE(err, "续期token失败 %s %s", pack.UserId, pack.Env) } } return NewPipeResult(resp.Result) }, } )
var ( // KvValid kv结构验证器 必传params KvValid = &RunnerContext[any, *KvValidConfig, any, bool]{ Name: "kv验证器", Key: "kv_valid", call: func(ctx iris.Context, origin any, params *KvValidConfig, db any, more ...any) *RunResp[bool] { if params == nil { return NewPipeErr[bool](PipePackParamsError) } pass, err := params.Check() if err != nil { return NewPipeErr[bool](err) } return NewPipeResult(pass) }, } )
var ( // ModelAdd 模型json新增 // 必传origin 支持map和struct 为模型的struct 对于传入struct会转换为map 通过json标签为key // 必传params ModelCtxAddConfig 配置信息 模型ID必须存在 // 必传db 为qmgo的Database的实例 ModelAdd = &RunnerContext[any, *ModelCtxAddConfig, *qmgo.Database, map[string]any]{ Key: "model_ctx_add", Name: "模型json新增", call: func(ctx iris.Context, origin any, params *ModelCtxAddConfig, db *qmgo.Database, more ...any) *RunResp[map[string]any] { if origin == nil { return NewPipeErr[map[string]any](PipeDepNotFound) } rawData := make(map[string]any) typ := reflect.TypeOf(origin) if typ.Kind() == reflect.Pointer { typ = typ.Elem() } switch typ.Kind() { case reflect.Struct: mp, err := ut.StructToMap(origin) if err != nil { return NewPipeErr[map[string]any](err) } rawData = mp case reflect.Map: rawData = origin.(map[string]any) default: return NewPipeErr[map[string]any](errors.New("origin 类型错误")) } mp := DefaultModelMap() mapper := &ut.ModelCtxMapperPack{ InjectData: mp, } err := mapper.Process(rawData) if err != nil { return NewPipeErr[map[string]any](err) } _, err = db.Collection(params.ModelId).InsertOne(ctx, rawData) if err != nil { return NewPipeErr[map[string]any](err) } return NewPipeResult(rawData) }, } )
var ( // ModelDel 模型单条删除 // 必传params ModelDelConfig 必传modelId和rowId // 必传db 为qmgo的qmgo.Database ModelDel = &RunnerContext[any, *ModelDelConfig, *qmgo.Database, any]{ Key: "model_ctx_del", Name: "模型单条删除", call: func(ctx iris.Context, origin any, params *ModelDelConfig, db *qmgo.Database, more ...any) *RunResp[any] { ft := params.QueryFilter if ft == nil { ft = new(ut.QueryFull) } ft.And = append(ft.And, &ut.Kov{ Key: ut.DefaultUidTag, Value: params.RowId, }) var result = make(map[string]any) pipeline := ut.QueryToMongoPipeline(ft) err := db.Collection(params.ModelId).Aggregate(ctx, pipeline).One(&result) if err != nil { return NewPipeErr[any](err) } err = db.Collection(params.ModelId).Remove(ctx, bson.M{ut.DefaultUidTag: params.RowId}) if err != nil { return NewPipeErr[any](err) } return NewPipeResult[any]("ok") }, } )
var ( // ModelMapper 模型body中映射取出对应的map 不需要db // 必传origin 支持map和struct struct以json的tag为key进行匹配 // 必传params ut.ModelCtxMapperPack new(ut.ModelCtxMapperPack)都可以 但是必传 ModelMapper = &RunnerContext[any, *ut.ModelCtxMapperPack, any, any]{ Key: "model_ctx_mapper", Name: "模型body取map", call: func(ctx iris.Context, origin any, params *ut.ModelCtxMapperPack, db any, more ...any) *RunResp[any] { var bodyData = origin if origin == nil { return NewPipeErr[any](PipeOriginError) } err := params.Process(bodyData) if err != nil { return NewPipeErr[any](err) } return NewPipeResult(bodyData) }, } )
var ( // ModelPut 模型修改 origin需要是一个map或struct 只会修改与原始条目的diff项 // 必传origin 可选struct或map 可以是ctx.ReadBody的映射 // 必传params ModelPutConfig 其中ModelId和RowId必传 // 必传db 为qmgo的Database ModelPut = &RunnerContext[any, *ModelPutConfig, *qmgo.Database, map[string]any]{ Key: "model_ctx_put", Name: "模型单条修改", call: func(ctx iris.Context, origin any, params *ModelPutConfig, db *qmgo.Database, more ...any) *RunResp[map[string]any] { if params == nil { return NewPipeErr[map[string]any](PipeParamsError) } if params.BodyMap == nil { return NewPipeErr[map[string]any](PipeOriginError) } bodyData := params.BodyMap ft := params.QueryFilter if ft == nil { ft = new(ut.QueryFull) } if ft.QueryParse == nil { ft.QueryParse = new(ut.QueryParse) } if ft.QueryParse.And == nil { ft.QueryParse.And = make([]*ut.Kov, 0) } if ft.QueryParse.Or == nil { ft.QueryParse.Or = make([]*ut.Kov, 0) } ft.QueryParse.And = append(ft.QueryParse.And, &ut.Kov{ Key: ut.DefaultUidTag, Value: params.RowId, }) pipeline := ut.QueryToMongoPipeline(ft) // 获取原始那一条 var result = make(map[string]any) err := db.Collection(params.ModelId).Aggregate(ctx, pipeline).One(&result) if err != nil { return NewPipeErr[map[string]any](err) } if origin == nil { origin = bodyData } diff := CompareAndDiff(origin, bodyData, result, "json") params.DropKeys = append(params.DropKeys, "_id", ut.DefaultUidTag) for _, key := range params.DropKeys { if _, ok := diff[key]; ok { delete(diff, key) } } if len(diff) < 1 { return NewPipeErr[map[string]any](errors.New("未获取到更新项")) } if params.UpdateTime { _, ok := diff["update_at"] if params.UpdateForce || !ok { diff["update_at"] = time.Now() } } err = db.Collection(params.ModelId).UpdateOne(ctx, bson.M{ut.DefaultUidTag: params.RowId}, bson.M{"$set": diff}) if err != nil { return NewPipeErr[map[string]any](err) } return NewPipeResult[map[string]any](diff) }, } )
var (
PipeBulkEmptySuccessError = errors.New("批量新增无一成功错误")
)
var ( // QueryGetData 通过模型解析出query获取内容 // 必传origin ModelGetDataDep 中的modelId // 必传params ModelGetData 需要设定为是否为单条以及是否获取匹配条数 // 必传db 为qmgo的Database QueryGetData = &RunnerContext[*ModelGetDataDep, *ModelGetData, *qmgo.Database, *ut.MongoFacetResult]{ Key: "query_get_data", Name: "query获取数据", call: func(ctx iris.Context, origin *ModelGetDataDep, params *ModelGetData, db *qmgo.Database, more ...any) *RunResp[*ut.MongoFacetResult] { if params.Single { origin.Query.Page = 1 origin.Query.PageSize = 1 } origin.Query.GetCount = params.GetQueryCount pipeline := ut.QueryToMongoPipeline(origin.Query) var err error var all = new(ut.MongoFacetResult) if params.Single { var result = make(map[string]any) err = db.Collection(origin.ModelId).Aggregate(ctx, pipeline).One(&result) all.Data = result } else { if params.GetQueryCount { type inlineResp struct { Meta struct { Count int64 `json:"count"` } Data []map[string]any `json:"data,omitempty"` } var batch = new(inlineResp) err = db.Collection(origin.ModelId).Aggregate(ctx, pipeline).One(&batch) all.Data = batch.Data all.Count = batch.Meta.Count } else { var batch = make([]map[string]any, 0) err = db.Collection(origin.ModelId).Aggregate(ctx, pipeline).All(&batch) all.Data = batch } } if err != nil { return NewPipeErr[*ut.MongoFacetResult](err) } return NewPipeResult(all) }, } )
var ( // QueryParse 根据约定规则从query中解析出mongodb的查询信息 // 必传params QueryParseConfig 所有的fields都是以json tag为准 QueryParse = &RunnerContext[any, *QueryParseConfig, any, *ut.QueryFull]{ Key: "model_ctx_query", Name: "模型query映射", call: func(ctx iris.Context, origin any, params *QueryParseConfig, db any, more ...any) *RunResp[*ut.QueryFull] { qs := ut.NewPruneCtxQuery() if params == nil { params = new(QueryParseConfig) } var urlParams = params.UrlParams if urlParams == nil { urlParams = ctx.URLParams() } mapper, err := qs.PruneParse(urlParams, params.SearchFields, params.GeoKey) if err != nil { return NewPipeErr[*ut.QueryFull](err) } if params.InjectAnd != nil { mapper.QueryParse.InsertOrReplaces("and", params.InjectAnd...) } if params.InjectOr != nil { mapper.QueryParse.InsertOrReplaces("or", params.InjectOr...) } mapper.Pks = params.Pks return NewPipeResult(mapper) }, } )
var ( // RandomGen 随机数生成 // 必传params RandomPipe RandomGen = &RunnerContext[any, *RandomPipe, any, any]{ Name: "随机数生成", Key: "random", call: func(ctx iris.Context, origin any, params *RandomPipe, db any, more ...any) *RunResp[any] { var result any switch params.NeedType { case "string": if params.Len < 1 { return NewPipeErr[any](errors.New("需要指定生成的字符串位数")) } result = ut.RandomStr(int(params.Len)) break case "int": if params.End < params.Start { return NewPipeErr[any](errors.New("截止值应该大于起始值")) } result = ut.RandomInt(int(params.End), int(params.Start)) break default: return NewPipeErr[any](errors.New("生成器类型未被支持")) } return NewPipeResult(result) }, } )
var ( // RequestRate 限速器 使用 https://github.com/ulule/limiter 实现 // 必传params RateLimitPipe RequestRate = &RunnerContext[any, *RateLimitPipe, any, any]{ Name: "请求限速", Key: "request_rate", call: func(ctx iris.Context, origin any, params *RateLimitPipe, db any, more ...any) *RunResp[any] { if params == nil { return NewPipeErr[any](PipePackParamsError) } k, err := params.KeyGen.Build() if err != nil { return NewPipeErr[any](err) } client, err := params.genClient() if err != nil { return NewPipeErr[any](err) } rateCtx, err := client.Get(ctx, k) if err != nil { return NewPipeErr[any](err) } if params.WriteHeader { ctx.Header("X-RateLimit-Limit", strconv.FormatInt(rateCtx.Limit, 10)) ctx.Header("X-RateLimit-Remaining", strconv.FormatInt(rateCtx.Remaining, 10)) ctx.Header("X-RateLimit-Reset", strconv.FormatInt(rateCtx.Reset, 10)) } if rateCtx.Reached { return NewPipeErr[any](PipeRatedError).SetReqCode(http.StatusTooManyRequests) } return NewPipeResult[any](nil) }, } )
var ( // ResponseParse 请求返回值的设定与解析 // 必传params ReqResponse ResponseParse = &RunnerContext[any, *ReqResponse, any, *ParseResponse]{ Name: "返回值解析", Key: "response_parse", call: func(ctx iris.Context, origin any, params *ReqResponse, db any, more ...any) *RunResp[*ParseResponse] { if params == nil { return NewPipeErr[*ParseResponse](PipePackParamsError) } var pr = new(ParseResponse) if params.Type == "string" && len(params.Msg) >= 1 { pr.Msg = params.Msg } else { pr.Json = nil if params.Items != nil { respMap := params.Items if len(params.Excludes) > 0 { for _, exclude := range params.Excludes { tls := strings.Split(exclude, ".") if len(tls) == 1 { delete(respMap, exclude) continue } if len(tls) == 2 { top := tls[0] if v, ok := respMap[top]; ok { if vt, ok := v.(map[string]any); ok { delete(vt, tls[1]) } } } } } switch params.Type { case "string": st, err := jsoniter.MarshalToString(respMap) if err != nil { return NewPipeErr[*ParseResponse](errors.Wrap(err, "返回值转换为字符串失败")) } pr.Msg = st break default: pr.Json = respMap break } } } return NewPipeResult(pr) }, } )
var ( // RulesValid 规则验证 使用github.com/gookit/validate库 基于语义可验证map // 必传params RulesValidate 格式是这样的 required|int|min:1|max:99 RulesValid = &RunnerContext[any, *RulesValidate, any, ValidResult]{ Name: "规则验证", Key: "rules_valid", call: func(ctx iris.Context, origin any, params *RulesValidate, db any, more ...any) *RunResp[ValidResult] { if params == nil { return NewPipeErr[ValidResult](PipePackParamsError) } mp := make(map[string]any) for _, rv := range params.Record { tv, err := ut.TypeChange(rv.Value, rv.NeedType) if err != nil { return NewPipeErr[ValidResult](err) } mp[rv.Key] = tv } result := params.Valid(mp) if !result.Pass { return NewPipeErr[ValidResult](errors.New(result.Msg)) } return NewPipeResult(result) }, } )
var ( // SchemaValid 基于json schema的验证器 // 必传origin 为待验证的数据 只能是map // 必传params SchemaValidConfig 必包含schema SchemaValid = &RunnerContext[map[string]any, *SchemaValidConfig, any, map[string]any]{ Name: "schema验证器", Key: "schema_valid", call: func(ctx iris.Context, origin map[string]any, params *SchemaValidConfig, db any, more ...any) *RunResp[map[string]any] { if origin == nil { return NewPipeErr[map[string]any](PipeDepError) } if params == nil { return NewPipeErr[map[string]any](PipePackParamsError) } rawBin, err := jsoniter.Marshal(params.Schema) if err != nil { return NewPipeErr[map[string]any](err) } err = SchemaValidFunc(rawBin, origin) if err != nil { return NewPipeErr[map[string]any](err) } return NewPipeResult(origin) }, } )
var ( // TextSafe 文字安全校验 // 必传origin 为待校验文字 TextSafe = &RunnerContext[string, any, any, bool]{ Name: "文字安全验证", Key: "text_safe", call: func(ctx iris.Context, origin string, params any, db any, more ...any) *RunResp[bool] { value := origin if len(value) > 1 { result, msg := contentSafe.C.AutoHitText(value) if !result { return NewPipeResultErr(result, errors.New(fmt.Sprintf("文字安全校验失败 错误:%s", msg))) } return NewPipeResult(result) } return NewPipeResult(false) }, } )
Functions ¶
func AcquireLock ¶
func AcquireLock(rdb rueidiscompat.Cmdable, key string, value string, expiration time.Duration) bool
AcquireLock 加锁 需要设置key和value 以及锁的时间
func CbcRegisterHandler ¶
func CompareAndDiff ¶
func CompareAndDiff(origin interface{}, bodyData map[string]interface{}, oldData map[string]interface{}, tagName string) map[string]interface{}
CompareAndDiff 对比不同 逻辑是出现在bodyData中的 然后origin与oldData不一致的 则返回一个diff Map
func DefaultModelMap ¶
func FastMsgMap ¶
func GetModelAllCount ¶
GetModelAllCount 使用 metadata 统计文档数量 https://www.mongodb.com/docs/drivers/go/current/fundamentals/crud/read-operations/count/
func MongoBulkInsert ¶
func MongoBulkInsertCount ¶
func MongoFilterGetOne ¶
func MongoFilters ¶
func MongoGetOne ¶
MongoGetOne 传入实例 返回new之后的指针
func MongoIterateByBatch ¶
func MongoRandom ¶
func MongoUpdateOne ¶
func ReleaseLock ¶
func ReleaseLock(client rueidiscompat.Cmdable, key string, value string) error
ReleaseLock 释放锁 必须传入正确的key和value才能释放 使用lua脚本
func SchemaValidFunc ¶
SchemaValidFunc 验证数据
func ToJsonSchema ¶
func ToJsonSchema[T any](origin T, omitFields ...string) *jsonschema.Schema
Types ¶
type AccountCoin ¶
type AccountCoin struct { Balance uint64 `json:"balance,omitempty" bson:"balance,omitempty" comment:"余额(分)" ` // 余额 单位是分 ReferrerUid string `json:"referrer_uid,omitempty" bson:"referrer_uid,omitempty" comment:"介绍人uid"` // 介绍人 }
func (*AccountCoin) GetBalance ¶
func (a *AccountCoin) GetBalance() uint64
func (*AccountCoin) GetReferrerUid ¶
func (a *AccountCoin) GetReferrerUid() string
func (*AccountCoin) SetBalance ¶
func (a *AccountCoin) SetBalance(newBalance uint64)
func (*AccountCoin) SetReferrerUid ¶
func (a *AccountCoin) SetReferrerUid(referrer string)
type AccountComm ¶
type AccountComm struct { AvatarUrl string `json:"avatar_url,omitempty" bson:"avatar_url,omitempty" comment:"头像地址"` // 头像地址 NickName string `json:"nick_name,omitempty" bson:"nick_name,omitempty" comment:"昵称"` // 昵称 Disable bool `json:"disable,omitempty" bson:"disable" comment:"是否禁用"` Msg string `json:"msg,omitempty" bson:"msg,omitempty" comment:"状态说明"` }
func (*AccountComm) GetAvatarUrl ¶
func (a *AccountComm) GetAvatarUrl() string
func (*AccountComm) GetDisable ¶
func (a *AccountComm) GetDisable() bool
func (*AccountComm) GetMsg ¶
func (a *AccountComm) GetMsg() string
func (*AccountComm) GetNickName ¶
func (a *AccountComm) GetNickName() string
func (*AccountComm) SetAvatarUrl ¶
func (a *AccountComm) SetAvatarUrl(uri string)
func (*AccountComm) SetDisable ¶
func (a *AccountComm) SetDisable(newDisable bool)
func (*AccountComm) SetMsg ¶
func (a *AccountComm) SetMsg(newMsg string)
func (*AccountComm) SetNickName ¶
func (a *AccountComm) SetNickName(name string)
type AccountPass ¶
type AccountPass struct { UserName string `json:"user_name,omitempty" bson:"user_name,omitempty" comment:"用户名"` Password string `json:"password,omitempty" bson:"password,omitempty" comment:"加密后登录密码"` Salt string `json:"salt,omitempty" bson:"salt,omitempty" comment:"密码加密salt"` Email string `json:"email,omitempty" bson:"email,omitempty" comment:"邮箱地址"` TelPhone string `json:"tel_phone,omitempty" bson:"tel_phone,omitempty" comment:"电话号码"` // 电话号码 }
func (*AccountPass) GetEmail ¶
func (a *AccountPass) GetEmail() string
func (*AccountPass) GetPassword ¶
func (a *AccountPass) GetPassword() string
func (*AccountPass) GetTelPhone ¶
func (a *AccountPass) GetTelPhone() string
func (*AccountPass) GetUserName ¶
func (a *AccountPass) GetUserName() string
func (*AccountPass) PasswordMd5 ¶
func (a *AccountPass) PasswordMd5(rawPassword string) (m5ps string, salt string)
PasswordMd5 通过原始密码生成加密的m5为password
func (*AccountPass) SetEmail ¶
func (a *AccountPass) SetEmail(newEmail string)
func (*AccountPass) SetPassword ¶
func (a *AccountPass) SetPassword(newPassword string)
SetPassword 设置密码 明文 会自动加密
func (*AccountPass) SetTelPhone ¶
func (a *AccountPass) SetTelPhone(newTelPhone string)
func (*AccountPass) SetUserName ¶
func (a *AccountPass) SetUserName(newUserName string)
func (*AccountPass) ValidPassword ¶
func (a *AccountPass) ValidPassword(rawPassword string) bool
ValidPassword 验证密码输出是否正确 password 为输入密码
type AccountPlatform ¶
type AccountPlatform struct { Appid string `json:"appid,omitempty" bson:"appid,omitempty" comment:"平台appid"` // 同样是微信小程序 可能有多个应用 这就是应用id Name string `json:"name,omitempty" bson:"name,omitempty" comment:"平台名称"` // 微信小程序 抖音 Pid string `json:"pid,omitempty" bson:"pid,omitempty" comment:"平台ID"` // 常见于微信的openid UnionId string `json:"union_id,omitempty" bson:"union_id,omitempty" comment:"通用ID"` // 常见于微信的unionid NickName string `json:"nick_name,omitempty" bson:"nick_name,omitempty" comment:"平台昵称"` AvatarUrl string `json:"avatar_url,omitempty" bson:"avatar_url,omitempty" comment:"平台头像"` Password string `json:"password,omitempty" bson:"password,omitempty" comment:"密码"` Phone string `json:"phone,omitempty" bson:"phone,omitempty" comment:"手机号"` // 平台绑定的手机号码 与用户手机号码可能不同 Scopes []string `json:"scopes,omitempty" bson:"scopes,omitempty" comment:"授权范围"` // 平台的授权范围 AuthorTime time.Time `json:"author_time,omitempty" bson:"author_time,omitempty" comment:"平台授权时间"` // 如果是第三方授权 则有一个授权时间 PublicData *AccountPlatformPublic `json:"public_data,omitempty" bson:"public_data,omitempty" comment:"平台公共数据"` }
type AccountPlatformPublic ¶
type AccountPlatformPublic struct { Favorite int `json:"favorite,omitempty" bson:"favorite,omitempty" comment:"我的收藏数量"` // 用于我的收藏数量 Digg int `json:"digg,omitempty" bson:"digg,omitempty" comment:"被点赞数量"` // 用于我的作品的被点赞数量 WorkCount int `json:"work_count,omitempty" bson:"work_count,omitempty" comment:"作品数量"` Fans int `json:"fans,omitempty" bson:"fans,omitempty" comment:"粉丝数量"` Follow int `json:"follow,omitempty" bson:"follow,omitempty" comment:"关注数量"` PlayView int `json:"play_view,omitempty" bson:"play_view,omitempty" comment:"播放数量"` // 用于被多少人点开看了 Recommend int `json:"recommend,omitempty" bson:"recommend,omitempty" comment:"推荐数量"` // 用户被推荐给多少人看了 Description string `json:"description,omitempty" bson:"description,omitempty" comment:"描述简介"` }
type Attribute ¶
type Attribute struct { GenType string `json:"gen_type,omitempty" bson:"gen_type,omitempty"` // 自动生成方式 GenLen int `json:"gen_len,omitempty" bson:"gen_len,omitempty"` // 生成长度 GenStat int `json:"gen_stat,omitempty" bson:"gen_stat,omitempty"` // 自动生成起始值 GenEnd int `json:"gen_end,omitempty" bson:"gen_end,omitempty"` // 自动生成结束值 AllowEdit bool `json:"allow_edit,omitempty" bson:"allow_edit,omitempty"` // 生成的值是否允许修改 默认不允许 }
type CbcRequestData ¶
type CbcRequestData struct { Query map[string]interface{} `json:"query"` Body json.RawMessage `json:"body"` Router string `json:"router"` }
type CbcService ¶
type CbcService struct {
// contains filtered or unexported fields
}
func NewCbcService ¶
func NewCbcService(iv string) *CbcService
func (*CbcService) CbcMainHandler ¶
func (c *CbcService) CbcMainHandler(ctx iris.Context)
type GenericsAccount ¶
type GenericsAccount struct { ModelBase `bson:",inline"` AccountPass `bson:",inline"` AccountCoin `bson:",inline"` AccountComm `bson:",inline"` // 在mongo中 可以直接使用.法 也就是 platforms.name 就可以传所有数组对象的name包含了的 Platforms []*AccountPlatform `json:"platforms,omitempty" bson:"platforms,omitempty" comment:"平台信息"` }
func (*GenericsAccount) BulkInsert ¶
func (s *GenericsAccount) BulkInsert(ctx context.Context, db *qmgo.Collection, accounts ...*GenericsAccount) error
func (*GenericsAccount) Filters ¶
func (s *GenericsAccount) Filters(ctx context.Context, db *qmgo.Collection, filters bson.M) ([]*GenericsAccount, error)
func (*GenericsAccount) GetAccountPass ¶
func (s *GenericsAccount) GetAccountPass() AccountPass
func (*GenericsAccount) GetCoin ¶
func (s *GenericsAccount) GetCoin() AccountCoin
func (*GenericsAccount) GetComm ¶
func (s *GenericsAccount) GetComm() AccountComm
func (*GenericsAccount) GetOne ¶
func (s *GenericsAccount) GetOne(ctx context.Context, db *qmgo.Collection, uid string) (*GenericsAccount, error)
func (*GenericsAccount) Random ¶
func (s *GenericsAccount) Random(ctx context.Context, db *qmgo.Collection, filters bson.D, count int) ([]*GenericsAccount, error)
func (*GenericsAccount) SetAccountPass ¶
func (s *GenericsAccount) SetAccountPass(pass AccountPass)
func (*GenericsAccount) SetComm ¶
func (s *GenericsAccount) SetComm(comm AccountComm)
type HashGenPipe ¶
type HttpRequestConfig ¶
type HttpRequestConfig struct { Uri string `json:"uri,omitempty"` // 请求地址 Method string `json:"method,omitempty"` // 请求方法 PathParams map[string]string `json:"path_params,omitempty"` // UrlParams map[string]any `json:"url_params,omitempty"` // Body any `json:"body,omitempty"` // Headers map[string]string `json:"headers,omitempty"` // 请求头设置 MustCode int `json:"must_code,omitempty"` // 响应码 }
func (*HttpRequestConfig) GetMethod ¶
func (c *HttpRequestConfig) GetMethod() string
func (*HttpRequestConfig) GetMustCode ¶
func (c *HttpRequestConfig) GetMustCode() int
type IAccountGenerics ¶
type IAccountGenerics interface { SetAccountPass(pass AccountPass) GetAccountPass() AccountPass GetCoin() AccountCoin GetComm() AccountComm SetComm(comm AccountComm) // contains filtered or unexported methods }
type IAccountGenericsFull ¶
type IAccountGenericsFull interface { IAccountGenerics IAccountShortcut }
type IAccountShortcut ¶
type IAccountShortcut interface { Filters(ctx context.Context, db *qmgo.Collection, filters bson.M) ([]*GenericsAccount, error) GetOne(ctx context.Context, db *qmgo.Collection, uid string) (*GenericsAccount, error) Random(ctx context.Context, db *qmgo.Collection, filters bson.D, count int) ([]*GenericsAccount, error) UpdateOne(ctx context.Context, db *qmgo.Collection, uid string, pack bson.M) error BulkInsert(ctx context.Context, db *qmgo.Collection, accounts ...*GenericsAccount) error // contains filtered or unexported methods }
type IMongoBase ¶
type IMongoModel ¶
type IMongoModel interface { IMongoBase GetCollName() string SyncIndex() error }
type JwtCheckDep ¶
type JwtCheckDep struct { FlatMap JwtFlatBase Env string Authorization string // Auth头 }
type JwtFlatBase ¶
type JwtFlatBase struct { UserId string `json:"user_id,omitempty"` Env string `json:"env,omitempty"` Raw string `json:"raw,omitempty"` LoginTime string `json:"login_time,omitempty"` }
func (JwtFlatBase) IsShort ¶
func (c JwtFlatBase) IsShort() bool
type JwtGenPipe ¶
type JwtHelper ¶
type JwtHelper struct {
// contains filtered or unexported fields
}
func NewJwtHelper ¶
func (*JwtHelper) GenJwtToken ¶
func (*JwtHelper) JwtRedisGenKey ¶
func (*JwtHelper) JwtRedisGetKey ¶
func (*JwtHelper) JwtSaveToken ¶
func (*JwtHelper) JwtShortRedisGenKey ¶
func (*JwtHelper) TokenExtract ¶
func (c *JwtHelper) TokenExtract(token string, m *irisJwt.Middleware) (*JwtFlatBase, error)
TokenExtract jwt验证
type KvValidConfig ¶
type KvValidConfig struct { Origin any `json:"origin,omitempty"` // 原始值 Op string `json:"op,omitempty"` // 操作符 Value string `json:"value,omitempty"` // 值 }
func (*KvValidConfig) Check ¶
func (c *KvValidConfig) Check() (bool, error)
type KvsValidPipe ¶
type KvsValidPipe struct {
Records []*KvValidConfig `json:"records,omitempty" bson:"records,omitempty"`
}
type LocalCachePipe ¶
type LocalCachePipe struct { ExpireDuration time.Duration `json:"expire_duration,omitempty"` // 过期时间 默认1分钟 KeyGen *StrExpand `json:"key_gen,omitempty"` // key的来源 EmptyRaise bool `json:"empty_raise,omitempty"` // 获取时 为空报错 Values map[string]any `json:"values,omitempty"` DisWriteHeader bool `json:"dis_write_header,omitempty"` // 不写入header }
LocalCachePipe 使用 https://github.com/bluele/gcache
func (*LocalCachePipe) GetExpire ¶
func (c *LocalCachePipe) GetExpire() time.Duration
type ModelBase ¶
type ModelBase struct { Id primitive.ObjectID `json:"_id,omitempty" bson:"_id"` Uid string `json:"uid,omitempty" bson:"uid,omitempty"` UpdateAt time.Time `json:"update_at,omitempty" bson:"update_at,omitempty" comment:"更新时间"` CreateAt time.Time `json:"create_at,omitempty" bson:"create_at,omitempty" comment:"创建时间"` }
type ModelCtxAddConfig ¶
type ModelCtxAddConfig struct {
ModelId string `json:"model_id,omitempty"`
}
type ModelDelConfig ¶
type ModelGetData ¶
type ModelGetDataDep ¶
type ModelIndex ¶
type ModelIndex struct { FieldName []string `json:"field_name,omitempty" comment:"字段名"` // 支持多级 按.分割 数组是因为可以支持联合索引 这取决于保存的后端是否支持 Type string `json:"type,omitempty" comment:"类型"` // 2dSphere text unique unique_sparse normal }
func (*ModelIndex) Gen ¶
func (c *ModelIndex) Gen(v any) mongo.IndexModel
func (*ModelIndex) NewModel2dSphereIndex ¶
func (c *ModelIndex) NewModel2dSphereIndex(fields ...string) *ModelIndex
func (*ModelIndex) NewModelNormalIndex ¶
func (c *ModelIndex) NewModelNormalIndex(fields ...string) *ModelIndex
func (*ModelIndex) NewModelTextIndex ¶
func (c *ModelIndex) NewModelTextIndex(fields ...string) *ModelIndex
func (*ModelIndex) NewModelUniqueIndex ¶
func (c *ModelIndex) NewModelUniqueIndex(fields ...string) *ModelIndex
func (*ModelIndex) NewModelUniqueSparseIndex ¶
func (c *ModelIndex) NewModelUniqueSparseIndex(fields ...string) *ModelIndex
type ModelPutConfig ¶
type ModelPutConfig struct { QueryFilter *ut.QueryFull `json:"query_filter,omitempty"` DropKeys []string `json:"drop_keys,omitempty"` // 最后的diff还需要丢弃的key ModelId string `json:"model_id,omitempty"` RowId string `json:"row_id,omitempty"` UpdateTime bool `json:"update_time,omitempty"` UpdateForce bool `json:"update_force,omitempty"` // 强行覆盖 BodyMap map[string]any `json:"body_map,omitempty"` }
type ParseResponse ¶
type PipeJwtDep ¶
type QueryParseConfig ¶
type QueryParseConfig struct { SearchFields []string `json:"search_fields,omitempty"` Pks []*ut.Pk `json:"pks,omitempty"` GeoKey string `json:"geo_key,omitempty"` // 开启了geo的字段 InjectAnd []*ut.Kov `json:"inject_and,omitempty"` InjectOr []*ut.Kov `json:"inject_or,omitempty"` UrlParams map[string]string `json:"url_params,omitempty"` }
QueryParseConfig 所有的fields都是以json tag为准
type RandomPipe ¶
type RateLimitPipe ¶
type RateLimitPipe struct { // <limit>-<period> // * "S": second // * "M": minute // * "H": hour // * "D": day // // Examples: // // * 5 reqs/second: "5-S" // * 10 reqs/minute: "10-M" // * 1000 reqs/hour: "1000-H" // * 2000 reqs/day: "2000-D" RatePeriod string `json:"rate_period,omitempty"` Store string `json:"store,omitempty"` // 存储 暂时 memory KeyGen *StrExpand `json:"key_gen,omitempty"` // 判断key的来源 WriteHeader bool `json:"write_header,omitempty"` // 是否把rate状态写入到请求header中 }
type RbacAllowPipe ¶
type RbacAllowPipe struct { Sub string `json:"sub,omitempty"` // 访问对象不能为空 Domain string `json:"domain,omitempty"` // 默认自身站点名称 Obj string `json:"obj,omitempty"` // 默认当前访问路径 Act string `json:"act,omitempty"` // 默认当前请求方式 }
RbacAllowPipe 用户是否有权通过此操作 谁(sub)在那个域名(domain)下进行了什么资源(obj)的什么操作(act)
type RbacDomain ¶
type RbacDomain struct { E *casbin.Enforcer // contains filtered or unexported fields }
func NewRbacDomain ¶
func NewRbacDomain(redisAddress, password string) (*RbacDomain, error)
func (*RbacDomain) DelRead ¶
func (c *RbacDomain) DelRead(uid string) error
func (*RbacDomain) DelRoleDefaultDomain ¶
func (c *RbacDomain) DelRoleDefaultDomain(uid string, role string) (bool, error)
func (*RbacDomain) DelRoot ¶
func (c *RbacDomain) DelRoot(uid string) error
func (*RbacDomain) DelStaff ¶
func (c *RbacDomain) DelStaff(uid string) error
func (*RbacDomain) IsStaffOrRoot ¶
func (c *RbacDomain) IsStaffOrRoot(uid string) bool
func (*RbacDomain) SetRoleDefaultDomain ¶
func (c *RbacDomain) SetRoleDefaultDomain(uid string, role string) (bool, error)
type RbacGetRolePipe ¶
type RbacGetRolePipe struct { Domain string `json:"domain,omitempty"` UserId string `json:"user_id,omitempty"` }
RbacGetRolePipe 获取用户角色操作序列包
type RedisKv ¶
type RedisOperate ¶
type RedisOperate struct { // 最终组合成{Name}: {COMMAND} [{mid:key} {value}] {runAttach:{key | KEY} {value} 模板替换} {EXPIRY} = {ResultType} Uid string `json:"mid,omitempty"` // 用户id 自动解析到key上面去 Type string `json:"type,omitempty"` // 类型 string, list, set, zSet, hash, stream, json? 暂定 可不填 Command string `json:"command,omitempty"` // 命令 https://redis.io/commands/ 对应上面Type类型 必填 Kvs []RedisKv `json:"kvs,omitempty"` // key value 对应关系 Attach *StrExpand `json:"runAttach,omitempty"` // 模板key 区分大小写 Expiry string `json:"expiry,omitempty"` // NX XX GT LT ResultType string `json:"result_type,omitempty"` // 结果类型 推荐直接为空 (string|[]) (int 8 16 32 64|[]|{}) bool (number float 32 64|[]) {}string 为空则any直接输出 AllowNil bool `json:"allow_nil,omitempty"` // 允许结果为空 }
RedisOperate redis操作 必传uid 一定要注意attach命令需要区分大小写 所有的key都会自动加上 reqUid:key
func (*RedisOperate) Build ¶
func (c *RedisOperate) Build() (*redisAb, error)
func (*RedisOperate) RespParse ¶
func (c *RedisOperate) RespParse(resp rueidis.RedisResult) (result any, err error)
type RedisOperates ¶
type RedisOperates struct {
Records []*RedisOperate `json:"records,omitempty" bson:"records,omitempty"`
}
type ReqResponse ¶
type RequestCachePipe ¶
type RequestCachePipe struct { CacheTime time.Duration `json:"cache_time,omitempty"` // 不传 默认1分钟 AttachData map[string]string `json:"attach_data,omitempty"` }
func (*RequestCachePipe) GetCacheKey ¶
func (c *RequestCachePipe) GetCacheKey(ctx iris.Context) (string, error)
func (*RequestCachePipe) GetCacheTime ¶
func (c *RequestCachePipe) GetCacheTime() time.Duration
type RuleValidate ¶
type RuleValidate struct { Key string `json:"key,omitempty"` Value any `json:"value,omitempty"` Rules string `json:"rules,omitempty"` // 规则 看上面 NeedType string `json:"need_type,omitempty"` // 类型转换 可为空 }
RuleValidate 使用这个库 https://github.com/gookit/validate/blob/master/README.zh-CN.md 格式是这样的 required|int|min:1|max:99 处理方法为
type RulesValidate ¶
type RulesValidate struct {
Record []*RuleValidate `json:"record,omitempty"`
}
func (*RulesValidate) Valid ¶
func (c *RulesValidate) Valid(data map[string]any) ValidResult
type RunResp ¶
type RunResp[T any] struct { Result T // 执行结果 Msg string // 错误说明 有说明则返回说明 Err error // 错误 ReqCode int // 请求状态码 权重在pipeline定义的errCode之后 BusinessCode int // 业务code 仅在错误时有则会返回 IsBreak bool // 是否中断之后的执行 }
RunResp 操作序列执行结果
func NewPipeErr ¶
func NewPipeResult ¶
func NewPipeResultErr ¶
func (*RunResp[T]) RaiseError ¶
func (c *RunResp[T]) RaiseError(ctx iris.Context)
func (*RunResp[T]) ReturnSuccess ¶
func (c *RunResp[T]) ReturnSuccess(ctx iris.Context)
func (*RunResp[T]) SetBusinessCode ¶
func (*RunResp[T]) SetReqCode ¶
type RunnerContext ¶
type RunnerContext[T any, P any, D any, R any] struct { Key string `json:"key,omitempty"` Name string `json:"name,omitempty"` Desc string `json:"desc,omitempty"` // contains filtered or unexported fields }
RunnerContext 运行器上下文 T 是原始传入值 运行的默认值 P 是执行传入的参数 运行的配置 D 是db 运行的依赖 R 执行结果类型
func (*RunnerContext[T, P, D, R]) NewPipeErr ¶
func (c *RunnerContext[T, P, D, R]) NewPipeErr(err error) *RunResp[R]
func (*RunnerContext[T, P, D, R]) Run ¶
func (c *RunnerContext[T, P, D, R]) Run(ctx iris.Context, origin T, params P, db D, more ...any) *RunResp[R]
func (*RunnerContext[T, P, D, R]) SetDesc ¶
func (c *RunnerContext[T, P, D, R]) SetDesc(desc string) *RunnerContext[T, P, D, R]
func (*RunnerContext[T, P, D, R]) SetKey ¶
func (c *RunnerContext[T, P, D, R]) SetKey(key string) *RunnerContext[T, P, D, R]
func (*RunnerContext[T, P, D, R]) SetName ¶
func (c *RunnerContext[T, P, D, R]) SetName(name string) *RunnerContext[T, P, D, R]
type SchemaValidConfig ¶
type SchemaValidConfig struct {
Schema *jsonschema.Schema `json:"schema,omitempty"` // 验证器 使用 schema 进行验证
}
type SmsClient ¶
type SmsClient struct {
// contains filtered or unexported fields
}
func NewDefaultSmsClient ¶
func NewSmsClient ¶
func (*SmsClient) SendBeforeCheck ¶
type StrExpand ¶
type StrExpand struct { Key string `json:"key,omitempty"` KeyMap []StrTemplate `json:"key_map,omitempty"` }
StrExpand 字符串展开 字符串模板
type StrTemplate ¶
type SwipeItem ¶
type SwipeValid ¶
type SwipeValid struct { Sid string `json:"sid,omitempty"` RefreshCount int `json:"refresh_count,omitempty"` // 刷新次数 X int64 `json:"x,omitempty"` // 停止时的x 滑块左侧上角 Y int64 `json:"y,omitempty"` // 停止时的y 滑块左侧上角 T time.Time `json:"t,omitempty"` // 滑动开始的时间 Te time.Time `json:"te,omitempty"` // 滑动结束的时间 S float64 `json:"s,omitempty"` // 拖动速度 N float64 `json:"n,omitempty"` // 归一化 拖动X平均值波动值最高 Nm float64 `json:"nm,omitempty"` // 归一化 拖动X平均值波动值最低 }
type SwipeValidCode ¶
type SwipeValidCode struct { RandomCount int8 `json:"random_count,omitempty"` // Prefix string `json:"Prefix,omitempty"` // 前缀 EnableTime time.Time `json:"enable_time,omitempty"` // 生效时间 ExpireSec int64 `json:"expire_sec,omitempty"` // 过期秒数 // contains filtered or unexported fields }
SwipeValidCode 滑块验证码实例
func NewSwipeValidInst ¶
func NewSwipeValidInst(rdb rueidis.Client) *SwipeValidCode
func (*SwipeValidCode) BlockSize ¶
func (c *SwipeValidCode) BlockSize(half bool) int
func (*SwipeValidCode) Check ¶
func (c *SwipeValidCode) Check(ctx iris.Context, raw string) (*SwipeValid, error)
func (*SwipeValidCode) Gen ¶
func (c *SwipeValidCode) Gen(ctx context.Context) (*SwipeItem, error)
Gen 生成滑块要素并存入redis
func (*SwipeValidCode) RandomBlockX ¶
func (c *SwipeValidCode) RandomBlockX() int
func (*SwipeValidCode) RandomBlockY ¶
func (c *SwipeValidCode) RandomBlockY() int
func (*SwipeValidCode) SetExpireSec ¶
func (c *SwipeValidCode) SetExpireSec(newSec int64)
func (*SwipeValidCode) SetPrefix ¶
func (c *SwipeValidCode) SetPrefix(prefix string)
func (*SwipeValidCode) SetRandomCount ¶
func (c *SwipeValidCode) SetRandomCount(newCount int8)
type ValidResult ¶
Source Files ¶
- a_cache.go
- a_hash.go
- a_http_request.go
- a_img_safe.go
- a_jwt.go
- a_jwt_check.go
- a_jwt_exchange.go
- a_jwt_flat.go
- a_jwt_tool.go
- a_jwt_visit.go
- a_kv_valid.go
- a_local_cache.go
- a_model_add.go
- a_model_body.go
- a_model_del.go
- a_model_get.go
- a_model_index.go
- a_model_put.go
- a_mongo.go
- a_query_parse.go
- a_random.go
- a_rate.go
- a_rbac.go
- a_redis.go
- a_response.go
- a_rules_valid.go
- a_schema_valid.go
- a_schema_valid_tools.go
- a_sms.go
- a_swipe_valid.go
- a_text_safe.go
- cbc_requests.go
- error.go
- gen.go
- generics_account.go
- index.go
- mock.go
- model_preset.go
- mongo_operator.go
- pipeline.go
- pipeline_runner.go
- redis_operator.go
- sms.go
- sony_idgen.go
- swipe_valid.go
- tools.go
- user_rbac.go