This commit is contained in:
孟帅
2023-05-12 16:20:22 +08:00
parent f30fd885be
commit 9198a53584
52 changed files with 982 additions and 834 deletions

View File

@@ -91,18 +91,12 @@ import (
)
// RouterPrefix 路由前缀
// 最终效果:/应用名称/插件模块名称/xxx/xxx
// 最终效果:/应用名称/插件模块名称/xxx/xxx。如果你不喜欢现在的路由风格,可以自行调整
func RouterPrefix(ctx context.Context, app, name string) string {
var prefix = "/"
switch app {
case consts.AppAdmin:
prefix = g.Cfg().MustGet(ctx, "router.admin.prefix", "/admin").String()
case consts.AppApi:
prefix = g.Cfg().MustGet(ctx, "router.api.prefix", "/api").String()
case consts.AppHome:
prefix = g.Cfg().MustGet(ctx, "router.home.prefix", "/home").String()
case consts.AppWebSocket:
prefix = g.Cfg().MustGet(ctx, "router.ws.prefix", "/socket").String()
if app != "" {
prefix = g.Cfg().MustGet(ctx, "router."+app+".prefix", "/"+app+"").String()
}
return prefix + "/" + name

View File

@@ -11,6 +11,13 @@
> 如果升级(覆盖)代码后打开会出现 sql 报错, 请检查更新的数据库格式或自行调整
### v2.6.10
updated 2023.05.12
- 增加增加jwt+缓存驱动实现的令牌认证,支持自动续约、可控过期失效策略
- 移除移除旧jwt功能库
- 移除:移除`decimal``mahonia` package
### v2.6.7
updated 2023.05.10
- 增加增加支付网关集成支付宝、微信支付、QQ支付可通过后台直接配置参数

View File

@@ -3,8 +3,8 @@
目录
- 缓存驱动
- 请求上下文(待写)
- JWT(待写)
- 请求上下文
- JWT
- 地理定位(待写)
- 通知(待写)
@@ -87,8 +87,68 @@ func test(ctx context.Context) {
```
### JWT
- 基于jwt+缓存驱动实现的用户登录令牌功能支持自动续约解决了jwt服务端无法退出问题和jwt令牌无法主动失效问题
#### 配置示例
```yaml
# 登录令牌
token:
secretKey: "hotgo123" # 令牌加密秘钥,考虑安全问题生产环境中请修改默认值
expires: 604800 # 令牌有效期单位秒。默认7天
autoRefresh: true # 是否开启自动刷新过期时间, false|true 默认为true
refreshInterval: 86400 # 刷新间隔单位秒。必须小于expires否则无法触发。默认1天内只允许刷新一次
maxRefreshTimes: 30 # 最大允许刷新次数,-1不限制。默认30次
multiLogin: true # 是否允许多端登录, false|true 默认为true
```
```go
// 待写
package admin
import (
"fmt"
"context"
"hotgo/internal/library/token"
"hotgo/internal/model"
)
func test(ctx context.Context) {
// 登录
user := &model.Identity{
Id: mb.Id,
Pid: mb.Pid,
DeptId: mb.DeptId,
RoleId: ro.Id,
RoleKey: ro.Key,
Username: mb.Username,
RealName: mb.RealName,
Avatar: mb.Avatar,
Email: mb.Email,
Mobile: mb.Mobile,
App: consts.AppAdmin,
LoginAt: gtime.Now(),
}
loginToken, expires, err := token.Login(ctx, user)
if err != nil {
return nil, err
}
// gf请求对象
r := *ghttp.Request
// 获取登录用户信息
user, err := token.ParseLoginUser(r)
if err != nil {
return
}
// 注销登录
err = token.Logout(r)
}
```
### 地理定位

View File

@@ -25,7 +25,7 @@ func WebSocket(ctx context.Context, group *ghttp.RouterGroup) {
websocket.Index,
)
// ws连接中间件
group.Middleware(service.Middleware().WebSocketToken)
group.Middleware(service.Middleware().WebSocketAuth)
group.Bind(
// 需要验证的路由
// ..

View File

@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package common
import (
@@ -13,7 +12,7 @@ import (
// LoginLogoutReq 注销登录
type LoginLogoutReq struct {
g.Meta `path:"/site/logout" method:"get" tags:"后台基础" summary:"注销登录"`
g.Meta `path:"/site/logout" method:"post" tags:"后台基础" summary:"注销登录"`
}
type LoginLogoutRes struct{}
@@ -21,7 +20,6 @@ type LoginLogoutRes struct{}
type LoginCaptchaReq struct {
g.Meta `path:"/site/captcha" method:"get" tags:"后台基础" summary:"获取登录验证码"`
}
type LoginCaptchaRes struct {
Cid string `json:"cid" dc:"验证码ID"`
Base64 string `json:"base64" dc:"验证码"`

View File

@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package monitor
import (
@@ -47,13 +46,12 @@ type OnlineModel struct {
Addr string `json:"addr"` // 客户端地址
Os string `json:"os"` // 客户端系统名称
Browser string `json:"browser"` // 浏览器
FirstTime uint64 `json:"firstTime"` // 首次连接时间
FirstTime int64 `json:"firstTime"` // 首次连接时间
HeartbeatTime uint64 `json:"heartbeatTime"` // 用户上次心跳时间
App string `json:"app"` // 应用名称
UserId int64 `json:"userId"` // 用户ID
Username string `json:"username"` // 用户名
Avatar string `json:"avatar"` // 头像
ExpTime int64 `json:"expTime"` // 过期时间
}
type OnlineModels []*OnlineModel

View File

@@ -10,7 +10,6 @@ require (
github.com/alibabacloud-go/tea-utils/v2 v2.0.1
github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible
github.com/apache/rocketmq-client-go/v2 v2.1.0
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
github.com/casbin/casbin/v2 v2.55.0
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/forgoer/openssl v1.4.0
@@ -18,13 +17,13 @@ require (
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.4.1
github.com/gogf/gf/contrib/nosql/redis/v2 v2.4.1
github.com/gogf/gf/v2 v2.4.1
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/gorilla/websocket v1.5.0
github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794
github.com/mojocn/base64Captcha v1.3.5
github.com/olekukonko/tablewriter v0.0.5
github.com/qiniu/go-sdk/v7 v7.14.0
github.com/shirou/gopsutil/v3 v3.23.3
github.com/shopspring/decimal v1.3.1
github.com/silenceper/wechat/v2 v2.1.4
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.633
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.633

View File

@@ -81,8 +81,6 @@ github.com/aliyun/credentials-go v1.1.2 h1:qU1vwGIBb3UJ8BwunHDRFtAhS6jnQLnde/yk0
github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
github.com/apache/rocketmq-client-go/v2 v2.1.0 h1:3eABKfxc1WmS2lLTTbKMe1gZfZV6u1Sx9orFnOfABV0=
github.com/apache/rocketmq-client-go/v2 v2.1.0/go.mod h1:oEZKFDvS7sz/RWU0839+dQBupazyBV7WX5cP6nrio0Q=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -179,6 +177,8 @@ github.com/gogf/gf/contrib/nosql/redis/v2 v2.4.1/go.mod h1:0t7pBtXdfuemskzkdxyC2
github.com/gogf/gf/v2 v2.4.1 h1:snsuvDhNFiRoAuWBbKfIIng0KyMaRA87Qr03GLir5j8=
github.com/gogf/gf/v2 v2.4.1/go.mod h1:tsbmtwcAl2chcYoq/fP9W2FZf06aw4i89X34nbSHo9Y=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -418,8 +418,6 @@ github.com/shoenig/go-m1cpu v0.1.4 h1:SZPIgRM2sEF9NJy50mRHu9PKGwxyyTTJIWvCtgVboz
github.com/shoenig/go-m1cpu v0.1.4/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ=
github.com/shoenig/test v0.6.3 h1:GVXWJFk9PiOjN0KoJ7VrJGH6uLPnqxR7/fe3HUPfE0c=
github.com/shoenig/test v0.6.3/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/silenceper/wechat/v2 v2.1.4 h1:X+G9C/EiBET5AK0zhrflX3ESCP/yxhJUvoRoSXHm0js=
github.com/silenceper/wechat/v2 v2.1.4/go.mod h1:F0PKqImb15THnwoqRNrZO1z3vpwyWuiHr5zzfnjdECY=

View File

@@ -7,6 +7,6 @@ package consts
// cache
const (
CacheJwtToken = "jwt_token:" // JWT-token
CacheJwtUserBind = "jwt_user_bind:" // JWT-用户身份绑定
CacheToken = "token" // 登录token
CacheTokenBind = "token_bind" // 登录用户身份绑定
)

View File

@@ -5,7 +5,9 @@
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package consts
import "github.com/gogf/gf/v2/text/gstr"
import (
"github.com/gogf/gf/v2/text/gstr"
)
// 错误解释
const (

View File

@@ -7,5 +7,5 @@ package consts
// VersionApp HotGo版本
const (
VersionApp = "2.6.7"
VersionApp = "2.6.10"
)

View File

@@ -3,13 +3,13 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package admin
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/text/gstr"
"hotgo/api/admin/monitor"
"hotgo/internal/consts"
@@ -79,13 +79,12 @@ func (c *cMonitor) OnlineList(ctx context.Context, req *monitor.OnlineListReq) (
Addr: conn.Addr,
Os: useragent.GetOs(conn.UserAgent),
Browser: useragent.GetBrowser(conn.UserAgent),
FirstTime: conn.FirstTime,
FirstTime: gtime.New(conn.User.LoginAt).Unix(),
HeartbeatTime: conn.HeartbeatTime,
App: conn.User.App,
UserId: conn.User.Id,
Username: conn.User.Username,
Avatar: conn.User.Avatar,
ExpTime: conn.User.Exp,
})
}

View File

@@ -7,16 +7,14 @@ package common
import (
"context"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/api/admin/common"
"hotgo/internal/consts"
"hotgo/internal/library/cache"
"hotgo/internal/library/captcha"
"hotgo/internal/library/jwt"
"hotgo/internal/library/token"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
@@ -112,13 +110,6 @@ func (c *cSite) Login(ctx context.Context, req *common.LoginReq) (res *common.Lo
// Logout 注销登录
func (c *cSite) Logout(ctx context.Context, req *common.LoginLogoutReq) (res *common.LoginLogoutRes, err error) {
token := consts.CacheJwtToken + gmd5.MustEncryptString(jwt.GetAuthorization(ghttp.RequestFromCtx(ctx)))
if len(token) == 0 {
err = gerror.New("当前用户未登录!")
return
}
// 删除登录token
_, err = cache.Instance().Remove(ctx, token)
err = token.Logout(ghttp.RequestFromCtx(ctx))
return
}

View File

@@ -27,7 +27,6 @@ type AdminMemberColumns struct {
Username string // 帐号
PasswordHash string // 密码
Salt string // 密码盐
AuthKey string // 授权令牌
PasswordResetToken string // 密码重置令牌
Integral string // 积分
Balance string // 余额
@@ -59,7 +58,6 @@ var adminMemberColumns = AdminMemberColumns{
Username: "username",
PasswordHash: "password_hash",
Salt: "salt",
AuthKey: "auth_key",
PasswordResetToken: "password_reset_token",
Integral: "integral",
Balance: "balance",

View File

@@ -35,7 +35,7 @@ type SysLogColumns struct {
ProvinceId string // 省编码
CityId string // 市编码
ErrorCode string // 报错code
ErrorMsg string // 报错信息
ErrorMsg string // 对外错误提示
ErrorData string // 报错日志
UserAgent string // UA信息
TakeUpTime string // 请求耗时

View File

@@ -23,15 +23,9 @@ func Tpl(name, tpl string) string {
// 最终效果:/应用名称/插件模块名称/xxx/xxx。如果你不喜欢现在的路由风格可以自行调整
func RouterPrefix(ctx context.Context, app, name string) string {
var prefix = "/"
switch app {
case consts.AppAdmin:
prefix = g.Cfg().MustGet(ctx, "router.admin.prefix", "/admin").String()
case consts.AppApi:
prefix = g.Cfg().MustGet(ctx, "router.api.prefix", "/api").String()
case consts.AppHome:
prefix = g.Cfg().MustGet(ctx, "router.home.prefix", "/home").String()
case consts.AppWebSocket:
prefix = g.Cfg().MustGet(ctx, "router.ws.prefix", "/socket").String()
if app != "" {
prefix = g.Cfg().MustGet(ctx, "router."+app+".prefix", "/"+app+"").String()
}
return prefix + "/" + name

View File

@@ -1,113 +0,0 @@
// Package jwt
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package jwt
import (
"context"
"fmt"
j "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"
"hotgo/internal/consts"
"hotgo/internal/library/cache"
"hotgo/internal/model"
"time"
)
// GenerateLoginToken 为指定用户生成token
func GenerateLoginToken(ctx context.Context, user *model.Identity, isRefresh bool) (string, error) {
var (
jwtVersion = g.Cfg().MustGet(ctx, "jwt.version", "1.0")
jwtSign = g.Cfg().MustGet(ctx, "jwt.sign", "hotGo")
token = j.NewWithClaims(j.SigningMethodHS256, j.MapClaims{
"id": user.Id,
"pid": user.Pid,
"deptId": user.DeptId,
"roleId": user.RoleId,
"roleKey": user.RoleKey,
"username": user.Username,
"realName": user.RealName,
"avatar": user.Avatar,
"email": user.Email,
"mobile": user.Mobile,
"exp": user.Exp,
"expires": user.Expires,
"app": user.App,
"isRefresh": isRefresh,
"jwtVersion": jwtVersion.String(),
})
)
tokenString, err := token.SignedString(jwtSign.Bytes())
if err != nil {
return "", err
}
var (
tokenStringMd5 = gmd5.MustEncryptString(tokenString)
// 绑定登录token
key = consts.CacheJwtToken + tokenStringMd5
// 将有效期转为持续时间,单位:秒
expires, _ = time.ParseDuration(fmt.Sprintf("+%vs", user.Expires))
)
err = cache.Instance().Set(ctx, key, tokenString, expires)
if err != nil {
return "", err
}
err = cache.Instance().Set(ctx, consts.CacheJwtUserBind+user.App+":"+gconv.String(user.Id), key, expires)
if err != nil {
return "", err
}
return tokenString, err
}
// ParseToken 解析token
func ParseToken(tokenString string, secret []byte) (j.MapClaims, error) {
if tokenString == "" {
err := gerror.New("token 为空")
return nil, err
}
token, err := j.Parse(tokenString, func(token *j.Token) (interface{}, error) {
if _, ok := token.Method.(*j.SigningMethodHMAC); !ok {
return nil, gerror.Newf("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.(j.MapClaims); ok && token.Valid {
return claims, nil
} else {
return nil, err
}
}
// GetAuthorization 获取authorization
func GetAuthorization(r *ghttp.Request) string {
// 默认从请求头获取
var authorization = r.Header.Get("Authorization")
// 如果请求头不存在则从get参数获取
if authorization == "" {
return r.Get("authorization").String()
}
return gstr.Replace(authorization, "Bearer ", "")
}
func GenAuthKey(token string) string {
return gmd5.MustEncryptString(token)
}

View File

@@ -8,8 +8,8 @@ package location
import (
"context"
"fmt"
"github.com/axgle/mahonia"
"github.com/gogf/gf/v2/container/gmap"
"github.com/gogf/gf/v2/encoding/gcharset"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/text/gstr"
@@ -67,19 +67,18 @@ func WhoisLocation(ctx context.Context, ip string) (*IpLocationData, error) {
defer response.Close()
var (
whoisData *WhoisRegionData
enc = mahonia.NewDecoder("gbk")
data = enc.ConvertString(response.ReadAllString())
)
str, err := gcharset.ToUTF8("GBK", response.ReadAllString())
if err != nil {
return nil, err
}
if err = gconv.Struct(data, &whoisData); err != nil {
var whoisData *WhoisRegionData
if err = gconv.Struct([]byte(str), &whoisData); err != nil {
return nil, err
}
return &IpLocationData{
Ip: whoisData.Ip,
//Country string `json:"country"`
Region: whoisData.Addr,
Province: whoisData.Pro,
ProvinceCode: gconv.Int64(whoisData.ProCode),

View File

@@ -0,0 +1,299 @@
package token
import (
"context"
"fmt"
"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/os/gtime"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"github.com/golang-jwt/jwt/v5"
"hotgo/internal/consts"
"hotgo/internal/library/cache"
"hotgo/internal/library/contexts"
"hotgo/internal/model"
"hotgo/utility/simple"
"time"
)
type Claims struct {
*model.Identity
jwt.RegisteredClaims
}
type Token struct {
ExpireAt int64 `json:"exp"` // token过期时间
RefreshAt int64 `json:"ra"` // 刷新时间
RefreshCount int64 `json:"rc"` // 刷新次数
}
var (
config *model.TokenConfig
errorLogin = gerror.New("登录身份已失效,请重新登录!")
errorMultiLogin = gerror.New("账号存在异地登录,如非本人操作请及时修改登录密码!")
)
func SetConfig(c *model.TokenConfig) {
config = c
}
func GetConfig() *model.TokenConfig {
return config
}
// Login 登录
func Login(ctx context.Context, user *model.Identity) (string, int64, error) {
claims := Claims{
user,
jwt.RegisteredClaims{},
}
header, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(config.SecretKey))
if err != nil {
return "", 0, err
}
var (
now = gtime.Now()
// 认证key
authKey = GetAuthKey(header)
// 登录token
tokenKey = GetTokenKey(user.App, authKey)
// 身份绑定
bindKey = GetBindKey(user.App, user.Id)
// 有效时长
duration = time.Second * gconv.Duration(config.Expires)
)
token := &Token{
ExpireAt: now.Unix() + config.Expires,
RefreshAt: now.Unix(),
RefreshCount: 0,
}
if err = cache.Instance().Set(ctx, tokenKey, token, duration); err != nil {
return "", 0, err
}
if err = cache.Instance().Set(ctx, bindKey, tokenKey, duration); err != nil {
return "", 0, err
}
return header, config.Expires, nil
}
// Logout 注销登录
func Logout(r *ghttp.Request) (err error) {
var (
ctx = r.Context()
header = GetAuthorization(r)
)
if header == "" {
err = errorLogin
return
}
claims, err := parseToken(ctx, header)
if err != nil {
return
}
var (
// 认证key
authKey = GetAuthKey(header)
// 登录token
tokenKey = GetTokenKey(contexts.GetModule(ctx), authKey)
// 身份绑定
bindKey = GetBindKey(contexts.GetModule(ctx), claims.Id)
)
// 删除token
if _, err = cache.Instance().Remove(ctx, tokenKey); err != nil {
return
}
if !config.MultiLogin {
if _, err = cache.Instance().Remove(ctx, bindKey); err != nil {
return
}
}
return
}
// ParseLoginUser 解析登录用户信息
func ParseLoginUser(r *ghttp.Request) (user *model.Identity, err error) {
var (
ctx = r.Context()
header = GetAuthorization(r)
)
if header == "" {
err = errorLogin
return
}
claims, err := parseToken(ctx, header)
if err != nil {
return
}
var (
authKey = GetAuthKey(header)
// 登录token
tokenKey = GetTokenKey(claims.App, authKey)
// 身份绑定
bindKey = GetBindKey(claims.App, claims.Id)
)
// 检查token是否存在
tk, err := cache.Instance().Get(ctx, tokenKey)
if err != nil {
g.Log().Debugf(ctx, "get tokenKey err:%+v", err)
err = errorLogin
return
}
if tk.IsEmpty() {
g.Log().Debug(ctx, "token isEmpty")
err = errorLogin
return
}
var token *Token
if err = tk.Scan(&token); err != nil {
g.Log().Debugf(ctx, "token scan err:%+v", err)
err = errorLogin
return
}
if token == nil {
g.Log().Debugf(ctx, "token = nil")
err = errorLogin
return
}
now := gtime.Now()
if token.ExpireAt < now.Unix() {
g.Log().Debugf(ctx, "token expired.")
err = errorLogin
return
}
// 是否允许多端登录
if !config.MultiLogin {
origin, err := cache.Instance().Get(ctx, bindKey)
if err != nil {
g.Log().Debugf(ctx, "bindKey get err:%+v", err)
err = errorLogin
return nil, err
}
if origin == nil || origin.IsEmpty() {
g.Log().Debug(ctx, "bindKey isEmpty")
err = errorLogin
return nil, err
}
if tokenKey != origin.String() {
g.Log().Debugf(ctx, "bindKey offsite login tokenKey:%v, origin:%v", tokenKey, origin.String())
err = errorMultiLogin
return nil, err
}
}
// 自动刷新token有效期
refreshToken := func() {
// 未开启自动刷新
if !config.AutoRefresh {
return
}
// 刷新次数已达上限
if config.MaxRefreshTimes != -1 && token.RefreshCount >= config.MaxRefreshTimes {
return
}
// 未达到刷新间隔
if gtime.New(token.RefreshAt).Unix()+config.RefreshInterval > now.Unix() {
return
}
// 刷新有效期
token.ExpireAt = now.Unix() + config.Expires
token.RefreshAt = now.Unix()
token.RefreshCount += 1
duration := time.Second * gconv.Duration(config.Expires)
if err = cache.Instance().Set(ctx, tokenKey, token, duration); err != nil {
return
}
if err = cache.Instance().Set(ctx, bindKey, tokenKey, duration); err != nil {
return
}
}
simple.SafeGo(ctx, func(ctx context.Context) {
refreshToken()
})
user = new(model.Identity)
user = claims.Identity
return
}
// parseToken 解析jwt令牌
func parseToken(ctx context.Context, header string) (*Claims, error) {
token, err := jwt.ParseWithClaims(header, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(config.SecretKey), nil
})
if err != nil {
g.Log().Debugf(ctx, "parseToken err:%+v", err)
return nil, err
}
if !token.Valid {
return nil, errorLogin
}
claims, ok := token.Claims.(*Claims)
if !ok {
return nil, errorLogin
}
return claims, nil
}
// GetAuthorization 获取authorization
func GetAuthorization(r *ghttp.Request) string {
// 默认从请求头获取
var authorization = r.Header.Get("Authorization")
// 如果请求头不存在则从get参数获取
if authorization == "" {
return r.Get("authorization").String()
}
return gstr.Replace(authorization, "Bearer ", "")
}
// GetAuthKey 认证key
func GetAuthKey(token string) string {
return gmd5.MustEncryptString(token)
}
// GetTokenKey 令牌缓存key
func GetTokenKey(appName, authKey string) string {
return fmt.Sprintf("%v:%v:%v", consts.CacheToken, appName, authKey)
}
// GetBindKey 令牌身份绑定key
func GetBindKey(appName string, userId int64) string {
return fmt.Sprintf("%v:%v:%v", consts.CacheTokenBind, appName, userId)
}

View File

@@ -21,7 +21,7 @@ import (
"hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm/handler"
"hotgo/internal/library/hgorm/hook"
"hotgo/internal/library/jwt"
"hotgo/internal/library/token"
"hotgo/internal/model"
"hotgo/internal/model/do"
"hotgo/internal/model/entity"
@@ -665,7 +665,6 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
var (
ro *entity.AdminRole
mb *entity.AdminMember
expires = g.Cfg().MustGet(ctx, "jwt.expires", 1).Int64()
)
if err = dao.AdminMember.Ctx(ctx).Where("username", in.Username).Scan(&mb); err != nil {
@@ -707,7 +706,7 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
return
}
identity := &model.Identity{
user := &model.Identity{
Id: mb.Id,
Pid: mb.Pid,
DeptId: mb.DeptId,
@@ -718,20 +717,17 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
Avatar: mb.Avatar,
Email: mb.Email,
Mobile: mb.Mobile,
Exp: gtime.Timestamp() + expires,
Expires: expires,
App: consts.AppAdmin,
LoginAt: gtime.Now(),
}
token, err := jwt.GenerateLoginToken(ctx, identity, false)
loginToken, expires, err := token.Login(ctx, user)
if err != nil {
err = gerror.New(err.Error())
return
return nil, err
}
update := do.AdminMember{
AuthKey: jwt.GenAuthKey(token),
LastActiveAt: gtime.Now(),
LastActiveAt: user.LoginAt,
}
// 更新登录信息
@@ -740,8 +736,8 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
}
res = &adminin.MemberLoginModel{
Id: identity.Id,
Token: token,
Id: user.Id,
Token: loginToken,
Expires: expires,
}

View File

@@ -21,7 +21,6 @@ import (
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/form"
"hotgo/internal/service"
"hotgo/utility/auth"
"hotgo/utility/convert"
"hotgo/utility/tree"
"sort"
@@ -39,10 +38,6 @@ func init() {
// Verify 验证权限
func (s *sAdminRole) Verify(ctx context.Context, path, method string) bool {
if auth.IsExceptAuth(ctx, path) {
return true
}
var (
user = contexts.Get(ctx).User
superRoleKey = g.Cfg().MustGet(ctx, "hotgo.admin.superRoleKey")
@@ -57,6 +52,7 @@ func (s *sAdminRole) Verify(ctx context.Context, path, method string) bool {
if service.AdminMember().VerifySuperId(ctx, user.Id) || user.RoleKey == superRoleKey.String() {
return true
}
ok, err := casbin.Enforcer.Enforce(user.RoleKey, path, method)
if err != nil {
g.Log().Infof(ctx, "admin Verify Enforce err:%+v", err)

View File

@@ -19,8 +19,8 @@ import (
"hotgo/internal/consts"
"hotgo/internal/library/cache"
"hotgo/internal/library/contexts"
"hotgo/internal/library/jwt"
"hotgo/internal/library/response"
"hotgo/internal/library/token"
"hotgo/internal/library/wechat"
"hotgo/internal/model/input/commonin"
"hotgo/internal/service"
@@ -65,7 +65,7 @@ func (s *sCommonWechat) Authorize(ctx context.Context, in commonin.WechatAuthori
path = gmeta.Get(common.WechatAuthorizeCallReq{}, "path").String()
redirectUri = basic.Domain + prefix + path
memberId = contexts.GetUserId(ctx)
state = s.GetCacheKey(in.Type, jwt.GenAuthKey(jwt.GetAuthorization(request)))
state = s.GetCacheKey(in.Type, token.GetAuthKey(token.GetAuthorization(request)))
scope string
)
@@ -109,14 +109,14 @@ func (s *sCommonWechat) AuthorizeCall(ctx context.Context, in commonin.WechatAut
defer delete(s.temp, in.State)
token, err := wechat.GetUserAccessToken(ctx, in.Code)
tk, err := wechat.GetUserAccessToken(ctx, in.Code)
if err != nil {
return
}
switch data.Type {
case consts.WechatAuthorizeOpenId: // 设置openid
cache.Instance().Set(ctx, data.State, token.OpenID, time.Hour*24*7)
cache.Instance().Set(ctx, data.State, tk.OpenID, time.Hour*24*7)
case consts.WechatAuthorizeBindLogin: // 绑定微信登录
// ...
default:
@@ -131,7 +131,7 @@ func (s *sCommonWechat) AuthorizeCall(ctx context.Context, in commonin.WechatAut
// GetOpenId 从缓存中获取临时openid
func (s *sCommonWechat) GetOpenId(ctx context.Context) (openId string, err error) {
request := ghttp.RequestFromCtx(ctx)
key := s.GetCacheKey(consts.WechatAuthorizeOpenId, jwt.GenAuthKey(jwt.GetAuthorization(request)))
key := s.GetCacheKey(consts.WechatAuthorizeOpenId, token.GetAuthKey(token.GetAuthorization(request)))
date, err := cache.Instance().Get(ctx, key)
if err != nil {
err = gerror.Newf("GetOpenId err:%+v", err.Error())

View File

@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package middleware
import (
@@ -15,27 +14,35 @@ import (
"hotgo/internal/library/contexts"
"hotgo/internal/library/response"
"hotgo/internal/service"
"hotgo/utility/auth"
)
// AdminAuth 后台鉴权中间件
func (s *sMiddleware) AdminAuth(r *ghttp.Request) {
var ctx = r.Context()
// 替换掉模块前缀
routerPrefix := g.Cfg().MustGet(ctx, "router.admin.prefix", "/admin")
path := gstr.Replace(r.URL.Path, routerPrefix.String(), "", 1)
var (
ctx = r.Context()
prefix = g.Cfg().MustGet(ctx, "router.admin.prefix", "/admin").String()
path = gstr.Replace(r.URL.Path, prefix, "", 1)
)
/// 不需要验证登录的路由地址
if auth.IsExceptLogin(ctx, path) {
// 不需要验证登录的路由地址
if isExceptLogin(ctx, consts.AppAdmin, path) {
r.Middleware.Next()
return
}
if err := inspectAuth(r, consts.AppAdmin); err != nil {
// 将用户信息传递到上下文中
if err := deliverUserContext(r); err != nil {
g.Log().Warningf(ctx, "deliverUserContext err:%+v", err)
response.JsonExit(r, gcode.CodeNotAuthorized.Code(), err.Error())
return
}
// 不需要验证权限的路由地址
if isExceptAuth(ctx, consts.AppAdmin, path) {
r.Middleware.Next()
return
}
// 验证路由访问权限
if !service.AdminRole().Verify(ctx, path, r.Method) {
g.Log().Debugf(ctx, "AdminAuth fail path:%+v, GetRoleKey:%+v, r.Method:%+v", path, contexts.GetRoleKey(ctx), r.Method)

View File

@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package middleware
import (
@@ -13,34 +12,30 @@ import (
"github.com/gogf/gf/v2/text/gstr"
"hotgo/internal/consts"
"hotgo/internal/library/response"
"hotgo/utility/auth"
)
// ApiAuth API鉴权中间件
func (s *sMiddleware) ApiAuth(r *ghttp.Request) {
var ctx = r.Context()
var (
ctx = r.Context()
prefix = g.Cfg().MustGet(ctx, "router.api.prefix", "/api").String()
path = gstr.Replace(r.URL.Path, prefix, "", 1)
)
// 替换掉模块前缀
routerPrefix := g.Cfg().MustGet(ctx, "router.api.prefix", "/api")
path := gstr.Replace(r.URL.Path, routerPrefix.String(), "", 1)
/// 不需要验证登录的路由地址
if auth.IsExceptLogin(ctx, path) {
// 不需要验证登录的路由地址
if isExceptLogin(ctx, consts.AppApi, path) {
r.Middleware.Next()
return
}
if err := inspectAuth(r, consts.AppAdmin); err != nil {
// 将用户信息传递到上下文中
if err := deliverUserContext(r); err != nil {
response.JsonExit(r, gcode.CodeNotAuthorized.Code(), err.Error())
return
}
//// 验证路由访问权限
//verify := service.AdminRole().Verify(ctx, path, r.Method)
//if !verify {
// response.JsonExit(r, consts.CodeSecurityReason, "你没有访问权限!")
// return
//}
// 验证路由访问权限
// ...
r.Middleware.Next()
}

View File

@@ -6,22 +6,21 @@
package middleware
import (
"github.com/gogf/gf/v2/crypto/gmd5"
"context"
"fmt"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/errors/gcode"
"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"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
"hotgo/internal/library/cache"
"hotgo/internal/library/contexts"
"hotgo/internal/library/jwt"
"hotgo/internal/library/response"
"hotgo/internal/library/token"
"hotgo/internal/model"
"hotgo/internal/service"
"hotgo/utility/validate"
"net/http"
"strings"
)
@@ -33,10 +32,10 @@ type sMiddleware struct {
}
func init() {
service.RegisterMiddleware(New())
service.RegisterMiddleware(NewMiddleware())
}
func New() *sMiddleware {
func NewMiddleware() *sMiddleware {
return &sMiddleware{
LoginUrl: "/common",
DemoWhiteList: g.Map{
@@ -124,85 +123,38 @@ func (s *sMiddleware) Addon(r *ghttp.Request) {
r.Middleware.Next()
}
// inspectAuth 检查并完成身份认证
func inspectAuth(r *ghttp.Request, appName string) (err error) {
var (
ctx = r.Context()
user = new(model.Identity)
authorization = jwt.GetAuthorization(r)
customCtx = &model.Context{}
)
if authorization == "" {
err = gerror.New("请先登录!")
// deliverUserContext 将用户信息传递到上下文中
func deliverUserContext(r *ghttp.Request) (err error) {
user, err := token.ParseLoginUser(r)
if err != nil {
return
}
contexts.SetUser(r.Context(), user)
return
}
// 获取jwtToken
jwtToken := consts.CacheJwtToken + gmd5.MustEncryptString(authorization)
jwtSign := g.Cfg().MustGet(ctx, "jwt.sign", "hotgo")
// isExceptAuth 是否是不需要验证权限的路由地址
func isExceptAuth(ctx context.Context, appName, path string) bool {
pathList := g.Cfg().MustGet(ctx, fmt.Sprintf("router.%v.exceptAuth", appName)).Strings()
data, parseErr := jwt.ParseToken(authorization, jwtSign.Bytes())
if parseErr != nil {
err = gerror.Newf("token不正确或已过期! err :%+v", parseErr.Error())
return
}
if parseErr = gconv.Struct(data, &user); parseErr != nil {
err = gerror.Newf("登录信息解析异常,请重新登录! err :%+v", parseErr.Error())
return
}
// 判断token跟redis的缓存的token是否一样
isContains, containsErr := cache.Instance().Contains(ctx, jwtToken)
if containsErr != nil {
err = gerror.Newf("token无效 err :%+v", containsErr.Error())
return
}
if !isContains {
err = gerror.Newf("token已过期")
return
}
// 是否开启多端登录
if !g.Cfg().MustGet(ctx, "jwt.multiPort", true).Bool() {
key := consts.CacheJwtUserBind + appName + ":" + gconv.String(user.Id)
originJwtToken, originErr := cache.Instance().Get(ctx, key)
if originErr != nil {
err = gerror.Newf("信息异常,请重新登录! err :%+v", originErr.Error())
return
}
if originJwtToken == nil || originJwtToken.IsEmpty() {
err = gerror.New("token已过期")
return
}
if jwtToken != originJwtToken.String() {
err = gerror.New("账号已在其他地方登录!")
return
for i := 0; i < len(pathList); i++ {
if validate.InSliceExistStr(pathList[i], path) {
return true
}
}
// 保存到上下文
if user != nil {
customCtx.User = &model.Identity{
Id: user.Id,
Pid: user.Pid,
DeptId: user.DeptId,
RoleId: user.RoleId,
RoleKey: user.RoleKey,
Username: user.Username,
RealName: user.RealName,
Avatar: user.Avatar,
Email: user.Email,
Mobile: user.Mobile,
Exp: user.Exp,
Expires: user.Expires,
App: user.App,
return false
}
// isExceptLogin 是否是不需要登录的路由地址
func isExceptLogin(ctx context.Context, appName, path string) bool {
pathList := g.Cfg().MustGet(ctx, fmt.Sprintf("router.%v.exceptLogin", appName)).Strings()
for i := 0; i < len(pathList); i++ {
if validate.InSliceExistStr(pathList[i], path) {
return true
}
}
contexts.SetUser(ctx, customCtx.User)
return
return false
}

View File

@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package middleware
import (
@@ -13,24 +12,24 @@ import (
"github.com/gogf/gf/v2/text/gstr"
"hotgo/internal/consts"
"hotgo/internal/library/response"
"hotgo/utility/auth"
)
// WebSocketToken 检查ws连接token
func (s *sMiddleware) WebSocketToken(r *ghttp.Request) {
var ctx = r.Context()
// WebSocketAuth websocket鉴权中间件
func (s *sMiddleware) WebSocketAuth(r *ghttp.Request) {
var (
ctx = r.Context()
prefix = g.Cfg().MustGet(ctx, "router.websocket.prefix", "/websocket").String()
path = gstr.Replace(r.URL.Path, prefix, "", 1)
)
// 替换掉模块前缀
routerPrefix := g.Cfg().MustGet(ctx, "router.ws.prefix", "/socket")
path := gstr.Replace(r.URL.Path, routerPrefix.String(), "", 1)
/// 不需要验证登录的路由地址
if auth.IsExceptLogin(ctx, path) {
// 不需要验证登录的路由地址
if isExceptLogin(ctx, consts.AppWebSocket, path) {
r.Middleware.Next()
return
}
if err := inspectAuth(r, consts.AppAdmin); err != nil {
// 将用户信息传递到上下文中
if err := deliverUserContext(r); err != nil {
response.JsonExit(r, gcode.CodeNotAuthorized.Code(), err.Error())
return
}

View File

@@ -17,6 +17,7 @@ import (
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/payment"
"hotgo/internal/library/token"
"hotgo/internal/library/wechat"
"hotgo/internal/model"
"hotgo/internal/model/entity"
@@ -74,6 +75,12 @@ func (s *sSysConfig) InitConfig(ctx context.Context) {
}
payment.SetConfig(pay)
tk, err := s.GetLoadToken(ctx)
if err != nil {
g.Log().Fatalf(ctx, "init token conifg fail%+v", err)
}
token.SetConfig(tk)
}
// GetLoadTCP 获取本地tcp配置
@@ -94,6 +101,12 @@ func (s *sSysConfig) GetLoadGenerate(ctx context.Context) (conf *model.GenerateC
return
}
// GetLoadToken 获取本地token配置
func (s *sSysConfig) GetLoadToken(ctx context.Context) (conf *model.TokenConfig, err error) {
err = g.Cfg().MustGet(ctx, "token").Scan(&conf)
return
}
// GetWechat 获取微信配置
func (s *sSysConfig) GetWechat(ctx context.Context) (conf *model.WechatConfig, err error) {
models, err := s.GetConfigByGroup(ctx, sysin.GetConfigInp{Group: "wechat"})

View File

@@ -261,7 +261,18 @@ type TCPClientConnConfig struct {
SecretKey string `json:"secretKey"`
}
// TCPConfig tcp服务器配置
type TCPConfig struct {
Server *TCPServerConfig `json:"server"`
Client *TCPClientConfig `json:"client"`
}
// TokenConfig 登录令牌配置
type TokenConfig struct {
SecretKey string `json:"secretKey"`
Expires int64 `json:"expires"`
AutoRefresh bool `json:"autoRefresh"`
RefreshInterval int64 `json:"refreshInterval"`
MaxRefreshTimes int64 `json:"maxRefreshTimes"`
MultiLogin bool `json:"multiLogin"`
}

View File

@@ -7,6 +7,7 @@ package model
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Context 请求上下文结构
@@ -30,7 +31,6 @@ type Identity struct {
Avatar string `json:"avatar" description:"头像"`
Email string `json:"email" description:"邮箱"`
Mobile string `json:"mobile" description:"手机号码"`
Exp int64 `json:"exp" description:"登录有效期截止时间戳"`
Expires int64 `json:"expires" description:"登录有效期"`
App string `json:"app" description:"登录应用"`
LoginAt *gtime.Time `json:"loginAt" description:"登录时间"`
}

View File

@@ -20,7 +20,6 @@ type AdminMember struct {
Username interface{} // 帐号
PasswordHash interface{} // 密码
Salt interface{} // 密码盐
AuthKey interface{} // 授权令牌
PasswordResetToken interface{} // 密码重置令牌
Integral interface{} // 积分
Balance interface{} // 余额

View File

@@ -28,7 +28,7 @@ type SysLog struct {
ProvinceId interface{} // 省编码
CityId interface{} // 市编码
ErrorCode interface{} // 报错code
ErrorMsg interface{} // 报错信息
ErrorMsg interface{} // 对外错误提示
ErrorData *gjson.Json // 报错日志
UserAgent interface{} // UA信息
TakeUpTime interface{} // 请求耗时

View File

@@ -18,7 +18,6 @@ type AdminMember struct {
Username string `json:"username" description:"帐号"`
PasswordHash string `json:"passwordHash" description:"密码"`
Salt string `json:"salt" description:"密码盐"`
AuthKey string `json:"authKey" description:"授权令牌"`
PasswordResetToken string `json:"passwordResetToken" description:"密码重置令牌"`
Integral float64 `json:"integral" description:"积分"`
Balance float64 `json:"balance" description:"余额"`

View File

@@ -26,7 +26,7 @@ type SysLog struct {
ProvinceId int64 `json:"provinceId" description:"省编码"`
CityId int64 `json:"cityId" description:"市编码"`
ErrorCode int `json:"errorCode" description:"报错code"`
ErrorMsg string `json:"errorMsg" description:"报错信息"`
ErrorMsg string `json:"errorMsg" description:"对外错误提示"`
ErrorData *gjson.Json `json:"errorData" description:"报错日志"`
UserAgent string `json:"userAgent" description:"UA信息"`
TakeUpTime int64 `json:"takeUpTime" description:"请求耗时"`

View File

@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package router
import (
@@ -27,7 +26,7 @@ func WebSocket(ctx context.Context, group *ghttp.RouterGroup) {
)
// ws连接中间件
group.Middleware(service.Middleware().WebSocketToken)
group.Middleware(service.Middleware().WebSocketAuth)
// ws
group.GET("/", websocket.WsPage)

View File

@@ -19,6 +19,86 @@ import (
)
type (
IAdminRole interface {
Verify(ctx context.Context, path, method string) bool
List(ctx context.Context, in adminin.RoleListInp) (res *adminin.RoleListModel, totalCount int, err error)
GetName(ctx context.Context, RoleId int64) (name string, err error)
GetMemberList(ctx context.Context, RoleId int64) (list []*adminin.RoleListModel, err error)
GetPermissions(ctx context.Context, reqInfo *role.GetPermissionsReq) (MenuIds []int64, err error)
UpdatePermissions(ctx context.Context, reqInfo *role.UpdatePermissionsReq) (err error)
Edit(ctx context.Context, in *role.EditReq) (err error)
Delete(ctx context.Context, in *role.DeleteReq) (err error)
DataScopeSelect(ctx context.Context) (res form.Selects)
DataScopeEdit(ctx context.Context, in *adminin.DataScopeEditInp) (err error)
}
IAdminNotice interface {
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
Delete(ctx context.Context, in adminin.NoticeDeleteInp) (err error)
Edit(ctx context.Context, in adminin.NoticeEditInp) (err error)
Status(ctx context.Context, in adminin.NoticeStatusInp) (err error)
MaxSort(ctx context.Context, in adminin.NoticeMaxSortInp) (res *adminin.NoticeMaxSortModel, err error)
View(ctx context.Context, in adminin.NoticeViewInp) (res *adminin.NoticeViewModel, err error)
List(ctx context.Context, in adminin.NoticeListInp) (list []*adminin.NoticeListModel, totalCount int, err error)
PullMessages(ctx context.Context, in adminin.PullMessagesInp) (res *adminin.PullMessagesModel, err error)
UnreadCount(ctx context.Context, in adminin.NoticeUnreadCountInp) (res *adminin.NoticeUnreadCountModel, err error)
UpRead(ctx context.Context, in adminin.NoticeUpReadInp) (err error)
ReadAll(ctx context.Context, in adminin.NoticeReadAllInp) (err error)
MessageList(ctx context.Context, in adminin.NoticeMessageListInp) (list []*adminin.NoticeMessageListModel, totalCount int, err error)
}
IAdminCash interface {
View(ctx context.Context, in adminin.CashViewInp) (res *adminin.CashViewModel, err error)
List(ctx context.Context, in adminin.CashListInp) (list []*adminin.CashListModel, totalCount int, err error)
Apply(ctx context.Context, in adminin.CashApplyInp) (err error)
Payment(ctx context.Context, in adminin.CashPaymentInp) (err error)
}
IAdminCreditsLog interface {
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
SaveBalance(ctx context.Context, in adminin.CreditsLogSaveBalanceInp) (res *adminin.CreditsLogSaveBalanceModel, err error)
SaveIntegral(ctx context.Context, in adminin.CreditsLogSaveIntegralInp) (res *adminin.CreditsLogSaveIntegralModel, err error)
List(ctx context.Context, in adminin.CreditsLogListInp) (list []*adminin.CreditsLogListModel, totalCount int, err error)
Export(ctx context.Context, in adminin.CreditsLogListInp) (err error)
}
IAdminDept interface {
NameUnique(ctx context.Context, in adminin.DeptNameUniqueInp) (res *adminin.DeptNameUniqueModel, err error)
Delete(ctx context.Context, in adminin.DeptDeleteInp) (err error)
Edit(ctx context.Context, in adminin.DeptEditInp) (err error)
Status(ctx context.Context, in adminin.DeptStatusInp) (err error)
MaxSort(ctx context.Context, in adminin.DeptMaxSortInp) (res *adminin.DeptMaxSortModel, err error)
View(ctx context.Context, in adminin.DeptViewInp) (res *adminin.DeptViewModel, err error)
Option(ctx context.Context, in adminin.DeptOptionInp) (res *adminin.DeptOptionModel, totalCount int, err error)
List(ctx context.Context, in adminin.DeptListInp) (res *adminin.DeptListModel, err error)
GetName(ctx context.Context, id int64) (name string, err error)
}
IAdminMember interface {
AddBalance(ctx context.Context, in adminin.MemberAddBalanceInp) (err error)
AddIntegral(ctx context.Context, in adminin.MemberAddIntegralInp) (err error)
UpdateCash(ctx context.Context, in adminin.MemberUpdateCashInp) (err error)
UpdateEmail(ctx context.Context, in adminin.MemberUpdateEmailInp) (err error)
UpdateMobile(ctx context.Context, in adminin.MemberUpdateMobileInp) (err error)
UpdateProfile(ctx context.Context, in adminin.MemberUpdateProfileInp) (err error)
UpdatePwd(ctx context.Context, in adminin.MemberUpdatePwdInp) (err error)
ResetPwd(ctx context.Context, in adminin.MemberResetPwdInp) (err error)
EmailUnique(ctx context.Context, in adminin.MemberEmailUniqueInp) (res *adminin.MemberEmailUniqueModel, err error)
MobileUnique(ctx context.Context, in adminin.MemberMobileUniqueInp) (res *adminin.MemberMobileUniqueModel, err error)
NameUnique(ctx context.Context, in adminin.MemberNameUniqueInp) (res *adminin.MemberNameUniqueModel, err error)
VerifySuperId(ctx context.Context, verifyId int64) bool
Delete(ctx context.Context, in adminin.MemberDeleteInp) (err error)
Edit(ctx context.Context, in adminin.MemberEditInp) (err error)
View(ctx context.Context, in adminin.MemberViewInp) (res *adminin.MemberViewModel, err error)
List(ctx context.Context, in adminin.MemberListInp) (list []*adminin.MemberListModel, totalCount int, err error)
LoginMemberInfo(ctx context.Context) (res *adminin.LoginMemberInfoModel, err error)
Login(ctx context.Context, in adminin.MemberLoginInp) (res *adminin.MemberLoginModel, err error)
RoleMemberList(ctx context.Context, in adminin.RoleMemberListInp) (list []*adminin.MemberListModel, totalCount int, err error)
Status(ctx context.Context, in adminin.MemberStatusInp) (err error)
GetIdByCode(ctx context.Context, in adminin.GetIdByCodeInp) (res *adminin.GetIdByCodeModel, err error)
Select(ctx context.Context, in adminin.MemberSelectInp) (res []*adminin.MemberSelectModel, err error)
FilterAuthModel(ctx context.Context, memberId int64) *gdb.Model
MemberLoginStat(ctx context.Context, in adminin.MemberLoginStatInp) (res *adminin.MemberLoginStatModel, err error)
}
IAdminMemberPost interface {
UpdatePostIds(ctx context.Context, memberId int64, postIds []int64) (err error)
GetMemberByIds(ctx context.Context, memberId int64) (postIds []int64, err error)
}
IAdminMenu interface {
MaxSort(ctx context.Context, req *menu.MaxSortReq) (res *menu.MaxSortRes, err error)
NameUnique(ctx context.Context, req *menu.NameUniqueReq) (res *menu.NameUniqueRes, err error)
@@ -47,69 +127,6 @@ type (
View(ctx context.Context, in adminin.OrderViewInp) (res *adminin.OrderViewModel, err error)
Status(ctx context.Context, in adminin.OrderStatusInp) (err error)
}
IAdminRole interface {
Verify(ctx context.Context, path, method string) bool
List(ctx context.Context, in adminin.RoleListInp) (res *adminin.RoleListModel, totalCount int, err error)
GetName(ctx context.Context, RoleId int64) (name string, err error)
GetMemberList(ctx context.Context, RoleId int64) (list []*adminin.RoleListModel, err error)
GetPermissions(ctx context.Context, reqInfo *role.GetPermissionsReq) (MenuIds []int64, err error)
UpdatePermissions(ctx context.Context, reqInfo *role.UpdatePermissionsReq) (err error)
Edit(ctx context.Context, in *role.EditReq) (err error)
Delete(ctx context.Context, in *role.DeleteReq) (err error)
DataScopeSelect(ctx context.Context) (res form.Selects)
DataScopeEdit(ctx context.Context, in *adminin.DataScopeEditInp) (err error)
}
IAdminCreditsLog interface {
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
SaveBalance(ctx context.Context, in adminin.CreditsLogSaveBalanceInp) (res *adminin.CreditsLogSaveBalanceModel, err error)
SaveIntegral(ctx context.Context, in adminin.CreditsLogSaveIntegralInp) (res *adminin.CreditsLogSaveIntegralModel, err error)
List(ctx context.Context, in adminin.CreditsLogListInp) (list []*adminin.CreditsLogListModel, totalCount int, err error)
Export(ctx context.Context, in adminin.CreditsLogListInp) (err error)
}
IAdminMemberPost interface {
UpdatePostIds(ctx context.Context, memberId int64, postIds []int64) (err error)
GetMemberByIds(ctx context.Context, memberId int64) (postIds []int64, err error)
}
IAdminMember interface {
AddBalance(ctx context.Context, in adminin.MemberAddBalanceInp) (err error)
AddIntegral(ctx context.Context, in adminin.MemberAddIntegralInp) (err error)
UpdateCash(ctx context.Context, in adminin.MemberUpdateCashInp) (err error)
UpdateEmail(ctx context.Context, in adminin.MemberUpdateEmailInp) (err error)
UpdateMobile(ctx context.Context, in adminin.MemberUpdateMobileInp) (err error)
UpdateProfile(ctx context.Context, in adminin.MemberUpdateProfileInp) (err error)
UpdatePwd(ctx context.Context, in adminin.MemberUpdatePwdInp) (err error)
ResetPwd(ctx context.Context, in adminin.MemberResetPwdInp) (err error)
EmailUnique(ctx context.Context, in adminin.MemberEmailUniqueInp) (res *adminin.MemberEmailUniqueModel, err error)
MobileUnique(ctx context.Context, in adminin.MemberMobileUniqueInp) (res *adminin.MemberMobileUniqueModel, err error)
NameUnique(ctx context.Context, in adminin.MemberNameUniqueInp) (res *adminin.MemberNameUniqueModel, err error)
VerifySuperId(ctx context.Context, verifyId int64) bool
Delete(ctx context.Context, in adminin.MemberDeleteInp) (err error)
Edit(ctx context.Context, in adminin.MemberEditInp) (err error)
View(ctx context.Context, in adminin.MemberViewInp) (res *adminin.MemberViewModel, err error)
List(ctx context.Context, in adminin.MemberListInp) (list []*adminin.MemberListModel, totalCount int, err error)
LoginMemberInfo(ctx context.Context) (res *adminin.LoginMemberInfoModel, err error)
Login(ctx context.Context, in adminin.MemberLoginInp) (res *adminin.MemberLoginModel, err error)
RoleMemberList(ctx context.Context, in adminin.RoleMemberListInp) (list []*adminin.MemberListModel, totalCount int, err error)
Status(ctx context.Context, in adminin.MemberStatusInp) (err error)
GetIdByCode(ctx context.Context, in adminin.GetIdByCodeInp) (res *adminin.GetIdByCodeModel, err error)
Select(ctx context.Context, in adminin.MemberSelectInp) (res []*adminin.MemberSelectModel, err error)
FilterAuthModel(ctx context.Context, memberId int64) *gdb.Model
MemberLoginStat(ctx context.Context, in adminin.MemberLoginStatInp) (res *adminin.MemberLoginStatModel, err error)
}
IAdminNotice interface {
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
Delete(ctx context.Context, in adminin.NoticeDeleteInp) (err error)
Edit(ctx context.Context, in adminin.NoticeEditInp) (err error)
Status(ctx context.Context, in adminin.NoticeStatusInp) (err error)
MaxSort(ctx context.Context, in adminin.NoticeMaxSortInp) (res *adminin.NoticeMaxSortModel, err error)
View(ctx context.Context, in adminin.NoticeViewInp) (res *adminin.NoticeViewModel, err error)
List(ctx context.Context, in adminin.NoticeListInp) (list []*adminin.NoticeListModel, totalCount int, err error)
PullMessages(ctx context.Context, in adminin.PullMessagesInp) (res *adminin.PullMessagesModel, err error)
UnreadCount(ctx context.Context, in adminin.NoticeUnreadCountInp) (res *adminin.NoticeUnreadCountModel, err error)
UpRead(ctx context.Context, in adminin.NoticeUpReadInp) (err error)
ReadAll(ctx context.Context, in adminin.NoticeReadAllInp) (err error)
MessageList(ctx context.Context, in adminin.NoticeMessageListInp) (list []*adminin.NoticeMessageListModel, totalCount int, err error)
}
IAdminPost interface {
Delete(ctx context.Context, in adminin.PostDeleteInp) (err error)
Edit(ctx context.Context, in adminin.PostEditInp) (err error)
@@ -121,61 +138,22 @@ type (
GetMemberByStartName(ctx context.Context, memberId int64) (name string, err error)
Status(ctx context.Context, in adminin.PostStatusInp) (err error)
}
IAdminCash interface {
View(ctx context.Context, in adminin.CashViewInp) (res *adminin.CashViewModel, err error)
List(ctx context.Context, in adminin.CashListInp) (list []*adminin.CashListModel, totalCount int, err error)
Apply(ctx context.Context, in adminin.CashApplyInp) (err error)
Payment(ctx context.Context, in adminin.CashPaymentInp) (err error)
}
IAdminDept interface {
NameUnique(ctx context.Context, in adminin.DeptNameUniqueInp) (res *adminin.DeptNameUniqueModel, err error)
Delete(ctx context.Context, in adminin.DeptDeleteInp) (err error)
Edit(ctx context.Context, in adminin.DeptEditInp) (err error)
Status(ctx context.Context, in adminin.DeptStatusInp) (err error)
MaxSort(ctx context.Context, in adminin.DeptMaxSortInp) (res *adminin.DeptMaxSortModel, err error)
View(ctx context.Context, in adminin.DeptViewInp) (res *adminin.DeptViewModel, err error)
Option(ctx context.Context, in adminin.DeptOptionInp) (res *adminin.DeptOptionModel, totalCount int, err error)
List(ctx context.Context, in adminin.DeptListInp) (res *adminin.DeptListModel, err error)
GetName(ctx context.Context, id int64) (name string, err error)
}
)
var (
localAdminCash IAdminCash
localAdminCreditsLog IAdminCreditsLog
localAdminDept IAdminDept
localAdminMember IAdminMember
localAdminNotice IAdminNotice
localAdminPost IAdminPost
localAdminRole IAdminRole
localAdminCreditsLog IAdminCreditsLog
localAdminMemberPost IAdminMemberPost
localAdminMenu IAdminMenu
localAdminMonitor IAdminMonitor
localAdminNotice IAdminNotice
localAdminOrder IAdminOrder
localAdminPost IAdminPost
localAdminRole IAdminRole
)
func AdminCreditsLog() IAdminCreditsLog {
if localAdminCreditsLog == nil {
panic("implement not found for interface IAdminCreditsLog, forgot register?")
}
return localAdminCreditsLog
}
func RegisterAdminCreditsLog(i IAdminCreditsLog) {
localAdminCreditsLog = i
}
func AdminMemberPost() IAdminMemberPost {
if localAdminMemberPost == nil {
panic("implement not found for interface IAdminMemberPost, forgot register?")
}
return localAdminMemberPost
}
func RegisterAdminMemberPost(i IAdminMemberPost) {
localAdminMemberPost = i
}
func AdminMenu() IAdminMenu {
if localAdminMenu == nil {
panic("implement not found for interface IAdminMenu, forgot register?")
@@ -198,26 +176,15 @@ func RegisterAdminMonitor(i IAdminMonitor) {
localAdminMonitor = i
}
func AdminOrder() IAdminOrder {
if localAdminOrder == nil {
panic("implement not found for interface IAdminOrder, forgot register?")
func AdminNotice() IAdminNotice {
if localAdminNotice == nil {
panic("implement not found for interface IAdminNotice, forgot register?")
}
return localAdminOrder
return localAdminNotice
}
func RegisterAdminOrder(i IAdminOrder) {
localAdminOrder = i
}
func AdminRole() IAdminRole {
if localAdminRole == nil {
panic("implement not found for interface IAdminRole, forgot register?")
}
return localAdminRole
}
func RegisterAdminRole(i IAdminRole) {
localAdminRole = i
func RegisterAdminNotice(i IAdminNotice) {
localAdminNotice = i
}
func AdminCash() IAdminCash {
@@ -231,6 +198,17 @@ func RegisterAdminCash(i IAdminCash) {
localAdminCash = i
}
func AdminCreditsLog() IAdminCreditsLog {
if localAdminCreditsLog == nil {
panic("implement not found for interface IAdminCreditsLog, forgot register?")
}
return localAdminCreditsLog
}
func RegisterAdminCreditsLog(i IAdminCreditsLog) {
localAdminCreditsLog = i
}
func AdminDept() IAdminDept {
if localAdminDept == nil {
panic("implement not found for interface IAdminDept, forgot register?")
@@ -253,15 +231,26 @@ func RegisterAdminMember(i IAdminMember) {
localAdminMember = i
}
func AdminNotice() IAdminNotice {
if localAdminNotice == nil {
panic("implement not found for interface IAdminNotice, forgot register?")
func AdminMemberPost() IAdminMemberPost {
if localAdminMemberPost == nil {
panic("implement not found for interface IAdminMemberPost, forgot register?")
}
return localAdminNotice
return localAdminMemberPost
}
func RegisterAdminNotice(i IAdminNotice) {
localAdminNotice = i
func RegisterAdminMemberPost(i IAdminMemberPost) {
localAdminMemberPost = i
}
func AdminOrder() IAdminOrder {
if localAdminOrder == nil {
panic("implement not found for interface IAdminOrder, forgot register?")
}
return localAdminOrder
}
func RegisterAdminOrder(i IAdminOrder) {
localAdminOrder = i
}
func AdminPost() IAdminPost {
@@ -274,3 +263,14 @@ func AdminPost() IAdminPost {
func RegisterAdminPost(i IAdminPost) {
localAdminPost = i
}
func AdminRole() IAdminRole {
if localAdminRole == nil {
panic("implement not found for interface IAdminRole, forgot register?")
}
return localAdminRole
}
func RegisterAdminRole(i IAdminRole) {
localAdminRole = i
}

View File

@@ -20,7 +20,7 @@ type (
Blacklist(r *ghttp.Request)
Develop(r *ghttp.Request)
ResponseHandler(r *ghttp.Request)
WebSocketToken(r *ghttp.Request)
WebSocketAuth(r *ghttp.Request)
}
)

View File

@@ -17,6 +17,11 @@ import (
)
type (
ISysAddonsConfig interface {
GetConfigByGroup(ctx context.Context, in sysin.GetAddonsConfigInp) (res *sysin.GetAddonsConfigModel, err error)
ConversionType(ctx context.Context, models *entity.SysAddonsConfig) (value interface{}, err error)
UpdateConfigByGroup(ctx context.Context, in sysin.UpdateAddonsConfigInp) (err error)
}
ISysCron interface {
StartCron(ctx context.Context)
Delete(ctx context.Context, in sysin.CronDeleteInp) (err error)
@@ -27,123 +32,6 @@ type (
List(ctx context.Context, in sysin.CronListInp) (list []*sysin.CronListModel, totalCount int, err error)
OnlineExec(ctx context.Context, in sysin.OnlineExecInp) (err error)
}
ISysBlacklist interface {
Delete(ctx context.Context, in sysin.BlacklistDeleteInp) (err error)
Edit(ctx context.Context, in sysin.BlacklistEditInp) (err error)
Status(ctx context.Context, in sysin.BlacklistStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.BlacklistMaxSortInp) (res *sysin.BlacklistMaxSortModel, err error)
View(ctx context.Context, in sysin.BlacklistViewInp) (res *sysin.BlacklistViewModel, err error)
List(ctx context.Context, in sysin.BlacklistListInp) (list []*sysin.BlacklistListModel, totalCount int, err error)
VariableLoad(ctx context.Context, err error)
Load(ctx context.Context)
}
ISysDictData interface {
Delete(ctx context.Context, in sysin.DictDataDeleteInp) error
Edit(ctx context.Context, in sysin.DictDataEditInp) (err error)
List(ctx context.Context, in sysin.DictDataListInp) (list []*sysin.DictDataListModel, totalCount int, err error)
Select(ctx context.Context, in sysin.DataSelectInp) (list sysin.DataSelectModel, err error)
}
ISysLog interface {
Export(ctx context.Context, in sysin.LogListInp) (err error)
RealWrite(ctx context.Context, log entity.SysLog) (err error)
AutoLog(ctx context.Context) error
AnalysisLog(ctx context.Context) entity.SysLog
View(ctx context.Context, in sysin.LogViewInp) (res *sysin.LogViewModel, err error)
Delete(ctx context.Context, in sysin.LogDeleteInp) (err error)
List(ctx context.Context, in sysin.LogListInp) (list []*sysin.LogListModel, totalCount int, err error)
}
ISysLoginLog interface {
Model(ctx context.Context) *gdb.Model
List(ctx context.Context, in sysin.LoginLogListInp) (list []*sysin.LoginLogListModel, totalCount int, err error)
Export(ctx context.Context, in sysin.LoginLogListInp) (err error)
Delete(ctx context.Context, in sysin.LoginLogDeleteInp) (err error)
View(ctx context.Context, in sysin.LoginLogViewInp) (res *sysin.LoginLogViewModel, err error)
Push(ctx context.Context, in sysin.LoginLogPushInp)
RealWrite(ctx context.Context, models entity.SysLoginLog) (err error)
}
ISysAddons interface {
List(ctx context.Context, in sysin.AddonsListInp) (list []*sysin.AddonsListModel, totalCount int, err error)
Selects(ctx context.Context, in sysin.AddonsSelectsInp) (res *sysin.AddonsSelectsModel, err error)
Build(ctx context.Context, in sysin.AddonsBuildInp) (err error)
Install(ctx context.Context, in sysin.AddonsInstallInp) (err error)
Upgrade(ctx context.Context, in sysin.AddonsUpgradeInp) (err error)
UnInstall(ctx context.Context, in sysin.AddonsUnInstallInp) (err error)
}
ISysConfig interface {
InitConfig(ctx context.Context)
GetLoadTCP(ctx context.Context) (conf *model.TCPConfig, err error)
GetLoadCache(ctx context.Context) (conf *model.CacheConfig, err error)
GetLoadGenerate(ctx context.Context) (conf *model.GenerateConfig, err error)
GetWechat(ctx context.Context) (conf *model.WechatConfig, err error)
GetPay(ctx context.Context) (conf *model.PayConfig, err error)
GetSms(ctx context.Context) (conf *model.SmsConfig, err error)
GetGeo(ctx context.Context) (conf *model.GeoConfig, err error)
GetUpload(ctx context.Context) (conf *model.UploadConfig, err error)
GetSmtp(ctx context.Context) (conf *model.EmailConfig, err error)
GetBasic(ctx context.Context) (conf *model.BasicConfig, err error)
GetLoadSSL(ctx context.Context) (conf *model.SSLConfig, err error)
GetLoadLog(ctx context.Context) (conf *model.LogConfig, err error)
GetLoadServeLog(ctx context.Context) (conf *model.ServeLogConfig, err error)
GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
ConversionType(ctx context.Context, models *entity.SysConfig) (value interface{}, err error)
UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) (err error)
}
ISysEmsLog interface {
Delete(ctx context.Context, in sysin.EmsLogDeleteInp) (err error)
Edit(ctx context.Context, in sysin.EmsLogEditInp) (err error)
Status(ctx context.Context, in sysin.EmsLogStatusInp) (err error)
View(ctx context.Context, in sysin.EmsLogViewInp) (res *sysin.EmsLogViewModel, err error)
List(ctx context.Context, in sysin.EmsLogListInp) (list []*sysin.EmsLogListModel, totalCount int, err error)
Send(ctx context.Context, in sysin.SendEmsInp) (err error)
GetTemplate(ctx context.Context, template string, config *model.EmailConfig) (val string, err error)
AllowSend(ctx context.Context, models *entity.SysEmsLog, config *model.EmailConfig) (err error)
VerifyCode(ctx context.Context, in sysin.VerifyEmsCodeInp) (err error)
}
ISysGenCodes interface {
Delete(ctx context.Context, in sysin.GenCodesDeleteInp) (err error)
Edit(ctx context.Context, in sysin.GenCodesEditInp) (res *sysin.GenCodesEditModel, err error)
Status(ctx context.Context, in sysin.GenCodesStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.GenCodesMaxSortInp) (res *sysin.GenCodesMaxSortModel, err error)
View(ctx context.Context, in sysin.GenCodesViewInp) (res *sysin.GenCodesViewModel, err error)
List(ctx context.Context, in sysin.GenCodesListInp) (list []*sysin.GenCodesListModel, totalCount int, err error)
Selects(ctx context.Context, in sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error)
TableSelect(ctx context.Context, in sysin.GenCodesTableSelectInp) (res []*sysin.GenCodesTableSelectModel, err error)
ColumnSelect(ctx context.Context, in sysin.GenCodesColumnSelectInp) (res []*sysin.GenCodesColumnSelectModel, err error)
ColumnList(ctx context.Context, in sysin.GenCodesColumnListInp) (res []*sysin.GenCodesColumnListModel, err error)
Preview(ctx context.Context, in sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error)
Build(ctx context.Context, in sysin.GenCodesBuildInp) (err error)
}
ISysProvinces interface {
Tree(ctx context.Context) (list []g.Map, err error)
Delete(ctx context.Context, in sysin.ProvincesDeleteInp) (err error)
Edit(ctx context.Context, in sysin.ProvincesEditInp) (err error)
Status(ctx context.Context, in sysin.ProvincesStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.ProvincesMaxSortInp) (res *sysin.ProvincesMaxSortModel, err error)
View(ctx context.Context, in sysin.ProvincesViewInp) (res *sysin.ProvincesViewModel, err error)
List(ctx context.Context, in sysin.ProvincesListInp) (list []*sysin.ProvincesListModel, totalCount int, err error)
ChildrenList(ctx context.Context, in sysin.ProvincesChildrenListInp) (list []*sysin.ProvincesChildrenListModel, totalCount int, err error)
UniqueId(ctx context.Context, in sysin.ProvincesUniqueIdInp) (res *sysin.ProvincesUniqueIdModel, err error)
Select(ctx context.Context, in sysin.ProvincesSelectInp) (res *sysin.ProvincesSelectModel, err error)
}
ISysAttachment interface {
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
Delete(ctx context.Context, in sysin.AttachmentDeleteInp) (err error)
Edit(ctx context.Context, in sysin.AttachmentEditInp) (err error)
Status(ctx context.Context, in sysin.AttachmentStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.AttachmentMaxSortInp) (res *sysin.AttachmentMaxSortModel, err error)
View(ctx context.Context, in sysin.AttachmentViewInp) (res *sysin.AttachmentViewModel, err error)
List(ctx context.Context, in sysin.AttachmentListInp) (list []*sysin.AttachmentListModel, totalCount int, err error)
Add(ctx context.Context, meta *sysin.UploadFileMeta, fullPath, drive string) (models *entity.SysAttachment, err error)
}
ISysCronGroup interface {
Delete(ctx context.Context, in sysin.CronGroupDeleteInp) (err error)
Edit(ctx context.Context, in sysin.CronGroupEditInp) (err error)
Status(ctx context.Context, in sysin.CronGroupStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.CronGroupMaxSortInp) (res *sysin.CronGroupMaxSortModel, err error)
View(ctx context.Context, in sysin.CronGroupViewInp) (res *sysin.CronGroupViewModel, err error)
List(ctx context.Context, in sysin.CronGroupListInp) (list []*sysin.CronGroupListModel, totalCount int, err error)
Select(ctx context.Context, in sysin.CronGroupSelectInp) (res *sysin.CronGroupSelectModel, err error)
}
ISysCurdDemo interface {
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
List(ctx context.Context, in sysin.CurdDemoListInp) (list []*sysin.CurdDemoListModel, totalCount int, err error)
@@ -161,13 +49,40 @@ type (
Edit(ctx context.Context, in sysin.DictTypeEditInp) (err error)
TreeSelect(ctx context.Context, in sysin.DictTreeSelectInp) (list []*sysin.DictTypeTree, err error)
}
ISysServeLog interface {
Model(ctx context.Context) *gdb.Model
List(ctx context.Context, in sysin.ServeLogListInp) (list []*sysin.ServeLogListModel, totalCount int, err error)
Export(ctx context.Context, in sysin.ServeLogListInp) (err error)
Delete(ctx context.Context, in sysin.ServeLogDeleteInp) (err error)
View(ctx context.Context, in sysin.ServeLogViewInp) (res *sysin.ServeLogViewModel, err error)
RealWrite(ctx context.Context, models entity.SysServeLog) (err error)
ISysCronGroup interface {
Delete(ctx context.Context, in sysin.CronGroupDeleteInp) (err error)
Edit(ctx context.Context, in sysin.CronGroupEditInp) (err error)
Status(ctx context.Context, in sysin.CronGroupStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.CronGroupMaxSortInp) (res *sysin.CronGroupMaxSortModel, err error)
View(ctx context.Context, in sysin.CronGroupViewInp) (res *sysin.CronGroupViewModel, err error)
List(ctx context.Context, in sysin.CronGroupListInp) (list []*sysin.CronGroupListModel, totalCount int, err error)
Select(ctx context.Context, in sysin.CronGroupSelectInp) (res *sysin.CronGroupSelectModel, err error)
}
ISysDictData interface {
Delete(ctx context.Context, in sysin.DictDataDeleteInp) error
Edit(ctx context.Context, in sysin.DictDataEditInp) (err error)
List(ctx context.Context, in sysin.DictDataListInp) (list []*sysin.DictDataListModel, totalCount int, err error)
Select(ctx context.Context, in sysin.DataSelectInp) (list sysin.DataSelectModel, err error)
}
ISysEmsLog interface {
Delete(ctx context.Context, in sysin.EmsLogDeleteInp) (err error)
Edit(ctx context.Context, in sysin.EmsLogEditInp) (err error)
Status(ctx context.Context, in sysin.EmsLogStatusInp) (err error)
View(ctx context.Context, in sysin.EmsLogViewInp) (res *sysin.EmsLogViewModel, err error)
List(ctx context.Context, in sysin.EmsLogListInp) (list []*sysin.EmsLogListModel, totalCount int, err error)
Send(ctx context.Context, in sysin.SendEmsInp) (err error)
GetTemplate(ctx context.Context, template string, config *model.EmailConfig) (val string, err error)
AllowSend(ctx context.Context, models *entity.SysEmsLog, config *model.EmailConfig) (err error)
VerifyCode(ctx context.Context, in sysin.VerifyEmsCodeInp) (err error)
}
ISysLog interface {
Export(ctx context.Context, in sysin.LogListInp) (err error)
RealWrite(ctx context.Context, log entity.SysLog) (err error)
AutoLog(ctx context.Context) error
AnalysisLog(ctx context.Context) entity.SysLog
View(ctx context.Context, in sysin.LogViewInp) (res *sysin.LogViewModel, err error)
Delete(ctx context.Context, in sysin.LogDeleteInp) (err error)
List(ctx context.Context, in sysin.LogListInp) (list []*sysin.LogListModel, totalCount int, err error)
}
ISysSmsLog interface {
Delete(ctx context.Context, in sysin.SmsLogDeleteInp) (err error)
@@ -181,88 +96,119 @@ type (
AllowSend(ctx context.Context, models *entity.SysSmsLog, config *model.SmsConfig) (err error)
VerifyCode(ctx context.Context, in sysin.VerifyCodeInp) (err error)
}
ISysAddonsConfig interface {
GetConfigByGroup(ctx context.Context, in sysin.GetAddonsConfigInp) (res *sysin.GetAddonsConfigModel, err error)
ConversionType(ctx context.Context, models *entity.SysAddonsConfig) (value interface{}, err error)
UpdateConfigByGroup(ctx context.Context, in sysin.UpdateAddonsConfigInp) (err error)
ISysAddons interface {
List(ctx context.Context, in sysin.AddonsListInp) (list []*sysin.AddonsListModel, totalCount int, err error)
Selects(ctx context.Context, in sysin.AddonsSelectsInp) (res *sysin.AddonsSelectsModel, err error)
Build(ctx context.Context, in sysin.AddonsBuildInp) (err error)
Install(ctx context.Context, in sysin.AddonsInstallInp) (err error)
Upgrade(ctx context.Context, in sysin.AddonsUpgradeInp) (err error)
UnInstall(ctx context.Context, in sysin.AddonsUnInstallInp) (err error)
}
ISysConfig interface {
InitConfig(ctx context.Context)
GetLoadTCP(ctx context.Context) (conf *model.TCPConfig, err error)
GetLoadCache(ctx context.Context) (conf *model.CacheConfig, err error)
GetLoadGenerate(ctx context.Context) (conf *model.GenerateConfig, err error)
GetLoadToken(ctx context.Context) (conf *model.TokenConfig, err error)
GetWechat(ctx context.Context) (conf *model.WechatConfig, err error)
GetPay(ctx context.Context) (conf *model.PayConfig, err error)
GetSms(ctx context.Context) (conf *model.SmsConfig, err error)
GetGeo(ctx context.Context) (conf *model.GeoConfig, err error)
GetUpload(ctx context.Context) (conf *model.UploadConfig, err error)
GetSmtp(ctx context.Context) (conf *model.EmailConfig, err error)
GetBasic(ctx context.Context) (conf *model.BasicConfig, err error)
GetLoadSSL(ctx context.Context) (conf *model.SSLConfig, err error)
GetLoadLog(ctx context.Context) (conf *model.LogConfig, err error)
GetLoadServeLog(ctx context.Context) (conf *model.ServeLogConfig, err error)
GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
ConversionType(ctx context.Context, models *entity.SysConfig) (value interface{}, err error)
UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) (err error)
}
ISysLoginLog interface {
Model(ctx context.Context) *gdb.Model
List(ctx context.Context, in sysin.LoginLogListInp) (list []*sysin.LoginLogListModel, totalCount int, err error)
Export(ctx context.Context, in sysin.LoginLogListInp) (err error)
Delete(ctx context.Context, in sysin.LoginLogDeleteInp) (err error)
View(ctx context.Context, in sysin.LoginLogViewInp) (res *sysin.LoginLogViewModel, err error)
Push(ctx context.Context, in sysin.LoginLogPushInp)
RealWrite(ctx context.Context, models entity.SysLoginLog) (err error)
}
ISysProvinces interface {
Tree(ctx context.Context) (list []g.Map, err error)
Delete(ctx context.Context, in sysin.ProvincesDeleteInp) (err error)
Edit(ctx context.Context, in sysin.ProvincesEditInp) (err error)
Status(ctx context.Context, in sysin.ProvincesStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.ProvincesMaxSortInp) (res *sysin.ProvincesMaxSortModel, err error)
View(ctx context.Context, in sysin.ProvincesViewInp) (res *sysin.ProvincesViewModel, err error)
List(ctx context.Context, in sysin.ProvincesListInp) (list []*sysin.ProvincesListModel, totalCount int, err error)
ChildrenList(ctx context.Context, in sysin.ProvincesChildrenListInp) (list []*sysin.ProvincesChildrenListModel, totalCount int, err error)
UniqueId(ctx context.Context, in sysin.ProvincesUniqueIdInp) (res *sysin.ProvincesUniqueIdModel, err error)
Select(ctx context.Context, in sysin.ProvincesSelectInp) (res *sysin.ProvincesSelectModel, err error)
}
ISysServeLog interface {
Model(ctx context.Context) *gdb.Model
List(ctx context.Context, in sysin.ServeLogListInp) (list []*sysin.ServeLogListModel, totalCount int, err error)
Export(ctx context.Context, in sysin.ServeLogListInp) (err error)
Delete(ctx context.Context, in sysin.ServeLogDeleteInp) (err error)
View(ctx context.Context, in sysin.ServeLogViewInp) (res *sysin.ServeLogViewModel, err error)
RealWrite(ctx context.Context, models entity.SysServeLog) (err error)
}
ISysAttachment interface {
Model(ctx context.Context, option ...*handler.Option) *gdb.Model
Delete(ctx context.Context, in sysin.AttachmentDeleteInp) (err error)
Edit(ctx context.Context, in sysin.AttachmentEditInp) (err error)
Status(ctx context.Context, in sysin.AttachmentStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.AttachmentMaxSortInp) (res *sysin.AttachmentMaxSortModel, err error)
View(ctx context.Context, in sysin.AttachmentViewInp) (res *sysin.AttachmentViewModel, err error)
List(ctx context.Context, in sysin.AttachmentListInp) (list []*sysin.AttachmentListModel, totalCount int, err error)
Add(ctx context.Context, meta *sysin.UploadFileMeta, fullPath, drive string) (models *entity.SysAttachment, err error)
}
ISysBlacklist interface {
Delete(ctx context.Context, in sysin.BlacklistDeleteInp) (err error)
Edit(ctx context.Context, in sysin.BlacklistEditInp) (err error)
Status(ctx context.Context, in sysin.BlacklistStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.BlacklistMaxSortInp) (res *sysin.BlacklistMaxSortModel, err error)
View(ctx context.Context, in sysin.BlacklistViewInp) (res *sysin.BlacklistViewModel, err error)
List(ctx context.Context, in sysin.BlacklistListInp) (list []*sysin.BlacklistListModel, totalCount int, err error)
VariableLoad(ctx context.Context, err error)
Load(ctx context.Context)
}
ISysGenCodes interface {
Delete(ctx context.Context, in sysin.GenCodesDeleteInp) (err error)
Edit(ctx context.Context, in sysin.GenCodesEditInp) (res *sysin.GenCodesEditModel, err error)
Status(ctx context.Context, in sysin.GenCodesStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.GenCodesMaxSortInp) (res *sysin.GenCodesMaxSortModel, err error)
View(ctx context.Context, in sysin.GenCodesViewInp) (res *sysin.GenCodesViewModel, err error)
List(ctx context.Context, in sysin.GenCodesListInp) (list []*sysin.GenCodesListModel, totalCount int, err error)
Selects(ctx context.Context, in sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error)
TableSelect(ctx context.Context, in sysin.GenCodesTableSelectInp) (res []*sysin.GenCodesTableSelectModel, err error)
ColumnSelect(ctx context.Context, in sysin.GenCodesColumnSelectInp) (res []*sysin.GenCodesColumnSelectModel, err error)
ColumnList(ctx context.Context, in sysin.GenCodesColumnListInp) (res []*sysin.GenCodesColumnListModel, err error)
Preview(ctx context.Context, in sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error)
Build(ctx context.Context, in sysin.GenCodesBuildInp) (err error)
}
)
var (
localSysProvinces ISysProvinces
localSysAttachment ISysAttachment
localSysConfig ISysConfig
localSysEmsLog ISysEmsLog
localSysGenCodes ISysGenCodes
localSysServeLog ISysServeLog
localSysLog ISysLog
localSysSmsLog ISysSmsLog
localSysAddonsConfig ISysAddonsConfig
localSysCronGroup ISysCronGroup
localSysDictData ISysDictData
localSysLoginLog ISysLoginLog
localSysProvinces ISysProvinces
localSysServeLog ISysServeLog
localSysAddons ISysAddons
localSysConfig ISysConfig
localSysGenCodes ISysGenCodes
localSysAttachment ISysAttachment
localSysBlacklist ISysBlacklist
localSysCurdDemo ISysCurdDemo
localSysDictType ISysDictType
localSysAddonsConfig ISysAddonsConfig
localSysCron ISysCron
localSysLoginLog ISysLoginLog
localSysAddons ISysAddons
localSysBlacklist ISysBlacklist
localSysDictData ISysDictData
localSysLog ISysLog
)
func SysAttachment() ISysAttachment {
if localSysAttachment == nil {
panic("implement not found for interface ISysAttachment, forgot register?")
}
return localSysAttachment
}
func RegisterSysAttachment(i ISysAttachment) {
localSysAttachment = i
}
func SysConfig() ISysConfig {
if localSysConfig == nil {
panic("implement not found for interface ISysConfig, forgot register?")
}
return localSysConfig
}
func RegisterSysConfig(i ISysConfig) {
localSysConfig = i
}
func SysEmsLog() ISysEmsLog {
if localSysEmsLog == nil {
panic("implement not found for interface ISysEmsLog, forgot register?")
}
return localSysEmsLog
}
func RegisterSysEmsLog(i ISysEmsLog) {
localSysEmsLog = i
}
func SysGenCodes() ISysGenCodes {
if localSysGenCodes == nil {
panic("implement not found for interface ISysGenCodes, forgot register?")
}
return localSysGenCodes
}
func RegisterSysGenCodes(i ISysGenCodes) {
localSysGenCodes = i
}
func SysProvinces() ISysProvinces {
if localSysProvinces == nil {
panic("implement not found for interface ISysProvinces, forgot register?")
}
return localSysProvinces
}
func RegisterSysProvinces(i ISysProvinces) {
localSysProvinces = i
}
func SysAddonsConfig() ISysAddonsConfig {
if localSysAddonsConfig == nil {
panic("implement not found for interface ISysAddonsConfig, forgot register?")
@@ -274,15 +220,15 @@ func RegisterSysAddonsConfig(i ISysAddonsConfig) {
localSysAddonsConfig = i
}
func SysCronGroup() ISysCronGroup {
if localSysCronGroup == nil {
panic("implement not found for interface ISysCronGroup, forgot register?")
func SysCron() ISysCron {
if localSysCron == nil {
panic("implement not found for interface ISysCron, forgot register?")
}
return localSysCronGroup
return localSysCron
}
func RegisterSysCronGroup(i ISysCronGroup) {
localSysCronGroup = i
func RegisterSysCron(i ISysCron) {
localSysCron = i
}
func SysCurdDemo() ISysCurdDemo {
@@ -307,59 +253,15 @@ func RegisterSysDictType(i ISysDictType) {
localSysDictType = i
}
func SysServeLog() ISysServeLog {
if localSysServeLog == nil {
panic("implement not found for interface ISysServeLog, forgot register?")
func SysCronGroup() ISysCronGroup {
if localSysCronGroup == nil {
panic("implement not found for interface ISysCronGroup, forgot register?")
}
return localSysServeLog
return localSysCronGroup
}
func RegisterSysServeLog(i ISysServeLog) {
localSysServeLog = i
}
func SysSmsLog() ISysSmsLog {
if localSysSmsLog == nil {
panic("implement not found for interface ISysSmsLog, forgot register?")
}
return localSysSmsLog
}
func RegisterSysSmsLog(i ISysSmsLog) {
localSysSmsLog = i
}
func SysCron() ISysCron {
if localSysCron == nil {
panic("implement not found for interface ISysCron, forgot register?")
}
return localSysCron
}
func RegisterSysCron(i ISysCron) {
localSysCron = i
}
func SysAddons() ISysAddons {
if localSysAddons == nil {
panic("implement not found for interface ISysAddons, forgot register?")
}
return localSysAddons
}
func RegisterSysAddons(i ISysAddons) {
localSysAddons = i
}
func SysBlacklist() ISysBlacklist {
if localSysBlacklist == nil {
panic("implement not found for interface ISysBlacklist, forgot register?")
}
return localSysBlacklist
}
func RegisterSysBlacklist(i ISysBlacklist) {
localSysBlacklist = i
func RegisterSysCronGroup(i ISysCronGroup) {
localSysCronGroup = i
}
func SysDictData() ISysDictData {
@@ -373,6 +275,17 @@ func RegisterSysDictData(i ISysDictData) {
localSysDictData = i
}
func SysEmsLog() ISysEmsLog {
if localSysEmsLog == nil {
panic("implement not found for interface ISysEmsLog, forgot register?")
}
return localSysEmsLog
}
func RegisterSysEmsLog(i ISysEmsLog) {
localSysEmsLog = i
}
func SysLog() ISysLog {
if localSysLog == nil {
panic("implement not found for interface ISysLog, forgot register?")
@@ -384,6 +297,39 @@ func RegisterSysLog(i ISysLog) {
localSysLog = i
}
func SysSmsLog() ISysSmsLog {
if localSysSmsLog == nil {
panic("implement not found for interface ISysSmsLog, forgot register?")
}
return localSysSmsLog
}
func RegisterSysSmsLog(i ISysSmsLog) {
localSysSmsLog = i
}
func SysAddons() ISysAddons {
if localSysAddons == nil {
panic("implement not found for interface ISysAddons, forgot register?")
}
return localSysAddons
}
func RegisterSysAddons(i ISysAddons) {
localSysAddons = i
}
func SysConfig() ISysConfig {
if localSysConfig == nil {
panic("implement not found for interface ISysConfig, forgot register?")
}
return localSysConfig
}
func RegisterSysConfig(i ISysConfig) {
localSysConfig = i
}
func SysLoginLog() ISysLoginLog {
if localSysLoginLog == nil {
panic("implement not found for interface ISysLoginLog, forgot register?")
@@ -394,3 +340,58 @@ func SysLoginLog() ISysLoginLog {
func RegisterSysLoginLog(i ISysLoginLog) {
localSysLoginLog = i
}
func SysProvinces() ISysProvinces {
if localSysProvinces == nil {
panic("implement not found for interface ISysProvinces, forgot register?")
}
return localSysProvinces
}
func RegisterSysProvinces(i ISysProvinces) {
localSysProvinces = i
}
func SysServeLog() ISysServeLog {
if localSysServeLog == nil {
panic("implement not found for interface ISysServeLog, forgot register?")
}
return localSysServeLog
}
func RegisterSysServeLog(i ISysServeLog) {
localSysServeLog = i
}
func SysAttachment() ISysAttachment {
if localSysAttachment == nil {
panic("implement not found for interface ISysAttachment, forgot register?")
}
return localSysAttachment
}
func RegisterSysAttachment(i ISysAttachment) {
localSysAttachment = i
}
func SysBlacklist() ISysBlacklist {
if localSysBlacklist == nil {
panic("implement not found for interface ISysBlacklist, forgot register?")
}
return localSysBlacklist
}
func RegisterSysBlacklist(i ISysBlacklist) {
localSysBlacklist = i
}
func SysGenCodes() ISysGenCodes {
if localSysGenCodes == nil {
panic("implement not found for interface ISysGenCodes, forgot register?")
}
return localSysGenCodes
}
func RegisterSysGenCodes(i ISysGenCodes) {
localSysGenCodes = i
}

View File

@@ -153,12 +153,14 @@ cache:
fileDir: "./storage/cache" # 文件缓存路径adapter=file时必填
#JWT
jwt:
version: "1.0" # 版本号
expires: "864000" # 有效期单位
sign: "hotgo" # 秘钥考虑安全问题请修改默认值
multiPort: true # 是否允许多端登录默认为true
# 登录令牌
token:
secretKey: "hotgo123" # 令牌加密秘钥考虑安全问题生产环境中请修改默认值
expires: 604800 # 令牌有效期单位默认7天
autoRefresh: true # 是否开启自动刷新过期时间 false|true 默认为true
refreshInterval: 86400 # 刷新间隔单位必须小于expires否则无法触发默认1天内只允许刷新一次
maxRefreshTimes: 30 # 最大允许刷新次数-1不限制默认30次
multiLogin: true # 是否允许多端登录 false|true 默认为true
#消息队列

View File

@@ -25,7 +25,7 @@ func WebSocket(ctx context.Context, group *ghttp.RouterGroup) {
websocket.Index,
)
// ws连接中间件
group.Middleware(service.Middleware().WebSocketToken)
group.Middleware(service.Middleware().WebSocketAuth)
group.Bind(
// 需要验证的路由
// ..

View File

@@ -3,7 +3,7 @@
-- https://www.phpmyadmin.net/
--
-- 主机 localhost:3306
-- 生成日期 2023-05-11 15:56:13
-- 生成日期 2023-05-12 15:45:52
-- 服务器版本 5.7.38-log
-- PHP 版本 5.6.40
@@ -171,7 +171,6 @@ CREATE TABLE `hg_admin_member` (
`username` varchar(20) NOT NULL DEFAULT '' COMMENT '帐号',
`password_hash` char(32) NOT NULL DEFAULT '' COMMENT '密码',
`salt` char(16) NOT NULL COMMENT '密码盐',
`auth_key` char(32) NOT NULL DEFAULT '' COMMENT '授权令牌',
`password_reset_token` varchar(150) DEFAULT '' COMMENT '密码重置令牌',
`integral` decimal(10,2) UNSIGNED DEFAULT '0.00' COMMENT '积分',
`balance` decimal(10,2) UNSIGNED DEFAULT '0.00' COMMENT '余额',
@@ -198,10 +197,10 @@ CREATE TABLE `hg_admin_member` (
-- 转存表中的数据 `hg_admin_member`
--
INSERT INTO `hg_admin_member` (`id`, `dept_id`, `role_id`, `real_name`, `username`, `password_hash`, `salt`, `auth_key`, `password_reset_token`, `integral`, `balance`, `avatar`, `sex`, `qq`, `email`, `mobile`, `birthday`, `city_id`, `address`, `pid`, `level`, `tree`, `cash`, `last_active_at`, `remark`, `status`, `created_at`, `updated_at`) VALUES
(1, 100, 1, '孟帅', 'admin', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '72c79855b0e94d4503e80a9fe064c645', '', '89.00', '99391.78', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '133814250', '133814250@qq.com', '15303830571', '2016-04-16', 410172, '莲花街001号', 0, 1, '', '{\"name\": \"孟帅\", \"account\": \"15303830571\", \"payeeCode\": \"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8mqal5isvcb58g.jpg\"}', '2023-05-11 15:52:51', NULL, 1, '2021-02-12 17:59:45', '2023-05-11 15:52:51'),
(3, 100, 2, '测试账号', 'test', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '33db4202dd10e2c670bfdfb16cd2ecd5', '', '0.00', '4.00', 'http://alioss.qvnidaye.com//images/2021/03/12/image_1615529198_vMK4kwq2.jpg', 1, '', 'c@qq.cc', '15303888888', '2016-04-13', 371100, '大潮街道666号', 1, 2, 'tr_1 ', NULL, '2023-04-29 10:20:16', '', 1, '2022-02-11 17:59:45', '2023-04-29 10:20:16'),
(8, 101, 200, 'ameng', 'ameng', '382df3b083a27886edb94e669a857c33', 'hfuUEb', 'a3197f39fae36471b2be8f2e86d8a91e', '', '11.00', '3.22', '', 1, '', '', '', NULL, 0, '', 1, 2, 'tr_1 ', NULL, '2023-04-30 20:04:06', '', 1, '2023-02-03 17:34:31', '2023-04-30 20:04:06');
INSERT INTO `hg_admin_member` (`id`, `dept_id`, `role_id`, `real_name`, `username`, `password_hash`, `salt`, `password_reset_token`, `integral`, `balance`, `avatar`, `sex`, `qq`, `email`, `mobile`, `birthday`, `city_id`, `address`, `pid`, `level`, `tree`, `cash`, `last_active_at`, `remark`, `status`, `created_at`, `updated_at`) VALUES
(1, 100, 1, '孟帅', 'admin', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', '89.00', '99391.78', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8er9nfkchdopav.png', 1, '133814250', '133814250@qq.com', '15303830571', '2016-04-16', 410172, '莲花街001号', 0, 1, '', '{\"name\": \"孟帅\", \"account\": \"15303830571\", \"payeeCode\": \"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq8mqal5isvcb58g.jpg\"}', '2023-05-12 15:44:12', NULL, 1, '2021-02-12 17:59:45', '2023-05-12 15:44:12'),
(3, 100, 2, '测试账号', 'test', 'a7c588fffeb2c1d99b29879d7fe97c78', '6541561', '', '0.00', '4.00', 'http://alioss.qvnidaye.com//images/2021/03/12/image_1615529198_vMK4kwq2.jpg', 1, '', 'c@qq.cc', '15303888888', '2016-04-13', 371100, '大潮街道666号', 1, 2, 'tr_1 ', NULL, '2023-04-29 10:20:16', '', 1, '2022-02-11 17:59:45', '2023-04-29 10:20:16'),
(8, 101, 200, 'ameng', 'ameng', '382df3b083a27886edb94e669a857c33', 'hfuUEb', '', '11.00', '3.22', '', 1, '', '', '', NULL, 0, '', 1, 2, 'tr_1 ', NULL, '2023-04-30 20:04:06', '', 1, '2023-02-03 17:34:31', '2023-04-30 20:04:06');
-- --------------------------------------------------------

View File

@@ -1,45 +0,0 @@
// Package auth
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package auth
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"hotgo/utility/validate"
)
// IsExceptAuth 是否是不需要验证权限的路由地址
func IsExceptAuth(ctx context.Context, path string) bool {
var pathList []string
except := g.Cfg().MustGet(ctx, "router.admin.exceptAuth")
pathList = except.Strings()
for i := 0; i < len(pathList); i++ {
if validate.InSliceExistStr(pathList[i], path) {
return true
}
}
return false
}
// IsExceptLogin 是否是不需要登录的路由地址
func IsExceptLogin(ctx context.Context, path string) bool {
var pathList []string
except := g.Cfg().MustGet(ctx, "router.admin.exceptLogin")
pathList = except.Strings()
for i := 0; i < len(pathList); i++ {
if validate.InSliceExistStr(pathList[i], path) {
return true
}
}
return false
}

View File

@@ -3,13 +3,13 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package format
import (
"fmt"
"github.com/shopspring/decimal"
"github.com/gogf/gf/v2/util/gconv"
"math"
"strconv"
)
// RoundInt64 四舍五入
@@ -19,22 +19,19 @@ func RoundInt64(x float64) int64 {
// Round2String 四舍五入保留小数默认2位
func Round2String(value float64, args ...interface{}) (v string) {
var places int32 = 2
var places = 2
if len(args) > 0 {
places = args[0].(int32)
places = gconv.Int(args[0])
}
return decimal.NewFromFloat(value).Round(places).String()
cDig := strconv.Itoa(places)
val := fmt.Sprintf("%0."+cDig+"f", value)
return val
}
// Round2Float64 四舍五入保留小数默认2位
func Round2Float64(value float64, args ...interface{}) (v float64) {
var places int32 = 2
if len(args) > 0 {
places = args[0].(int32)
}
return decimal.NewFromFloat(value).Round(places).InexactFloat64()
return gconv.Float64(Round2String(value, args...))
}
// FileSize 字节的单位转换 保留两位小数

View File

@@ -1,6 +1,6 @@
{
"name": "hotgo",
"version": "2.6.7",
"version": "2.6.10",
"author": {
"name": "MengShuai",
"email": "133814250@qq.com",

View File

@@ -24,7 +24,7 @@
import { useLockscreenStore } from '@/store/modules/lockscreen';
import { useRoute } from 'vue-router';
import { useDesignSettingStore } from '@/store/modules/designSetting';
import { lighten } from '@/utils/index';
import { lighten } from '@/utils';
const route = useRoute();
const useLockscreen = useLockscreenStore();

View File

@@ -101,6 +101,21 @@ export function login(params) {
);
}
/**
* @description: 用户注销
*/
export function logout() {
return http.request<BasicResponseModel>(
{
url: ApiEnum.SiteLogout,
method: 'POST',
},
{
isTransformResponse: false,
}
);
}
/**
* @description: 用户修改密码
*/
@@ -116,14 +131,3 @@ export function changePassword(params, uid) {
}
);
}
/**
* @description: 用户登出
*/
export function logout(params) {
return http.request({
url: '/login/logout',
method: 'POST',
params,
});
}

View File

@@ -4,6 +4,7 @@ export enum ApiEnum {
// 基础
SiteLogin = '/site/login', // 登录
SiteLogout = '/site/logout', // 注销
SiteConfig = '/site/config', // 配置信息
// 用户

View File

@@ -301,16 +301,16 @@
});
};
// 退出登录
// 注销登录
const doLogout = () => {
dialog.info({
title: '提示',
content: '您确定要退出登录吗',
content: '您确定要注销登录吗',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
userStore.logout().then(() => {
message.success('成功退出登录');
message.success('成功注销登录');
// 移除标签页
localStorage.removeItem(TABS_ROUTES);
router
@@ -377,7 +377,7 @@
key: 1,
},
{
label: '退出登录',
label: '注销登录',
key: 2,
},
];

View File

@@ -3,7 +3,7 @@ import { createStorage, storage } from '@/utils/Storage';
import { store } from '@/store';
import { ACCESS_TOKEN, CURRENT_CONFIG, CURRENT_USER, IS_LOCKSCREEN } from '@/store/mutation-types';
import { ResultEnum } from '@/enums/httpEnum';
import { getConfig, getUserInfo, login } from '@/api/system/user';
import { getConfig, getUserInfo, login, logout } from '@/api/system/user';
const Storage = createStorage({ storage: localStorage });
export interface UserInfoState {
@@ -114,7 +114,7 @@ export const useUserStore = defineStore({
const response = await login(userInfo);
const { data, code } = response;
if (code === ResultEnum.SUCCESS) {
const ex = 7 * 24 * 60 * 60 * 1000;
const ex = 30 * 24 * 60 * 60 * 1000;
storage.set(ACCESS_TOKEN, data.token, ex);
storage.set(CURRENT_USER, data, ex);
storage.set(IS_LOCKSCREEN, false);
@@ -168,11 +168,19 @@ export const useUserStore = defineStore({
},
// 登出
async logout() {
try {
const response = await logout();
const { code } = response;
if (code === ResultEnum.SUCCESS) {
this.setPermissions([]);
this.setUserInfo(null);
storage.remove(ACCESS_TOKEN);
storage.remove(CURRENT_USER);
return Promise.resolve('');
}
return Promise.resolve(response);
} catch (e) {
return Promise.reject(e);
}
},
},
});

View File

@@ -105,10 +105,10 @@ const transform: AxiosTransform = {
const LoginPath = PageEnum.BASE_LOGIN;
if (router.currentRoute.value?.name === LoginName) return;
// 到登录页
errorMsg = '登录超时,请重新登录!';
errorMsg = message ?? '登录超时,请重新登录!';
$dialog.warning({
title: '提示',
content: '登录身份已失效,请重新登录!',
content: errorMsg, // '登录身份已失效,请重新登录!',
positiveText: '确定',
//negativeText: '取消',
closable: false,

View File

@@ -203,7 +203,7 @@
message.success('更新成功');
userStore.logout().then(() => {
message.success('成功退出登录');
message.success('成功注销登录');
// 移除标签页
localStorage.removeItem(TABS_ROUTES);
router

View File

@@ -193,7 +193,7 @@
message.success('更新成功');
userStore.logout().then(() => {
message.success('成功退出登录');
message.success('成功注销登录');
// 移除标签页
localStorage.removeItem(TABS_ROUTES);
router

View File

@@ -1,6 +1,6 @@
import { h } from 'vue';
import { NAvatar, NTag } from 'naive-ui';
import { timestampToTime, formatBefore, formatAfter } from '@/utils/dateUtil';
import { timestampToTime, formatBefore } from '@/utils/dateUtil';
export const columns = [
{
@@ -31,11 +31,11 @@ export const columns = [
return row.app;
},
},
// {
// title: '用户ID',
// key: 'userId',
// width: 100,
// },
{
title: '用户ID',
key: 'userId',
width: 100,
},
{
title: '用户名',
key: 'username',
@@ -90,14 +90,6 @@ export const columns = [
return row.os;
},
},
{
title: '授权过期',
key: 'expTime',
width: 80,
render: (rows, _) => {
return formatAfter(new Date(rows.expTime * 1000));
},
},
{
title: '最后活跃',
key: 'heartbeatTime',