mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-08-26 16:46:14 +08:00
发布v2.6.10版本,更新内容请查看:https://github.com/bufanyun/hotgo/blob/v2.0/docs/guide-zh-CN/start-update-log.md
This commit is contained in:
@@ -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
|
||||
|
@@ -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支付,可通过后台直接配置参数
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 地理定位
|
||||
|
@@ -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(
|
||||
// 需要验证的路由
|
||||
// ..
|
||||
|
@@ -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:"验证码"`
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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=
|
||||
|
@@ -7,6 +7,6 @@ package consts
|
||||
|
||||
// cache
|
||||
const (
|
||||
CacheJwtToken = "jwt_token:" // JWT-token
|
||||
CacheJwtUserBind = "jwt_user_bind:" // JWT-用户身份绑定
|
||||
CacheToken = "token" // 登录token
|
||||
CacheTokenBind = "token_bind" // 登录用户身份绑定
|
||||
)
|
||||
|
@@ -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 (
|
||||
|
@@ -7,5 +7,5 @@ package consts
|
||||
|
||||
// VersionApp HotGo版本
|
||||
const (
|
||||
VersionApp = "2.6.7"
|
||||
VersionApp = "2.6.10"
|
||||
)
|
||||
|
@@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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",
|
||||
|
@@ -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 // 请求耗时
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
}
|
@@ -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),
|
||||
|
299
server/internal/library/token/token.go
Normal file
299
server/internal/library/token/token.go
Normal 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)
|
||||
}
|
@@ -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,
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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())
|
||||
|
@@ -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)
|
||||
|
@@ -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()
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
// 获取jwtToken
|
||||
jwtToken := consts.CacheJwtToken + gmd5.MustEncryptString(authorization)
|
||||
jwtSign := g.Cfg().MustGet(ctx, "jwt.sign", "hotgo")
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// 保存到上下文
|
||||
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,
|
||||
}
|
||||
}
|
||||
contexts.SetUser(ctx, customCtx.User)
|
||||
contexts.SetUser(r.Context(), user)
|
||||
return
|
||||
}
|
||||
|
||||
// isExceptAuth 是否是不需要验证权限的路由地址
|
||||
func isExceptAuth(ctx context.Context, appName, path string) bool {
|
||||
pathList := g.Cfg().MustGet(ctx, fmt.Sprintf("router.%v.exceptAuth", appName)).Strings()
|
||||
|
||||
for i := 0; i < len(pathList); i++ {
|
||||
if validate.InSliceExistStr(pathList[i], path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
@@ -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"})
|
||||
|
@@ -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"`
|
||||
}
|
||||
|
@@ -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:"登录时间"`
|
||||
}
|
||||
|
@@ -20,7 +20,6 @@ type AdminMember struct {
|
||||
Username interface{} // 帐号
|
||||
PasswordHash interface{} // 密码
|
||||
Salt interface{} // 密码盐
|
||||
AuthKey interface{} // 授权令牌
|
||||
PasswordResetToken interface{} // 密码重置令牌
|
||||
Integral interface{} // 积分
|
||||
Balance interface{} // 余额
|
||||
|
@@ -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{} // 请求耗时
|
||||
|
@@ -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:"余额"`
|
||||
|
@@ -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:"请求耗时"`
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
)
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
|
||||
|
||||
#消息队列
|
||||
|
@@ -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(
|
||||
// 需要验证的路由
|
||||
// ..
|
||||
|
@@ -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');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
@@ -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
|
||||
}
|
@@ -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 字节的单位转换 保留两位小数
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hotgo",
|
||||
"version": "2.6.7",
|
||||
"version": "2.6.10",
|
||||
"author": {
|
||||
"name": "MengShuai",
|
||||
"email": "133814250@qq.com",
|
||||
|
@@ -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();
|
||||
|
@@ -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,
|
||||
});
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ export enum ApiEnum {
|
||||
|
||||
// 基础
|
||||
SiteLogin = '/site/login', // 登录
|
||||
SiteLogout = '/site/logout', // 注销
|
||||
SiteConfig = '/site/config', // 配置信息
|
||||
|
||||
// 用户
|
||||
|
@@ -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,
|
||||
},
|
||||
];
|
||||
|
@@ -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);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@@ -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,
|
||||
|
@@ -203,7 +203,7 @@
|
||||
message.success('更新成功');
|
||||
|
||||
userStore.logout().then(() => {
|
||||
message.success('成功退出登录');
|
||||
message.success('成功注销登录');
|
||||
// 移除标签页
|
||||
localStorage.removeItem(TABS_ROUTES);
|
||||
router
|
||||
|
@@ -193,7 +193,7 @@
|
||||
message.success('更新成功');
|
||||
|
||||
userStore.logout().then(() => {
|
||||
message.success('成功退出登录');
|
||||
message.success('成功注销登录');
|
||||
// 移除标签页
|
||||
localStorage.removeItem(TABS_ROUTES);
|
||||
router
|
||||
|
@@ -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',
|
||||
|
Reference in New Issue
Block a user