mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-11-14 13:13:51 +08:00
tt
This commit is contained in:
31
hotgo-server/app/com/cache_com.go
Normal file
31
hotgo-server/app/com/cache_com.go
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package com
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcache"
|
||||
)
|
||||
|
||||
type cache struct {
|
||||
}
|
||||
|
||||
var (
|
||||
Cache = new(cache)
|
||||
)
|
||||
|
||||
func (component *cache) New() *gcache.Cache {
|
||||
c := gcache.New()
|
||||
|
||||
//redis
|
||||
adapter := gcache.NewAdapterRedis(g.Redis())
|
||||
|
||||
//内存
|
||||
//adapter := gcache.NewAdapterMemory()
|
||||
c.SetAdapter(adapter)
|
||||
return c
|
||||
}
|
||||
62
hotgo-server/app/com/captcha_com.go
Normal file
62
hotgo-server/app/com/captcha_com.go
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package com
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/mojocn/base64Captcha"
|
||||
)
|
||||
|
||||
var Captcha = new(captcha)
|
||||
|
||||
type captcha struct{}
|
||||
|
||||
//
|
||||
// @Title 获取字母数字混合验证码
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Return idKeyC
|
||||
// @Return base64stringC
|
||||
//
|
||||
func (component *captcha) GetVerifyImgString(ctx context.Context) (idKeyC string, base64stringC string) {
|
||||
driver := &base64Captcha.DriverString{
|
||||
Height: 80,
|
||||
Width: 240,
|
||||
//NoiseCount: 50,
|
||||
//ShowLineOptions: 20,
|
||||
Length: 4,
|
||||
Source: "abcdefghjkmnpqrstuvwxyz23456789",
|
||||
Fonts: []string{"chromohv.ttf"},
|
||||
}
|
||||
driver = driver.ConvertFonts()
|
||||
store := base64Captcha.DefaultMemStore
|
||||
c := base64Captcha.NewCaptcha(driver, store)
|
||||
idKeyC, base64stringC, err := c.Generate()
|
||||
if err != nil {
|
||||
g.Log().Error(ctx,err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 验证输入的验证码是否正确
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param id
|
||||
// @Param answer
|
||||
// @Return bool
|
||||
//
|
||||
func (component *captcha) VerifyString(id, answer string) bool {
|
||||
driver := new(base64Captcha.DriverString)
|
||||
store := base64Captcha.DefaultMemStore
|
||||
c := base64Captcha.NewCaptcha(driver, store)
|
||||
answer = gstr.ToLower(answer)
|
||||
return c.Verify(id, answer, true)
|
||||
}
|
||||
107
hotgo-server/app/com/context_com.go
Normal file
107
hotgo-server/app/com/context_com.go
Normal file
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package com
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/bufanyun/hotgo/app/consts"
|
||||
"github.com/bufanyun/hotgo/app/model"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
type comContext struct{}
|
||||
|
||||
var Context = new(comContext)
|
||||
|
||||
//
|
||||
// @Title 初始化上下文对象指针到上下文对象中,以便后续的请求流程中可以修改
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param r
|
||||
// @Param customCtx
|
||||
//
|
||||
func (component *comContext) Init(r *ghttp.Request, customCtx *model.Context) {
|
||||
r.SetCtxVar(consts.ContextKey, customCtx)
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获得上下文变量,如果没有设置,那么返回nil
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Return *model.Context
|
||||
//
|
||||
func (component *comContext) Get(ctx context.Context) *model.Context {
|
||||
value := ctx.Value(consts.ContextKey)
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
if localCtx, ok := value.(*model.Context); ok {
|
||||
return localCtx
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 将上下文信息设置到上下文请求中,注意是完整覆盖
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param user
|
||||
//
|
||||
func (component *comContext) SetUser(ctx context.Context, user *model.Identity) {
|
||||
component.Get(ctx).User = user
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 设置组件响应 用于全局日志使用
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param response
|
||||
//
|
||||
func (component *comContext) SetResponse(ctx context.Context, response *model.Response) {
|
||||
component.Get(ctx).ComResponse = response
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 设置应用模块
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param module
|
||||
//
|
||||
func (component *comContext) SetModule(ctx context.Context, module string) {
|
||||
component.Get(ctx).Module = module
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 设置请求耗时
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param module
|
||||
//
|
||||
func (component *comContext) SetTakeUpTime(ctx context.Context, takeUpTime int64) {
|
||||
component.Get(ctx).TakeUpTime = takeUpTime
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取用户ID
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Return int
|
||||
//
|
||||
func (component *comContext) GetUserId(ctx context.Context) int64 {
|
||||
user := component.Get(ctx).User
|
||||
if user == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return user.Id
|
||||
}
|
||||
254
hotgo-server/app/com/ip_com.go
Normal file
254
hotgo-server/app/com/ip_com.go
Normal file
@@ -0,0 +1,254 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package com
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/axgle/mahonia"
|
||||
"github.com/bufanyun/hotgo/app/model/entity"
|
||||
"github.com/bufanyun/hotgo/app/utils"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/kayon/iploc"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Ip = new(ip)
|
||||
|
||||
type ip struct{}
|
||||
|
||||
type IpLocationData struct {
|
||||
Ip string `json:"ip"`
|
||||
Country string `json:"country"`
|
||||
Region string `json:"region"`
|
||||
Province string `json:"province"`
|
||||
ProvinceCode int `json:"province_code"`
|
||||
City string `json:"city"`
|
||||
CityCode int `json:"city_code"`
|
||||
Area string `json:"area"`
|
||||
AreaCode int `json:"area_code"`
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 通过Whois接口查询IP归属地
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param ip
|
||||
// @Return IpLocationData
|
||||
//
|
||||
func (component *ip) WhoisLocation(ctx context.Context, ip string) IpLocationData {
|
||||
|
||||
type whoisRegionData struct {
|
||||
Ip string `json:"ip"`
|
||||
Pro string `json:"pro" `
|
||||
ProCode string `json:"proCode" `
|
||||
City string `json:"city" `
|
||||
CityCode string `json:"cityCode"`
|
||||
Region string `json:"region"`
|
||||
RegionCode string `json:"regionCode"`
|
||||
Addr string `json:"addr"`
|
||||
Err string `json:"err"`
|
||||
}
|
||||
|
||||
if !utils.Validate.IsIp(ip) {
|
||||
return IpLocationData{}
|
||||
}
|
||||
|
||||
response, err := g.Client().Timeout(10*time.Second).Get(ctx, "http://whois.pconline.com.cn/ipJson.jsp?ip="+ip+"&json=true")
|
||||
if err != nil {
|
||||
err = gerror.New(err.Error())
|
||||
return IpLocationData{
|
||||
Ip: ip,
|
||||
}
|
||||
}
|
||||
|
||||
defer response.Close()
|
||||
|
||||
var enc mahonia.Decoder
|
||||
enc = mahonia.NewDecoder("gbk")
|
||||
|
||||
data := enc.ConvertString(response.ReadAllString())
|
||||
|
||||
g.Log().Print(ctx, "data:", data)
|
||||
whoisData := whoisRegionData{}
|
||||
if err := gconv.Struct(data, &whoisData); err != nil {
|
||||
err = gerror.New(err.Error())
|
||||
|
||||
g.Log().Print(ctx, "err:", err)
|
||||
return IpLocationData{
|
||||
Ip: ip,
|
||||
}
|
||||
}
|
||||
|
||||
g.Log().Print(ctx, "whoisData:", whoisData)
|
||||
|
||||
return IpLocationData{
|
||||
Ip: whoisData.Ip,
|
||||
//Country string `json:"country"`
|
||||
Region: whoisData.Addr,
|
||||
Province: whoisData.Pro,
|
||||
ProvinceCode: gconv.Int(whoisData.ProCode),
|
||||
City: whoisData.City,
|
||||
CityCode: gconv.Int(whoisData.CityCode),
|
||||
Area: whoisData.Region,
|
||||
AreaCode: gconv.Int(whoisData.RegionCode),
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 通过Cz88的IP库查询IP归属地
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param ip
|
||||
// @Return IpLocationData
|
||||
//
|
||||
func (component *ip) Cz88Find(ctx context.Context, ip string) IpLocationData {
|
||||
if !utils.Validate.IsIp(ip) {
|
||||
g.Log().Print(ctx, "ip格式错误:", ip)
|
||||
return IpLocationData{}
|
||||
}
|
||||
|
||||
loc, err := iploc.OpenWithoutIndexes("./storage/ip/qqwry-utf8.dat")
|
||||
if err != nil {
|
||||
err = gerror.New(err.Error())
|
||||
return IpLocationData{
|
||||
Ip: ip,
|
||||
}
|
||||
}
|
||||
|
||||
detail := loc.Find(ip)
|
||||
if detail == nil {
|
||||
return IpLocationData{
|
||||
Ip: ip,
|
||||
}
|
||||
}
|
||||
|
||||
locationData := IpLocationData{
|
||||
Ip: ip,
|
||||
Country: detail.Country,
|
||||
Region: detail.Region,
|
||||
Province: detail.Province,
|
||||
City: detail.City,
|
||||
Area: detail.County,
|
||||
}
|
||||
|
||||
if gstr.LenRune(locationData.Province) == 0 {
|
||||
return locationData
|
||||
}
|
||||
|
||||
var (
|
||||
provinceModel *entity.SysProvinces
|
||||
cityModel *entity.SysProvinces
|
||||
areaModel *entity.SysProvinces
|
||||
)
|
||||
|
||||
err = g.DB().Model("hg_common_provinces").
|
||||
Where("level", 1).
|
||||
WhereLike("title", "%"+locationData.Province+"%").
|
||||
Scan(&provinceModel)
|
||||
|
||||
if err != nil {
|
||||
err = gerror.New(err.Error())
|
||||
return locationData
|
||||
}
|
||||
|
||||
if provinceModel != nil {
|
||||
locationData.ProvinceCode = provinceModel.Id
|
||||
locationData.Province = provinceModel.Title
|
||||
}
|
||||
|
||||
if gstr.LenRune(locationData.City) == 0 {
|
||||
return locationData
|
||||
|
||||
// 是否为直辖市
|
||||
} else if component.IsJurisdictionByIpTitle(locationData.City) {
|
||||
locationData.CityCode = provinceModel.Id + 100
|
||||
locationData.City = "直辖市"
|
||||
} else {
|
||||
|
||||
//替换掉
|
||||
locationData.City = gstr.Replace(locationData.City, "地区", "")
|
||||
|
||||
err = g.DB().Model("hg_common_provinces").
|
||||
Where("level", 2).
|
||||
Where("pid", locationData.ProvinceCode).
|
||||
WhereLike("title", "%"+locationData.City+"%").
|
||||
Scan(&cityModel)
|
||||
|
||||
if err != nil {
|
||||
err = gerror.New(err.Error())
|
||||
return locationData
|
||||
}
|
||||
|
||||
if cityModel != nil {
|
||||
locationData.CityCode = cityModel.Id
|
||||
locationData.City = cityModel.Title
|
||||
}
|
||||
}
|
||||
|
||||
if gstr.LenRune(locationData.Area) == 0 {
|
||||
return locationData
|
||||
}
|
||||
|
||||
err = g.DB().Model("hg_common_provinces").
|
||||
Where("level", 3).
|
||||
Where("pid", locationData.CityCode).
|
||||
WhereLike("title", "%"+locationData.Area+"%").
|
||||
Scan(&areaModel)
|
||||
|
||||
if err != nil {
|
||||
err = gerror.New(err.Error())
|
||||
return locationData
|
||||
}
|
||||
|
||||
if areaModel != nil {
|
||||
locationData.AreaCode = areaModel.Id
|
||||
locationData.Area = areaModel.Title
|
||||
}
|
||||
|
||||
return locationData
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 判断地区名称是否为直辖市
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param title
|
||||
// @Return bool
|
||||
//
|
||||
func (component *ip) IsJurisdictionByIpTitle(title string) bool {
|
||||
|
||||
lists := []string{"北京市", "天津市", "重庆市", "上海市"}
|
||||
|
||||
for i := 0; i < len(lists); i++ {
|
||||
if gstr.Contains(lists[i], title) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取IP归属地信息
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param ip
|
||||
// @Return IpLocationData
|
||||
//
|
||||
func (component *ip) GetLocation(ctx context.Context, ip string) IpLocationData {
|
||||
method, _ := g.Cfg().Get(ctx, "hotgo.ipMethod", "cz88")
|
||||
|
||||
if method.String() == "whois" {
|
||||
return component.WhoisLocation(ctx, ip)
|
||||
}
|
||||
return component.Cz88Find(ctx, ip)
|
||||
}
|
||||
161
hotgo-server/app/com/jwt_com.go
Normal file
161
hotgo-server/app/com/jwt_com.go
Normal file
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package com
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/bufanyun/hotgo/app/consts"
|
||||
"github.com/bufanyun/hotgo/app/model"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/gogf/gf/v2/crypto/gmd5"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type JWT struct{}
|
||||
|
||||
var Jwt = new(JWT)
|
||||
|
||||
//
|
||||
// @Title 为指定用户生成token
|
||||
// @Description 主要用于登录成功的jwt鉴权绑定
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param user 用户信息
|
||||
// @Param isRefresh 是否是刷新token
|
||||
// @Return interface{}
|
||||
// @Return error
|
||||
//
|
||||
func (component *JWT) GenerateLoginToken(ctx context.Context, user *model.Identity, isRefresh bool) (interface{}, error) {
|
||||
|
||||
jwtVersion, _ := g.Cfg().Get(ctx, "jwt.version", "1.0")
|
||||
jwtSign, _ := g.Cfg().Get(ctx, "jwt.sign", "hotGo")
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"id": user.Id,
|
||||
"username": user.Username,
|
||||
"realname": user.Realname,
|
||||
"avatar": user.Avatar,
|
||||
"email": user.Email,
|
||||
"mobile": user.Mobile,
|
||||
"last_time": user.LastTime,
|
||||
"last_ip": user.LastIp,
|
||||
"exp": user.Exp,
|
||||
"expires": user.Expires,
|
||||
"app": user.App,
|
||||
"role": user.Role,
|
||||
"visit_count": user.VisitCount,
|
||||
"is_refresh": isRefresh,
|
||||
"jwt_version": jwtVersion.String(),
|
||||
})
|
||||
|
||||
tokenString, err := token.SignedString(jwtSign.Bytes())
|
||||
if err != nil {
|
||||
err := gerror.New(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tokenStringMd5 := gmd5.MustEncryptString(tokenString)
|
||||
|
||||
// TODO 绑定登录token
|
||||
cache := Cache.New()
|
||||
key := consts.RedisJwtToken + tokenStringMd5
|
||||
|
||||
// TODO 将有效期转为持续时间,单位:秒
|
||||
expires, _ := time.ParseDuration(fmt.Sprintf("+%vs", user.Expires))
|
||||
|
||||
err = cache.Set(ctx, key, tokenString, expires)
|
||||
if err != nil {
|
||||
err := gerror.New(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
_ = cache.Set(ctx, consts.RedisJwtUserBind+user.App+":"+gconv.String(user.Id), key, expires)
|
||||
|
||||
return tokenString, err
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 解析token
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param tokenString
|
||||
// @Param secret
|
||||
// @Return jwt.MapClaims
|
||||
// @Return error
|
||||
//
|
||||
func (component *JWT) ParseToken(tokenString string, secret []byte) (jwt.MapClaims, error) {
|
||||
if tokenString == "" {
|
||||
err := gerror.New("token 为空")
|
||||
return nil, err
|
||||
}
|
||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return secret, nil
|
||||
})
|
||||
|
||||
if token == nil {
|
||||
err := gerror.New("token不存在")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||
return claims, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
token有效正确返回用户id
|
||||
*/
|
||||
//func(component *JWT) VerifyLoginToken(tokenString string) (uint, err error) {
|
||||
// //if tokenString == "" {
|
||||
// // err = gerror.New("token不能为空")
|
||||
// // return 0, err
|
||||
// //}
|
||||
//
|
||||
//}
|
||||
|
||||
//
|
||||
// @Title 获取 authorization
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param r
|
||||
// @Return string
|
||||
//
|
||||
func (component *JWT) GetAuthorization(r *ghttp.Request) string {
|
||||
|
||||
// TODO 默认从请求头获取
|
||||
var authorization = r.Header.Get("Authorization")
|
||||
|
||||
// TODO 如果请求头不存在则从get参数获取
|
||||
if authorization == "" {
|
||||
return r.Get("authorization").String()
|
||||
}
|
||||
|
||||
return gstr.Replace(authorization, "Bearer ", "")
|
||||
}
|
||||
|
||||
/**
|
||||
清掉所以的相关的redis
|
||||
*/
|
||||
func (component *JWT) Layout(adminUserId int, tokenString string) {
|
||||
if tokenString == "" {
|
||||
return
|
||||
}
|
||||
//g.Redis().Do("HDEL", "VerifyLoginToken", gmd5.MustEncryptString(tokenString))
|
||||
//// 删除
|
||||
//g.Redis().Do("HDEL", "VerifyLoginTokenAdminUserId", adminUserId)
|
||||
}
|
||||
83
hotgo-server/app/com/redis_com.go
Normal file
83
hotgo-server/app/com/redis_com.go
Normal file
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package com
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/database/gredis"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
var Redis = new(redis)
|
||||
|
||||
type redis struct{}
|
||||
|
||||
//
|
||||
// @Title 实例化redis
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param name
|
||||
// @Return *gredis.Redis
|
||||
//
|
||||
func (component *redis) Instance(name ...string) *gredis.Redis {
|
||||
return g.Redis(name...)
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 获取
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param key
|
||||
// @Return *gvar.Var
|
||||
// @Return error
|
||||
//
|
||||
func (component *redis) Get(ctx context.Context, key string) (*gvar.Var, error) {
|
||||
data, err := Redis.Instance().Do(ctx, "GET", key)
|
||||
if err != nil {
|
||||
err := gerror.New(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 设置
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param ctx
|
||||
// @Param key
|
||||
// @Param value
|
||||
// @Param expire
|
||||
// @Return *gvar.Var
|
||||
// @Return error
|
||||
//
|
||||
func (component *redis) Set(ctx context.Context, key string, value string, expire interface{}) (*gvar.Var, error) {
|
||||
|
||||
redisInstance := Redis.Instance()
|
||||
response, err := redisInstance.Do(ctx, "SET", key, value)
|
||||
if err != nil {
|
||||
err := gerror.New(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exp := gconv.Int(expire)
|
||||
// TODO 设置有效期
|
||||
if exp > 0 {
|
||||
_, err = redisInstance.Do(ctx, "EXPIRE", key, exp)
|
||||
if err != nil {
|
||||
err := gerror.New(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
121
hotgo-server/app/com/response_com.go
Normal file
121
hotgo-server/app/com/response_com.go
Normal file
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package com
|
||||
|
||||
import (
|
||||
"github.com/bufanyun/hotgo/app/consts"
|
||||
"github.com/bufanyun/hotgo/app/model"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Response = new(response)
|
||||
|
||||
type response struct{}
|
||||
|
||||
//
|
||||
// @Title 返回JSON数据并退出当前HTTP执行函数
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param r
|
||||
// @Param code
|
||||
// @Param message
|
||||
// @Param data
|
||||
//
|
||||
func (component *response) JsonExit(r *ghttp.Request, code int, message string, data ...interface{}) {
|
||||
component.RJson(r, code, message, data...)
|
||||
r.Exit()
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 标准返回结果数据结构封装
|
||||
// @Description 返回固定数据结构的JSON
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param r
|
||||
// @Param code 状态码(200:成功,302跳转,和http请求状态码一至)
|
||||
// @Param message 请求结果信息
|
||||
// @Param data 请求结果,根据不同接口返回结果的数据结构不同
|
||||
//
|
||||
func (component *response) RJson(r *ghttp.Request, code int, message string, data ...interface{}) {
|
||||
responseData := interface{}(nil)
|
||||
if len(data) > 0 {
|
||||
responseData = data[0]
|
||||
}
|
||||
Res := &model.Response{
|
||||
Code: code,
|
||||
Message: message,
|
||||
Timestamp: time.Now().Unix(),
|
||||
ReqId: Context.Get(r.Context()).ReqId,
|
||||
}
|
||||
|
||||
// TODO 如果不是正常的返回,则将data转为error
|
||||
if consts.CodeOK == code {
|
||||
Res.Data = responseData
|
||||
} else {
|
||||
Res.Error = responseData
|
||||
}
|
||||
|
||||
// TODO 清空响应
|
||||
r.Response.ClearBuffer()
|
||||
|
||||
// TODO 写入响应
|
||||
if err := r.Response.WriteJson(Res); err != nil {
|
||||
g.Log().Error(r.Context(), "响应异常:", err)
|
||||
}
|
||||
|
||||
// TODO 加入到上下文
|
||||
Context.SetResponse(r.Context(), Res)
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 返回成功JSON
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param isExit
|
||||
// @Param r
|
||||
// @Param message
|
||||
// @Param data
|
||||
//
|
||||
func (component *response) SusJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
|
||||
if isExit {
|
||||
component.JsonExit(r, consts.CodeOK, message, data...)
|
||||
}
|
||||
component.RJson(r, consts.CodeOK, message, data...)
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 返回失败JSON
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param isExit
|
||||
// @Param r
|
||||
// @Param message
|
||||
// @Param data
|
||||
//
|
||||
func (component *response) FailJson(isExit bool, r *ghttp.Request, message string, data ...interface{}) {
|
||||
if isExit {
|
||||
component.JsonExit(r, consts.CodeNil, message, data...)
|
||||
}
|
||||
component.RJson(r, consts.CodeNil, message, data...)
|
||||
}
|
||||
|
||||
//
|
||||
// @Title 重定向
|
||||
// @Description
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @Param r
|
||||
// @Param location
|
||||
// @Param code
|
||||
//
|
||||
func (component *response) Redirect(r *ghttp.Request, location string, code ...int) {
|
||||
r.Response.RedirectTo(location, code...)
|
||||
}
|
||||
|
||||
func (component *response) Download(r *ghttp.Request, location string, code ...int) {
|
||||
r.Response.ServeFileDownload("test.txt")
|
||||
}
|
||||
Reference in New Issue
Block a user