This commit is contained in:
孟帅
2023-03-13 17:00:46 +08:00
parent ab912d0ba6
commit 1acc6d17c4
51 changed files with 2777 additions and 1024 deletions

View File

@@ -0,0 +1,33 @@
package cmd
import (
"context"
"github.com/gogf/gf/v2/os/gcmd"
"hotgo/internal/service"
"os"
)
var (
Auth = &gcmd.Command{
Name: "auth",
Brief: "系统授权,当为第三方客户开发应用项目不想将源码和可执行文件让其随意使用时,可以通过授权的方式约束使用方。",
Description: `目前已实现,一对一、一对多、有效期授权,具体使用可以参考现有逻辑结合实际场景进行改造`,
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
service.TCPAuth().Start(ctx)
// 退出信号监听
signalListen(ctx, func(sig os.Signal) {
service.TCPAuth().Stop(ctx)
})
// 信号监听
signalListen(ctx, signalHandlerForOverall)
select {
case <-serverCloseSignal:
// ...
}
return
},
}
)

View File

@@ -80,7 +80,7 @@ var (
)
func init() {
if err := Main.AddCommand(Http, Queue, Tools, All, Help); err != nil {
if err := Main.AddCommand(Http, Queue, Tools, Auth, All, Help); err != nil {
panic(err)
}
serverCloseSignal = make(chan struct{}, 1)

View File

@@ -9,20 +9,10 @@ package cmd
import (
"context"
"github.com/gogf/gf/v2/os/gproc"
"hotgo/internal/crons"
"hotgo/internal/websocket"
"hotgo/utility/simple"
"os"
)
func signalHandlerForCron(sig os.Signal) {
crons.StopALL()
}
func signalHandlerForWebSocket(sig os.Signal) {
websocket.Stop()
}
func signalHandlerForOverall(sig os.Signal) {
serverCloseSignal <- struct{}{}
}

View File

@@ -10,10 +10,13 @@ import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcmd"
"hotgo/internal/crons"
"hotgo/internal/library/addons"
"hotgo/internal/library/casbin"
"hotgo/internal/router"
"hotgo/internal/service"
"hotgo/internal/websocket"
"os"
)
var (
@@ -68,12 +71,20 @@ var (
// 启动定时任务
service.SysCron().StartCron(ctx)
// 信号监听
signalListen(ctx, signalHandlerForCron, signalHandlerForWebSocket)
//// 启动TCP服务
//service.TCPServer().Start(ctx)
// https
setSSL(ctx, s)
// 退出信号监听
signalListen(ctx, func(sig os.Signal) {
s.Shutdown()
crons.StopALL()
websocket.Stop()
//service.TCPServer().Stop(ctx)
})
// Just run the server.
s.Run()

View File

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

View File

@@ -16,6 +16,7 @@ import (
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/model/entity"
"hotgo/utility/simple"
"strings"
"sync"
)
@@ -161,7 +162,9 @@ func Stop(sysCron *entity.SysCron) (err error) {
func Once(ctx context.Context, sysCron *entity.SysCron) error {
for _, v := range cronList {
if v.GetName() == sysCron.Name {
go v.Execute(ctx)
simple.SafeGo(ctx, func(ctx context.Context) {
v.Execute(ctx)
})
return nil
}
}

View File

@@ -0,0 +1,109 @@
// ==========================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// SysServeLicenseDao is the data access object for table hg_sys_serve_license.
type SysServeLicenseDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns SysServeLicenseColumns // columns contains all the column names of Table for convenient usage.
}
// SysServeLicenseColumns defines and stores column names for table hg_sys_serve_license.
type SysServeLicenseColumns struct {
Id string // 许可ID
Group string // 分组
Name string // 许可名称
Appid string // 应用ID
SecretKey string // 应用秘钥
Desc string // 授权说明
RemoteAddr string // 最后连接地址
Online string // 在线数量
OnlineLimit string // 在线数量限制默认1
LoginTimes string // 登录次数
LastLoginAt string // 最后登录时间
LastActiveAt string // 最后活跃时间
Routes string // 路由表,空使用默认分组路由
AllowedIps string // 白名单,*代表所有只有允许的IP才能连接到tcp服务
EndAt string // 授权结束时间
Remark string // 备注
Status string // 状态
CreatedAt string // 创建时间
UpdatedAt string // 修改时间
}
// sysServeLicenseColumns holds the columns for table hg_sys_serve_license.
var sysServeLicenseColumns = SysServeLicenseColumns{
Id: "id",
Group: "group",
Name: "name",
Appid: "appid",
SecretKey: "secret_key",
Desc: "desc",
RemoteAddr: "remote_addr",
Online: "online",
OnlineLimit: "online_limit",
LoginTimes: "login_times",
LastLoginAt: "last_login_at",
LastActiveAt: "last_active_at",
Routes: "routes",
AllowedIps: "allowed_ips",
EndAt: "end_at",
Remark: "remark",
Status: "status",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
}
// NewSysServeLicenseDao creates and returns a new DAO object for table data access.
func NewSysServeLicenseDao() *SysServeLicenseDao {
return &SysServeLicenseDao{
group: "default",
table: "hg_sys_serve_license",
columns: sysServeLicenseColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *SysServeLicenseDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *SysServeLicenseDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *SysServeLicenseDao) Columns() SysServeLicenseColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *SysServeLicenseDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *SysServeLicenseDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *SysServeLicenseDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"hotgo/internal/dao/internal"
)
// internalSysServeLicenseDao is internal type for wrapping internal DAO implements.
type internalSysServeLicenseDao = *internal.SysServeLicenseDao
// sysServeLicenseDao is the data access object for table hg_sys_serve_license.
// You can define custom methods on it to extend its functionality as you wish.
type sysServeLicenseDao struct {
internalSysServeLicenseDao
}
var (
// SysServeLicense is globally public accessible object for table hg_sys_serve_license operations.
SysServeLicense = sysServeLicenseDao{
internal.NewSysServeLicenseDao(),
}
)
// Fill with you ideas below.

View File

@@ -9,13 +9,13 @@ import (
"hotgo/internal/library/hggen/internal/utility/utils"
)
func doClear(ctx context.Context, dirPath string) {
func doClear(ctx context.Context, dirPath string, force bool) {
files, err := gfile.ScanDirFile(dirPath, "*.go", true)
if err != nil {
mlog.Fatal(err)
}
for _, file := range files {
if utils.IsFileDoNotEdit(file) {
if force || utils.IsFileDoNotEdit(file) {
if err = gfile.Remove(file); err != nil {
mlog.Print(err)
}

View File

@@ -24,7 +24,7 @@ func generateDao(ctx context.Context, in CGenDaoInternalInput) {
dirPathDaoInternal = gfile.Join(dirPathDao, "internal")
)
if in.Clear {
doClear(ctx, dirPathDao)
doClear(ctx, dirPathDao, true)
}
for i := 0; i < len(in.TableNames); i++ {
generateDaoSingle(ctx, generateDaoSingleInput{

View File

@@ -18,7 +18,7 @@ import (
func generateDo(ctx context.Context, in CGenDaoInternalInput) {
var dirPathDo = gfile.Join(in.Path, in.DoPath)
if in.Clear {
doClear(ctx, dirPathDo)
doClear(ctx, dirPathDo, false)
}
in.NoJsonTag = true
in.DescriptionTag = false

View File

@@ -16,7 +16,7 @@ import (
func generateEntity(ctx context.Context, in CGenDaoInternalInput) {
var dirPathEntity = gfile.Join(in.Path, in.EntityPath)
if in.Clear {
doClear(ctx, dirPathEntity)
doClear(ctx, dirPathEntity, false)
}
// Model content.
for i, tableName := range in.TableNames {

View File

@@ -0,0 +1,322 @@
package tcp
import (
"context"
"fmt"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/gtcp"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/gtime"
"hotgo/utility/simple"
"reflect"
"sync"
"time"
)
// ClientConfig 客户端配置
type ClientConfig struct {
Addr string
Auth *AuthMeta
Timeout time.Duration
ConnectInterval time.Duration
MaxConnectCount uint
ConnectCount uint
AutoReconnect bool
LoginEvent CallbackEvent
CloseEvent CallbackEvent
}
// Client 客户端
type Client struct {
Ctx context.Context
Logger *glog.Logger
IsLogin bool // 是否已登录
addr string
auth *AuthMeta
timeout time.Duration
connectInterval time.Duration
maxConnectCount uint
connectCount uint
autoReconnect bool
loginEvent CallbackEvent
closeEvent CallbackEvent
sync.Mutex
heartbeat int64
routers map[string]RouterHandler
conn *gtcp.Conn
wg sync.WaitGroup
closeFlag bool // 关闭标签,关闭以后可以重连
stopFlag bool // 停止标签,停止以后不能重连
}
func NewClient(config *ClientConfig) (client *Client, err error) {
client = new(Client)
if config == nil {
err = gerror.New("config is nil")
return
}
if config.Addr == "" {
err = gerror.New("client address is not set")
return
}
if config.Auth == nil {
err = gerror.New("client auth cannot be empty")
return
}
if config.Auth.Group == "" || config.Auth.Name == "" {
err = gerror.New("Auth.Group or Auth.Group is nil")
return
}
client.Ctx = gctx.New()
client.autoReconnect = true
client.addr = config.Addr
client.auth = config.Auth
client.loginEvent = config.LoginEvent
client.closeEvent = config.CloseEvent
logger := glog.New()
path := g.Cfg().MustGet(client.Ctx, "logger.path", "logs/logger").String()
if err = logger.SetPath(fmt.Sprintf("%s/tcp.client/%s.%s", path, config.Auth.Group, config.Auth.Name)); err != nil {
return
}
client.Logger = logger
if config.ConnectInterval <= 0 {
client.connectInterval = 5 * time.Second
client.Logger.Debugf(client.Ctx, "invalid connectInterval, reset to %v", client.connectInterval)
} else {
client.connectInterval = config.ConnectInterval
}
if config.Timeout <= 0 {
client.timeout = 10 * time.Second
client.Logger.Debugf(client.Ctx, "invalid timeout, reset to %v", client.timeout)
} else {
client.timeout = config.Timeout
}
return
}
// Start 启动
func (client *Client) Start() (err error) {
client.Lock()
defer client.Unlock()
if client.stopFlag {
err = gerror.New("client is stop")
return
}
if client.conn != nil {
return gerror.New("client is running")
}
client.IsLogin = false
client.connectCount = 0
client.closeFlag = false
client.stopFlag = false
client.wg.Add(1)
simple.SafeGo(client.Ctx, func(ctx context.Context) {
client.connect()
})
return
}
// RegisterRouter 注册路由
func (client *Client) RegisterRouter(routers map[string]RouterHandler) (err error) {
if client.conn != nil {
return gerror.New("client is running")
}
client.Lock()
defer client.Unlock()
if client.routers == nil {
client.routers = make(map[string]RouterHandler)
// 默认路由
client.routers = map[string]RouterHandler{
"ResponseServerHeartbeat": client.onResponseServerHeartbeat,
"ResponseServerLogin": client.onResponseServerLogin,
}
}
for i, router := range routers {
_, ok := client.routers[i]
if ok {
return gerror.Newf("client route duplicate registration:%v", i)
}
client.routers[i] = router
}
return
}
func (client *Client) dial() *gtcp.Conn {
for {
conn, err := gtcp.NewConn(client.addr, client.timeout)
if err == nil || client.closeFlag {
return conn
}
if client.maxConnectCount > 0 {
if client.connectCount < client.maxConnectCount {
client.connectCount += 1
} else {
return nil
}
}
client.Logger.Debugf(client.Ctx, "connect to %v error: %v", client.addr, err)
time.Sleep(client.connectInterval)
continue
}
}
func (client *Client) connect() {
defer client.wg.Done()
goto reconnect
reconnect:
conn := client.dial()
if conn == nil {
client.Logger.Debugf(client.Ctx, "client dial failed")
return
}
client.Lock()
if client.closeFlag {
client.Unlock()
conn.Close()
client.Logger.Debugf(client.Ctx, "client connect but closeFlag is true")
return
}
client.conn = conn
client.connectCount = 0
client.heartbeat = gtime.Timestamp()
client.read()
client.Unlock()
client.serverLogin()
client.startCron()
}
func (client *Client) read() {
simple.SafeGo(client.Ctx, func(ctx context.Context) {
defer func() {
client.Close()
client.Logger.Debugf(client.Ctx, "client are about to be reconnected..")
time.Sleep(client.connectInterval)
client.Start()
}()
for {
if client.conn == nil {
client.Logger.Debugf(client.Ctx, "client client.conn is nil, server closed")
break
}
msg, err := RecvPkg(client.conn)
if err != nil {
client.Logger.Debugf(client.Ctx, "client RecvPkg err:%+v, server closed", err)
break
}
if client.routers == nil {
client.Logger.Debugf(client.Ctx, "client RecvPkg routers is nil")
break
}
if msg == nil {
client.Logger.Debugf(client.Ctx, "client RecvPkg msg is nil")
break
}
f, ok := client.routers[msg.Router]
if !ok {
client.Logger.Debugf(client.Ctx, "client RecvPkg invalid message: %+v", msg)
continue
}
f(msg.Data, client.conn)
}
})
}
// Close 关闭同服务器的链接
func (client *Client) Close() {
client.Lock()
defer client.Unlock()
client.IsLogin = false
client.closeFlag = true
if client.conn != nil {
client.conn.Close()
client.conn = nil
}
if client.closeEvent != nil {
client.closeEvent()
}
client.wg.Wait()
}
// Stop 停止服务
func (client *Client) Stop() {
if client.stopFlag {
return
}
client.stopFlag = true
client.stopCron()
client.Close()
}
// Destroy 销毁当前连接
func (client *Client) Destroy() {
client.stopCron()
if client.conn != nil {
client.conn.Close()
client.conn = nil
}
}
// Write
func (client *Client) Write(data interface{}) error {
client.Lock()
defer client.Unlock()
if client.conn == nil {
return gerror.New("client conn is nil")
}
if client.closeFlag {
return gerror.New("client conn is closed")
}
if data == nil {
return gerror.New("client Write message is nil")
}
// 签名
SetSign(data, gctx.CtxId(client.Ctx), client.auth.AppId, client.auth.SecretKey)
msgType := reflect.TypeOf(data)
if msgType == nil || msgType.Kind() != reflect.Ptr {
return gerror.Newf("client json message pointer required: %+v", data)
}
msg := &Message{Router: msgType.Elem().Name(), Data: data}
client.Logger.Debugf(client.Ctx, "client Write Router:%v, data:%+v", msg.Router, gjson.New(data).String())
return SendPkg(client.conn, msg)
}

View File

@@ -0,0 +1,37 @@
package tcp
import (
"context"
"fmt"
"github.com/gogf/gf/v2/os/gcron"
"github.com/gogf/gf/v2/os/gtime"
)
func (client *Client) getCronKey(s string) string {
return fmt.Sprintf("tcp.client_%s_%s:%s", s, client.auth.Group, client.auth.Name)
}
func (client *Client) stopCron() {
for _, v := range gcron.Entries() {
gcron.Remove(v.Name)
}
}
func (client *Client) startCron() {
// 心跳超时检查
if gcron.Search(client.getCronKey(cronHeartbeatVerify)) == nil {
gcron.AddSingleton(client.Ctx, "@every 600s", func(ctx context.Context) {
if client.heartbeat < gtime.Timestamp()-600 {
client.Logger.Debugf(client.Ctx, "client heartbeat timeout, about to reconnect..")
client.Destroy()
}
}, client.getCronKey(cronHeartbeatVerify))
}
// 心跳
if gcron.Search(client.getCronKey(cronHeartbeat)) == nil {
gcron.AddSingleton(client.Ctx, "@every 120s", func(ctx context.Context) {
client.serverHeartbeat()
}, client.getCronKey(cronHeartbeat))
}
}

View File

@@ -0,0 +1,61 @@
package tcp
import (
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/internal/model/input/msgin"
)
// serverLogin 心跳
func (client *Client) serverHeartbeat() {
if err := client.Write(&msgin.ServerHeartbeat{}); err != nil {
client.Logger.Debugf(client.Ctx, "client WriteMsg ServerHeartbeat err:%+v", err)
return
}
}
// serverLogin 服务登陆
func (client *Client) serverLogin() {
data := &msgin.ServerLogin{
Group: client.auth.Group,
Name: client.auth.Name,
}
if err := client.Write(data); err != nil {
client.Logger.Debugf(client.Ctx, "client WriteMsg ServerLogin err:%+v", err)
return
}
if client.loginEvent != nil {
client.loginEvent()
}
}
func (client *Client) onResponseServerLogin(args ...interface{}) {
var in *msgin.ResponseServerLogin
if err := gconv.Scan(args[0], &in); err != nil {
client.Logger.Infof(client.Ctx, "onResponseServerLogin message Scan failed:%+v, args:%+v", err, args[0])
return
}
client.Logger.Infof(client.Ctx, "onResponseServerLogin in:%+v", *in)
if in.Code != gcode.CodeOK.Code() {
client.IsLogin = false
client.Logger.Warningf(client.Ctx, "onResponseServerLogin quit err:%v", in.Message)
client.Destroy()
return
}
client.IsLogin = true
}
func (client *Client) onResponseServerHeartbeat(args ...interface{}) {
var in *msgin.ResponseServerHeartbeat
if err := gconv.Scan(args[0], &in); err != nil {
client.Logger.Infof(client.Ctx, "onResponseServerHeartbeat message Scan failed:%+v, args:%+v", err, args)
return
}
client.heartbeat = gtime.Timestamp()
client.Logger.Infof(client.Ctx, "onResponseServerHeartbeat in:%+v", *in)
}

View File

@@ -0,0 +1,25 @@
package tcp
// 定时任务
const (
cronHeartbeatVerify = "tcpHeartbeatVerify"
cronHeartbeat = "tcpHeartbeat"
)
// 认证分组
const (
ClientGroupCron = "cron" // 定时任务
ClientGroupQueue = "queue" // 消息队列
ClientGroupAuth = "auth" // 服务授权
)
// AuthMeta 认证元数据
type AuthMeta struct {
Group string `json:"group"`
Name string `json:"name"`
AppId string `json:"appId"`
SecretKey string `json:"secretKey"`
}
// CallbackEvent 回调事件
type CallbackEvent func()

View File

@@ -0,0 +1,39 @@
package tcp
import (
"encoding/json"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/net/gtcp"
"github.com/gogf/gf/v2/util/gconv"
)
type RouterHandler func(args ...interface{})
// Message 路由消息
type Message struct {
Router string `json:"router"`
Data interface{} `json:"data"`
}
func SendPkg(conn *gtcp.Conn, message *Message) error {
b, err := json.Marshal(message)
if err != nil {
return err
}
return conn.SendPkg(b)
}
func RecvPkg(conn *gtcp.Conn) (*Message, error) {
if data, err := conn.RecvPkg(); err != nil {
return nil, err
} else {
var msg = new(Message)
if err = gconv.Scan(data, &msg); err != nil {
return nil, gerror.Newf("invalid package structure: %s", err.Error())
}
if msg.Router == "" {
return nil, gerror.Newf("message is not routed: %+v", msg)
}
return msg, err
}
}

View File

@@ -0,0 +1,278 @@
package tcp
import (
"context"
"fmt"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/gtcp"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/glog"
"reflect"
"sync"
"time"
)
type ClientConn struct {
Conn *gtcp.Conn
Auth *AuthMeta
heartbeat int64
mutex sync.Mutex
}
type ServerConfig struct {
Name string // 服务名称
Addr string // 监听地址
}
type Server struct {
Ctx context.Context
Logger *glog.Logger
addr string
name string
ln *gtcp.Server
wgLn sync.WaitGroup
mutex sync.Mutex
closeFlag bool
clients map[string]*ClientConn // 已登录的认证客户端
mutexConns sync.Mutex
wgConns sync.WaitGroup
cronRouters map[string]RouterHandler // 路由
queueRouters map[string]RouterHandler
authRouters map[string]RouterHandler
}
func NewServer(config *ServerConfig) (server *Server, err error) {
if config == nil {
err = gerror.New("config is nil")
return
}
if config.Addr == "" {
err = gerror.New("server address is not set")
return
}
if config.Name == "" {
config.Name = "hotgo"
}
server = new(Server)
server.Ctx = gctx.New()
server.addr = config.Addr
server.name = config.Name
server.ln = gtcp.NewServer(server.addr, server.accept, config.Name)
server.clients = make(map[string]*ClientConn)
server.closeFlag = false
logger := glog.New()
path := g.Cfg().MustGet(server.Ctx, "logger.path", "logs/logger").String()
if err = logger.SetPath(fmt.Sprintf("%s/tcp.server/%s", path, config.Name)); err != nil {
return
}
server.Logger = logger
server.startCron()
return
}
func (server *Server) accept(conn *gtcp.Conn) {
defer func() {
server.mutexConns.Lock()
conn.Close()
// 从登录列表中移除
if _, ok := server.clients[conn.RemoteAddr().String()]; ok {
delete(server.clients, conn.RemoteAddr().String())
}
server.mutexConns.Unlock()
}()
for {
msg, err := RecvPkg(conn)
if err != nil {
server.Logger.Debugf(server.Ctx, "RecvPkg err:%+v, client closed.", err)
break
}
client := server.getLoginConn(conn)
switch msg.Router {
case "ServerLogin": // 服务登录
server.onServerLogin(msg.Data, conn)
case "ServerHeartbeat": // 心跳
if client == nil {
server.Logger.Infof(server.Ctx, "conn not connected, ignore the heartbeat, msg:%+v", msg)
continue
}
server.onServerHeartbeat(msg, client)
default: // 通用路由消息处理
if client == nil {
server.Logger.Warningf(server.Ctx, "conn is not logged in but sends a routing message. actively conn disconnect, msg:%+v", msg)
time.Sleep(time.Second)
conn.Close()
return
}
server.handleRouterMsg(msg, client)
}
}
}
// handleRouterMsg 处理路由消息
func (server *Server) handleRouterMsg(msg *Message, client *ClientConn) {
// 验证签名
err := VerifySign(msg.Data, client.Auth.AppId, client.Auth.SecretKey)
if err != nil {
server.Logger.Warningf(server.Ctx, "handleRouterMsg VerifySign err:%+v message: %+v", err, msg)
return
}
handle := func(routers map[string]RouterHandler, group string) {
if routers == nil {
server.Logger.Debugf(server.Ctx, "handleRouterMsg route is not initialized %v message: %+v", group, msg)
return
}
f, ok := routers[msg.Router]
if !ok {
server.Logger.Debugf(server.Ctx, "handleRouterMsg invalid %v message: %+v", group, msg)
return
}
f(msg.Data, client)
}
switch client.Auth.Group {
case ClientGroupCron:
handle(server.cronRouters, client.Auth.Group)
case ClientGroupQueue:
handle(server.queueRouters, client.Auth.Group)
case ClientGroupAuth:
handle(server.authRouters, client.Auth.Group)
default:
server.Logger.Warningf(server.Ctx, "group is not registered: %+v", client.Auth.Group)
}
}
// getLoginConn 获取指定已登录的连接
func (server *Server) getLoginConn(conn *gtcp.Conn) *ClientConn {
client, ok := server.clients[conn.RemoteAddr().String()]
if !ok {
return nil
}
return client
}
// getLoginConn 获取指定appid的所有连接
func (server *Server) getAppIdClients(appid string) (list []*ClientConn) {
for _, v := range server.clients {
if v.Auth.AppId == appid {
list = append(list, v)
}
}
return
}
// RegisterAuthRouter 注册授权路由
func (server *Server) RegisterAuthRouter(routers map[string]RouterHandler) {
server.mutex.Lock()
defer server.mutex.Unlock()
if server.authRouters == nil {
server.authRouters = make(map[string]RouterHandler)
}
for i, router := range routers {
_, ok := server.authRouters[i]
if ok {
server.Logger.Debugf(server.Ctx, "server authRouters duplicate registration:%v", i)
continue
}
server.authRouters[i] = router
}
}
// RegisterCronRouter 注册任务路由
func (server *Server) RegisterCronRouter(routers map[string]RouterHandler) {
server.mutex.Lock()
defer server.mutex.Unlock()
if server.cronRouters == nil {
server.cronRouters = make(map[string]RouterHandler)
}
for i, router := range routers {
_, ok := server.cronRouters[i]
if ok {
server.Logger.Debugf(server.Ctx, "server cronRouters duplicate registration:%v", i)
continue
}
server.cronRouters[i] = router
}
}
// RegisterQueueRouter 注册队列路由
func (server *Server) RegisterQueueRouter(routers map[string]RouterHandler) {
server.mutex.Lock()
defer server.mutex.Unlock()
if server.queueRouters == nil {
server.queueRouters = make(map[string]RouterHandler)
}
for i, router := range routers {
_, ok := server.queueRouters[i]
if ok {
server.Logger.Debugf(server.Ctx, "server queueRouters duplicate registration:%v", i)
continue
}
server.queueRouters[i] = router
}
}
func (server *Server) Listen() (err error) {
server.wgLn.Add(1)
defer server.wgLn.Done()
return server.ln.Run()
}
// Close 关闭服务
func (server *Server) Close() {
if server.closeFlag {
return
}
server.closeFlag = true
server.stopCron()
server.mutexConns.Lock()
for _, client := range server.clients {
client.Conn.Close()
}
server.clients = nil
server.mutexConns.Unlock()
server.wgConns.Wait()
if server.ln != nil {
server.ln.Close()
}
server.wgLn.Wait()
}
// Write 向指定客户端发送消息
func (server *Server) Write(conn *gtcp.Conn, data interface{}) (err error) {
if server.closeFlag {
return gerror.New("service is down")
}
msgType := reflect.TypeOf(data)
if msgType == nil || msgType.Kind() != reflect.Ptr {
return gerror.Newf("json message pointer required: %+v", data)
}
msg := &Message{Router: msgType.Elem().Name(), Data: data}
server.Logger.Debugf(server.Ctx, "server Write Router:%v, data:%+v", msg.Router, gjson.New(data).String())
return SendPkg(conn, msg)
}

View File

@@ -0,0 +1,35 @@
package tcp
import (
"context"
"fmt"
"github.com/gogf/gf/v2/os/gcron"
"github.com/gogf/gf/v2/os/gtime"
)
func (server *Server) getCronKey(s string) string {
return fmt.Sprintf("tcp.server_%s_%s", s, server.name)
}
func (server *Server) stopCron() {
for _, v := range gcron.Entries() {
gcron.Remove(v.Name)
}
}
func (server *Server) startCron() {
// 心跳超时检查
if gcron.Search(server.getCronKey(cronHeartbeatVerify)) == nil {
gcron.AddSingleton(server.Ctx, "@every 300s", func(ctx context.Context) {
if server.clients == nil {
return
}
for _, client := range server.clients {
if client.heartbeat < gtime.Timestamp()-300 {
client.Conn.Close()
server.Logger.Debugf(server.Ctx, "client heartbeat timeout, about to reconnect.. auth:%+v", client.Auth)
}
}
}, server.getCronKey(cronHeartbeatVerify))
}
}

View File

@@ -0,0 +1,150 @@
package tcp
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/gtcp"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/internal/consts"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/msgin"
"hotgo/utility/convert"
)
func (server *Server) onServerLogin(args ...interface{}) {
var (
in = new(msgin.ServerLogin)
conn = args[1].(*gtcp.Conn)
res = new(msgin.ResponseServerLogin)
models *entity.SysServeLicense
)
if err := gconv.Scan(args[0], &in); err != nil {
server.Logger.Infof(server.Ctx, "onServerLogin message Scan failed:%+v, args:%+v", err, args)
return
}
server.Logger.Infof(server.Ctx, "onServerLogin in:%+v", *in)
err := g.Model("sys_serve_license").
Ctx(server.Ctx).
Where("appid = ?", in.AppId).
Scan(&models)
if err != nil {
res.Code = 1
res.Message = err.Error()
server.Write(conn, res)
return
}
if models == nil {
res.Code = 2
res.Message = "授权信息不存在"
server.Write(conn, res)
return
}
// 验证签名
if err = VerifySign(in, models.Appid, models.SecretKey); err != nil {
res.Code = 3
res.Message = "签名错误,请联系管理员"
server.Write(conn, res)
return
}
if models.Status != consts.StatusEnabled {
res.Code = 4
res.Message = "授权已禁用,请联系管理员"
server.Write(conn, res)
return
}
if models.Group != in.Group {
res.Code = 5
res.Message = "你登录的授权分组未得到授权,请联系管理员"
server.Write(conn, res)
return
}
if models.EndAt.Before(gtime.Now()) {
res.Code = 6
res.Message = "授权已过期,请联系管理员"
server.Write(conn, res)
return
}
allowedIps := convert.IpFilterStrategy(models.AllowedIps)
if _, ok := allowedIps["*"]; !ok {
ip := gstr.StrTillEx(conn.RemoteAddr().String(), ":")
if _, ok2 := allowedIps[ip]; !ok2 {
res.Code = 7
res.Message = "IP(" + ip + ")未授权,请联系管理员"
server.Write(conn, res)
return
}
}
// 检查是否存在多地登录,如果连接超出上限,直接将所有已连接断开,然后在吧新的连接加入进来
clients := server.getAppIdClients(models.Appid)
online := len(clients) + 1
if online > models.OnlineLimit {
online = 1
res2 := new(msgin.ResponseServerLogin)
res2.Code = 8
res2.Message = "授权登录端超出上限,请联系管理员"
for _, client := range clients {
server.Write(client.Conn, res2)
client.Conn.Close()
}
}
server.mutexConns.Lock()
server.clients[conn.RemoteAddr().String()] = &ClientConn{
Conn: conn,
Auth: &AuthMeta{
Group: in.Group,
Name: in.Name,
AppId: in.AppId,
SecretKey: models.SecretKey,
},
heartbeat: gtime.Timestamp(),
}
server.mutexConns.Unlock()
server.Write(conn, res)
_, err = g.Model("sys_serve_license").
Ctx(server.Ctx).
Where("id = ?", models.Id).Data(g.Map{
"online": online,
"login_times": models.LoginTimes + 1,
"last_login_at": gtime.Now(),
"last_active_at": gtime.Now(),
"remote_addr": conn.RemoteAddr().String(),
}).Update()
if err != nil {
server.Logger.Warningf(server.Ctx, "onServerLogin Update err:%+v", err)
}
}
func (server *Server) onServerHeartbeat(args ...interface{}) {
var in *msgin.ServerHeartbeat
if err := gconv.Scan(args, &in); err != nil {
server.Logger.Infof(server.Ctx, "onServerHeartbeat message Scan failed:%+v, args:%+v", err, args)
return
}
client := args[1].(*ClientConn)
client.heartbeat = gtime.Timestamp()
server.Write(client.Conn, &msgin.ResponseServerHeartbeat{})
_, err := g.Model("sys_serve_license").
Ctx(server.Ctx).
Where("appid = ?", client.Auth.AppId).Data(g.Map{
"last_active_at": gtime.Now(),
}).Update()
if err != nil {
server.Logger.Warningf(server.Ctx, "onServerHeartbeat Update err:%+v", err)
}
}

View File

@@ -0,0 +1,41 @@
package tcp
import (
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/internal/model/input/msgin"
)
type Sign interface {
SetSign(traceID, appId, secretKey string)
}
// SetSign 设置签名
func SetSign(data interface{}, traceID, appId, secretKey string) {
if c, ok := data.(Sign); ok {
c.SetSign(traceID, appId, secretKey)
return
}
}
// VerifySign 验证签名
func VerifySign(data interface{}, appId, secretKey string) (err error) {
// 无密钥,无需签名
if secretKey == "" {
return
}
var in *msgin.Request
if err = gconv.Scan(data, &in); err != nil {
return
}
if appId != in.AppId {
return gerror.New("appId invalid")
}
if in.Sign != in.GetSign(secretKey) {
return gerror.New("sign invalid")
}
return
}

View File

@@ -10,5 +10,7 @@ import (
_ "hotgo/internal/logic/hook"
_ "hotgo/internal/logic/middleware"
_ "hotgo/internal/logic/sys"
_ "hotgo/internal/logic/tcpclient"
_ "hotgo/internal/logic/tcpserver"
_ "hotgo/internal/logic/view"
)

View File

@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package sys
import (
@@ -11,13 +10,12 @@ import (
"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"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/global"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
"hotgo/utility/convert"
"hotgo/utility/validate"
)
@@ -176,91 +174,12 @@ func (s *sSysBlacklist) Load(ctx context.Context) {
return
}
matchStrategy := func(originIp string) {
// 多个IP
if gstr.Contains(originIp, ",") {
ips := gstr.Explode(",", originIp)
if len(ips) > 0 {
for _, ip := range ips {
if !validate.IsIp(ip) {
continue
}
global.Blacklists[ip] = struct{}{}
}
}
return
}
// IP段
if gstr.Contains(originIp, "/24") {
segment := gstr.Replace(originIp, "/24", "")
if !validate.IsIp(segment) {
return
}
var (
start = gstr.Explode(".", segment)
prefix = gstr.Implode(".", start[:len(start)-1]) + "."
index = gconv.Int(start[len(start)-1])
)
if index < 1 {
index = 1
}
for i := index; i <= 254; i++ {
global.Blacklists[prefix+gconv.String(i)] = struct{}{}
}
return
}
// IP范围
if gstr.Contains(originIp, "-") {
originIps := gstr.Explode("-", originIp)
if len(originIps) != 2 {
return
}
if !validate.IsIp(originIps[0]) || !validate.IsIp(originIps[1]) {
return
}
var (
start = gstr.Explode(".", originIps[0])
prefix = gstr.Implode(".", start[:len(start)-1]) + "."
startIndex = gconv.Int(gstr.SubStrFromREx(originIps[0], "."))
endIndex = gconv.Int(gstr.SubStrFromREx(originIps[1], "."))
)
if startIndex >= endIndex {
global.Blacklists[originIps[0]] = struct{}{}
return
}
if startIndex < 1 {
startIndex = 1
}
if endIndex > 254 {
endIndex = 254
}
for i := startIndex; i <= endIndex; i++ {
global.Blacklists[prefix+gconv.String(i)] = struct{}{}
}
return
}
// 指定IP
if validate.IsIp(originIp) {
global.Blacklists[originIp] = struct{}{}
return
}
}
for _, v := range array {
matchStrategy(v.String())
list := convert.IpFilterStrategy(v.String())
if len(list) > 0 {
for k, _ := range list {
global.Blacklists[k] = struct{}{}
}
}
}
}

View File

@@ -0,0 +1,110 @@
package tcpclient
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcron"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/internal/library/network/tcp"
"hotgo/internal/model/input/msgin"
"hotgo/internal/service"
"hotgo/utility/simple"
)
// tcp授权
type sTCPAuth struct {
client *tcp.Client
}
func init() {
service.RegisterTCPAuth(newTCPAuth())
}
func newTCPAuth() *sTCPAuth {
return &sTCPAuth{}
}
// Start 启动服务
func (s *sTCPAuth) Start(ctx context.Context) {
g.Log().Debug(ctx, "TCPAuth start..")
simple.SafeGo(ctx, func(ctx context.Context) {
client, err := tcp.NewClient(&tcp.ClientConfig{
Addr: "127.0.0.1:8099",
Auth: &tcp.AuthMeta{
Group: "auth",
Name: "auth1",
AppId: "mengshuai",
SecretKey: "123456",
},
LoginEvent: s.loginEvent,
CloseEvent: s.closeEvent,
})
if err != nil {
g.Log().Infof(ctx, "TCPAuth NewClient fail%+v", err)
return
}
s.client = client
err = s.client.RegisterRouter(map[string]tcp.RouterHandler{
"ResponseAuthSummary": s.onResponseAuthSummary, // 获取授权信息
})
if err != nil {
g.Log().Infof(ctx, "TCPAuth RegisterRouter fail%+v", err)
return
}
if err = s.client.Start(); err != nil {
g.Log().Infof(ctx, "TCPAuth Start fail%+v", err)
return
}
})
}
// Stop 关闭服务
func (s *sTCPAuth) Stop(ctx context.Context) {
if s.client != nil {
s.client.Stop()
g.Log().Debug(ctx, "TCPAuth stop..")
}
}
func (s *sTCPAuth) loginEvent() {
// 登录成功后立即请求一次授权信息
s.client.Write(&msgin.AuthSummary{})
// 定时检查授权
gcron.Add(s.client.Ctx, "@every 1200s", func(ctx context.Context) {
if !s.client.IsLogin {
g.Log().Infof(ctx, "TCPAuthVerify client is not logged in, skipped")
return
}
s.client.Write(&msgin.AuthSummary{})
}, "TCPAuthVerify")
}
func (s *sTCPAuth) closeEvent() {
// 关闭连接后,删除定时检查授权
gcron.Remove("TCPAuthVerify")
}
func (s *sTCPAuth) onResponseAuthSummary(args ...interface{}) {
var in *msgin.ResponseAuthSummary
if err := gconv.Scan(args[0], &in); err != nil {
s.client.Logger.Infof(s.client.Ctx, "ResponseAuthSummary message Scan failed:%+v, args:%+v", err, args[0])
return
}
s.client.Logger.Infof(s.client.Ctx, "onResponseAuthSummary in:%+v", *in)
// 授权异常
if in.Code != gcode.CodeOK.Code() {
s.client.Logger.Infof(s.client.Ctx, "onResponseAuthSummary authorization verification failed:%+v", in.Message)
s.client.Destroy()
return
}
// 授权通过
// 后续可以做一些操作...
}

View File

@@ -0,0 +1,73 @@
package tcpserver
import (
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/network/tcp"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/msgin"
)
// onAuthSummary 获取授权信息
func (s *sTCPServer) onAuthSummary(args ...interface{}) {
var (
in *msgin.AuthSummary
client = args[1].(*tcp.ClientConn)
res = new(msgin.ResponseAuthSummary)
models *entity.SysServeLicense
)
if err := gconv.Scan(args, &in); err != nil {
s.serv.Logger.Infof(s.serv.Ctx, "onAuthSummary message Scan failed:%+v, args:%+v", err, args)
return
}
if client.Auth == nil {
res.Code = 1
res.Message = "登录信息获取失败,请重新登录"
s.serv.Write(client.Conn, res)
return
}
if err := dao.SysServeLicense.Ctx(s.serv.Ctx).Where("appid = ?", client.Auth.AppId).Scan(&models); err != nil {
res.Code = 2
res.Message = err.Error()
s.serv.Write(client.Conn, res)
return
}
if models == nil {
res.Code = 3
res.Message = "授权信息不存在"
s.serv.Write(client.Conn, res)
return
}
if models.Status != consts.StatusEnabled {
res.Code = 4
res.Message = "授权已禁用,请联系管理员"
s.serv.Write(client.Conn, res)
return
}
if models.Group != client.Auth.Group {
res.Code = 5
res.Message = "你登录的授权分组未得到授权,请联系管理员"
s.serv.Write(client.Conn, res)
return
}
if models.EndAt.Before(gtime.Now()) {
res.Code = 6
res.Message = "授权已过期,请联系管理员"
s.serv.Write(client.Conn, res)
return
}
res.Data = new(msgin.AuthSummaryData)
res.Data.EndAt = models.EndAt
res.Data.Online = models.Online
s.serv.Write(client.Conn, res)
}

View File

@@ -0,0 +1,68 @@
package tcpserver
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"hotgo/internal/library/network/tcp"
"hotgo/internal/service"
"hotgo/utility/simple"
)
type sTCPServer struct {
serv *tcp.Server
}
func init() {
service.RegisterTCPServer(newTCPServer())
}
func newTCPServer() *sTCPServer {
return &sTCPServer{}
}
// Start 启动服务
func (s *sTCPServer) Start(ctx context.Context) {
simple.SafeGo(ctx, func(ctx context.Context) {
g.Log().Debug(ctx, "TCPServer start..")
server, err := tcp.NewServer(&tcp.ServerConfig{
Name: "hotgo",
Addr: g.Cfg().MustGet(ctx, "tcpServe.address").String(),
})
if err != nil {
g.Log().Warningf(ctx, "TCPServer start fail%+v", err)
return
}
s.serv = server
// 消息队列路由
s.serv.RegisterQueueRouter(map[string]tcp.RouterHandler{
// ...
})
// 定时任务路由
s.serv.RegisterCronRouter(map[string]tcp.RouterHandler{
// ...
})
// 授权服务路由
s.serv.RegisterAuthRouter(map[string]tcp.RouterHandler{
"AuthSummary": s.onAuthSummary, // 获取授权信息
})
// 服务监听
if err := s.serv.Listen(); err != nil {
g.Log().Warningf(ctx, "TCPServer Listen err:%v", err)
}
})
}
// Stop 关闭服务
func (s *sTCPServer) Stop(ctx context.Context) {
if s.serv != nil {
s.serv.Close()
g.Log().Debug(ctx, "TCPServer stop..")
}
}

View File

@@ -0,0 +1,35 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// SysServeLicense is the golang structure of table hg_sys_serve_license for DAO operations like Where/Data.
type SysServeLicense struct {
g.Meta `orm:"table:hg_sys_serve_license, do:true"`
Id interface{} // 许可ID
Group interface{} // 分组
Name interface{} // 许可名称
Appid interface{} // 应用ID
SecretKey interface{} // 应用秘钥
Desc interface{} // 授权说明
RemoteAddr interface{} // 最后连接地址
Online interface{} // 在线数量
OnlineLimit interface{} // 在线数量限制默认1
LoginTimes interface{} // 登录次数
LastLoginAt *gtime.Time // 最后登录时间
LastActiveAt *gtime.Time // 最后活跃时间
Routes *gjson.Json // 路由表,空使用默认分组路由
AllowedIps interface{} // 白名单,*代表所有只有允许的IP才能连接到tcp服务
EndAt *gtime.Time // 授权结束时间
Remark interface{} // 备注
Status interface{} // 状态
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 修改时间
}

View File

@@ -0,0 +1,33 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gtime"
)
// SysServeLicense is the golang structure for table sys_serve_license.
type SysServeLicense struct {
Id int64 `json:"id" description:"许可ID"`
Group string `json:"group" description:"分组"`
Name string `json:"name" description:"许可名称"`
Appid string `json:"appid" description:"应用ID"`
SecretKey string `json:"secretKey" description:"应用秘钥"`
Desc string `json:"desc" description:"授权说明"`
RemoteAddr string `json:"remoteAddr" description:"最后连接地址"`
Online int `json:"online" description:"在线数量"`
OnlineLimit int `json:"onlineLimit" description:"在线数量限制默认1"`
LoginTimes int64 `json:"loginTimes" description:"登录次数"`
LastLoginAt *gtime.Time `json:"lastLoginAt" description:"最后登录时间"`
LastActiveAt *gtime.Time `json:"lastActiveAt" description:"最后活跃时间"`
Routes *gjson.Json `json:"routes" description:"路由表,空使用默认分组路由"`
AllowedIps string `json:"allowedIps" description:"白名单,*代表所有只有允许的IP才能连接到tcp服务"`
EndAt *gtime.Time `json:"endAt" description:"授权结束时间"`
Remark string `json:"remark" description:"备注"`
Status int `json:"status" description:"状态"`
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" description:"修改时间"`
}

View File

@@ -0,0 +1,19 @@
package msgin
import "github.com/gogf/gf/v2/os/gtime"
// AuthSummary 授权摘要
type AuthSummary struct {
Request
}
// ResponseAuthSummary 响应授权摘要
type ResponseAuthSummary struct {
Response
Data *AuthSummaryData `json:"data,omitempty" description:"数据集"`
}
type AuthSummaryData struct {
EndAt *gtime.Time `json:"end_at" description:"授权过期时间"`
Online int `json:"online" description:"在线人数"`
}

View File

@@ -0,0 +1,61 @@
package msgin
import (
"fmt"
"github.com/gogf/gf/v2/os/gtime"
"hotgo/utility/encrypt"
)
type Request struct {
AppId string `json:"appID" v:"0" example:"d0bb93048bc5c9164cdee845dcb7f820" description:"应用ID"`
TraceID string `json:"traceID" v:"0" example:"d0bb93048bc5c9164cdee845dcb7f820" description:"链路ID"`
Timestamp int64 `json:"timestamp" example:"1640966400" description:"服务器时间戳"`
Sign string `json:"sign" example:"d0bb93048bc5c9164cdee845dcb7f820" description:"签名"`
}
func (i *Request) SetSign(traceID, appId, secretKey string) {
i.AppId = appId
i.TraceID = traceID
i.Timestamp = gtime.Timestamp()
i.Sign = i.GetSign(secretKey)
}
func (i *Request) GetSign(secretKey string) string {
return encrypt.Md5ToString(fmt.Sprintf("%s%s%s%s", i.AppId, i.TraceID, i.Timestamp, secretKey))
}
type Response struct {
Code int `json:"code" example:"0" description:"状态码"`
Message string `json:"message,omitempty" example:"操作成功" description:"提示消息"`
//Data interface{} `json:"data,omitempty" description:"数据集"`
}
// ServerHeartbeat 心跳
type ServerHeartbeat struct {
}
// ResponseServerHeartbeat 响应心跳
type ResponseServerHeartbeat struct {
Response
}
// ServerLogin 服务登录
type ServerLogin struct {
Request
Group string
Name string
}
// ResponseServerLogin 响应服务登录
type ResponseServerLogin struct {
Response
}
// ServerOffline 服务离线
type ServerOffline struct {
}
// ResponseServerOffline 响应服务离线
type ResponseServerOffline struct {
Response
}

View File

@@ -114,7 +114,6 @@ type (
)
var (
localAdminPost IAdminPost
localAdminRole IAdminRole
localAdminDept IAdminDept
localAdminMember IAdminMember
@@ -122,41 +121,9 @@ var (
localAdminMenu IAdminMenu
localAdminMonitor IAdminMonitor
localAdminNotice IAdminNotice
localAdminPost IAdminPost
)
func AdminDept() IAdminDept {
if localAdminDept == nil {
panic("implement not found for interface IAdminDept, forgot register?")
}
return localAdminDept
}
func RegisterAdminDept(i IAdminDept) {
localAdminDept = i
}
func AdminMember() IAdminMember {
if localAdminMember == nil {
panic("implement not found for interface IAdminMember, forgot register?")
}
return localAdminMember
}
func RegisterAdminMember(i IAdminMember) {
localAdminMember = 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?")
@@ -211,3 +178,36 @@ func AdminRole() IAdminRole {
func RegisterAdminRole(i IAdminRole) {
localAdminRole = i
}
func AdminDept() IAdminDept {
if localAdminDept == nil {
panic("implement not found for interface IAdminDept, forgot register?")
}
return localAdminDept
}
func RegisterAdminDept(i IAdminDept) {
localAdminDept = i
}
func AdminMember() IAdminMember {
if localAdminMember == nil {
panic("implement not found for interface IAdminMember, forgot register?")
}
return localAdminMember
}
func RegisterAdminMember(i IAdminMember) {
localAdminMember = i
}
func AdminMemberPost() IAdminMemberPost {
if localAdminMemberPost == nil {
panic("implement not found for interface IAdminMemberPost, forgot register?")
}
return localAdminMemberPost
}
func RegisterAdminMemberPost(i IAdminMemberPost) {
localAdminMemberPost = i
}

View File

@@ -17,148 +17,6 @@ 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) error
}
ISysAttachment interface {
Delete(ctx context.Context, in sysin.AttachmentDeleteInp) 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) (*sysin.AttachmentMaxSortModel, 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) (data *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) (*sysin.BlacklistMaxSortModel, 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)
}
ISysEmsLog interface {
Delete(ctx context.Context, in sysin.EmsLogDeleteInp) 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) 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) (*sysin.GenCodesMaxSortModel, 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)
}
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)
}
ISysSmsLog interface {
Delete(ctx context.Context, in sysin.SmsLogDeleteInp) error
Edit(ctx context.Context, in sysin.SmsLogEditInp) (err error)
Status(ctx context.Context, in sysin.SmsLogStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.SmsLogMaxSortInp) (*sysin.SmsLogMaxSortModel, error)
View(ctx context.Context, in sysin.SmsLogViewInp) (res *sysin.SmsLogViewModel, err error)
List(ctx context.Context, in sysin.SmsLogListInp) (list []*sysin.SmsLogListModel, totalCount int, err error)
SendCode(ctx context.Context, in sysin.SendCodeInp) (err error)
GetTemplate(ctx context.Context, template string, config *model.SmsConfig) (val string, err error)
AllowSend(ctx context.Context, models *entity.SysSmsLog, config *model.SmsConfig) (err error)
VerifyCode(ctx context.Context, in sysin.VerifyCodeInp) (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 {
GetLoadCache(ctx context.Context) (conf *model.CacheConfig, err error)
GetLoadGenerate(ctx context.Context) (conf *model.GenerateConfig, 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) (*sysin.GetConfigModel, error)
ConversionType(ctx context.Context, models *entity.SysConfig) (value interface{}, err error)
UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error
}
ISysLog interface {
Export(ctx context.Context, in sysin.LogListInp) (err error)
RealWrite(ctx context.Context, commonLog 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)
}
ISysCronGroup interface {
Delete(ctx context.Context, in sysin.CronGroupDeleteInp) 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) (*sysin.CronGroupMaxSortModel, 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)
Export(ctx context.Context, in sysin.CurdDemoListInp) (err error)
Edit(ctx context.Context, in sysin.CurdDemoEditInp) (err error)
Delete(ctx context.Context, in sysin.CurdDemoDeleteInp) (err error)
MaxSort(ctx context.Context, in sysin.CurdDemoMaxSortInp) (res *sysin.CurdDemoMaxSortModel, err error)
View(ctx context.Context, in sysin.CurdDemoViewInp) (res *sysin.CurdDemoViewModel, err error)
Status(ctx context.Context, in sysin.CurdDemoStatusInp) (err error)
Switch(ctx context.Context, in sysin.CurdDemoSwitchInp) (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)
}
ISysDictType interface {
Tree(ctx context.Context) (list []*sysin.DictTypeTree, err error)
Delete(ctx context.Context, in sysin.DictTypeDeleteInp) error
Edit(ctx context.Context, in sysin.DictTypeEditInp) (err error)
TreeSelect(ctx context.Context, in sysin.DictTreeSelectInp) (list []*sysin.DictTypeTree, err error)
}
ISysProvinces interface {
Tree(ctx context.Context) (list []g.Map, err error)
Delete(ctx context.Context, in sysin.ProvincesDeleteInp) error
@@ -181,28 +39,302 @@ type (
List(ctx context.Context, in sysin.CronListInp) (list []*sysin.CronListModel, totalCount int, err error)
OnlineExec(ctx context.Context, in sysin.OnlineExecInp) (err error)
}
ISysCronGroup interface {
Delete(ctx context.Context, in sysin.CronGroupDeleteInp) 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) (*sysin.CronGroupMaxSortModel, 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)
}
ISysEmsLog interface {
Delete(ctx context.Context, in sysin.EmsLogDeleteInp) 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)
}
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)
}
ISysGenCodes interface {
Delete(ctx context.Context, in sysin.GenCodesDeleteInp) 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) (*sysin.GenCodesMaxSortModel, 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)
}
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) error
}
ISysAttachment interface {
Delete(ctx context.Context, in sysin.AttachmentDeleteInp) 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) (*sysin.AttachmentMaxSortModel, 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) (data *entity.SysAttachment, 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)
}
ISysSmsLog interface {
Delete(ctx context.Context, in sysin.SmsLogDeleteInp) error
Edit(ctx context.Context, in sysin.SmsLogEditInp) (err error)
Status(ctx context.Context, in sysin.SmsLogStatusInp) (err error)
MaxSort(ctx context.Context, in sysin.SmsLogMaxSortInp) (*sysin.SmsLogMaxSortModel, error)
View(ctx context.Context, in sysin.SmsLogViewInp) (res *sysin.SmsLogViewModel, err error)
List(ctx context.Context, in sysin.SmsLogListInp) (list []*sysin.SmsLogListModel, totalCount int, err error)
SendCode(ctx context.Context, in sysin.SendCodeInp) (err error)
GetTemplate(ctx context.Context, template string, config *model.SmsConfig) (val string, err error)
AllowSend(ctx context.Context, models *entity.SysSmsLog, config *model.SmsConfig) (err error)
VerifyCode(ctx context.Context, in sysin.VerifyCodeInp) (err error)
}
ISysDictType interface {
Tree(ctx context.Context) (list []*sysin.DictTypeTree, err error)
Delete(ctx context.Context, in sysin.DictTypeDeleteInp) error
Edit(ctx context.Context, in sysin.DictTypeEditInp) (err error)
TreeSelect(ctx context.Context, in sysin.DictTreeSelectInp) (list []*sysin.DictTypeTree, err error)
}
ISysLog interface {
Export(ctx context.Context, in sysin.LogListInp) (err error)
RealWrite(ctx context.Context, commonLog 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)
}
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) (*sysin.BlacklistMaxSortModel, 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)
}
ISysConfig interface {
GetLoadCache(ctx context.Context) (conf *model.CacheConfig, err error)
GetLoadGenerate(ctx context.Context) (conf *model.GenerateConfig, 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) (*sysin.GetConfigModel, error)
ConversionType(ctx context.Context, models *entity.SysConfig) (value interface{}, err error)
UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) 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)
Export(ctx context.Context, in sysin.CurdDemoListInp) (err error)
Edit(ctx context.Context, in sysin.CurdDemoEditInp) (err error)
Delete(ctx context.Context, in sysin.CurdDemoDeleteInp) (err error)
MaxSort(ctx context.Context, in sysin.CurdDemoMaxSortInp) (res *sysin.CurdDemoMaxSortModel, err error)
View(ctx context.Context, in sysin.CurdDemoViewInp) (res *sysin.CurdDemoViewModel, err error)
Status(ctx context.Context, in sysin.CurdDemoStatusInp) (err error)
Switch(ctx context.Context, in sysin.CurdDemoSwitchInp) (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)
}
)
var (
localSysCron ISysCron
localSysAddonsConfig ISysAddonsConfig
localSysAttachment ISysAttachment
localSysBlacklist ISysBlacklist
localSysEmsLog ISysEmsLog
localSysGenCodes ISysGenCodes
localSysServeLog ISysServeLog
localSysSmsLog ISysSmsLog
localSysAddonsConfig ISysAddonsConfig
localSysBlacklist ISysBlacklist
localSysConfig ISysConfig
localSysLog ISysLog
localSysLoginLog ISysLoginLog
localSysAddons ISysAddons
localSysCurdDemo ISysCurdDemo
localSysDictData ISysDictData
localSysDictType ISysDictType
localSysProvinces ISysProvinces
localSysLog ISysLog
localSysCron ISysCron
localSysCronGroup ISysCronGroup
localSysEmsLog ISysEmsLog
localSysLoginLog ISysLoginLog
localSysProvinces ISysProvinces
localSysAddons ISysAddons
localSysGenCodes ISysGenCodes
)
func SysDictData() ISysDictData {
if localSysDictData == nil {
panic("implement not found for interface ISysDictData, forgot register?")
}
return localSysDictData
}
func RegisterSysDictData(i ISysDictData) {
localSysDictData = i
}
func SysDictType() ISysDictType {
if localSysDictType == nil {
panic("implement not found for interface ISysDictType, forgot register?")
}
return localSysDictType
}
func RegisterSysDictType(i ISysDictType) {
localSysDictType = i
}
func SysLog() ISysLog {
if localSysLog == nil {
panic("implement not found for interface ISysLog, forgot register?")
}
return localSysLog
}
func RegisterSysLog(i ISysLog) {
localSysLog = 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 SysConfig() ISysConfig {
if localSysConfig == nil {
panic("implement not found for interface ISysConfig, forgot register?")
}
return localSysConfig
}
func RegisterSysConfig(i ISysConfig) {
localSysConfig = i
}
func SysCurdDemo() ISysCurdDemo {
if localSysCurdDemo == nil {
panic("implement not found for interface ISysCurdDemo, forgot register?")
}
return localSysCurdDemo
}
func RegisterSysCurdDemo(i ISysCurdDemo) {
localSysCurdDemo = i
}
func SysLoginLog() ISysLoginLog {
if localSysLoginLog == nil {
panic("implement not found for interface ISysLoginLog, forgot register?")
}
return localSysLoginLog
}
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 SysCron() ISysCron {
if localSysCron == nil {
panic("implement not found for interface ISysCron, forgot register?")
}
return localSysCron
}
func RegisterSysCron(i ISysCron) {
localSysCron = i
}
func SysCronGroup() ISysCronGroup {
if localSysCronGroup == nil {
panic("implement not found for interface ISysCronGroup, forgot register?")
}
return localSysCronGroup
}
func RegisterSysCronGroup(i ISysCronGroup) {
localSysCronGroup = 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 SysAddons() ISysAddons {
if localSysAddons == nil {
panic("implement not found for interface ISysAddons, forgot register?")
}
return localSysAddons
}
func RegisterSysAddons(i ISysAddons) {
localSysAddons = i
}
func SysGenCodes() ISysGenCodes {
if localSysGenCodes == nil {
panic("implement not found for interface ISysGenCodes, forgot register?")
@@ -214,17 +346,6 @@ func RegisterSysGenCodes(i ISysGenCodes) {
localSysGenCodes = 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 SysSmsLog() ISysSmsLog {
if localSysSmsLog == nil {
panic("implement not found for interface ISysSmsLog, forgot register?")
@@ -258,134 +379,13 @@ func RegisterSysAttachment(i ISysAttachment) {
localSysAttachment = i
}
func SysBlacklist() ISysBlacklist {
if localSysBlacklist == nil {
panic("implement not found for interface ISysBlacklist, forgot register?")
func SysServeLog() ISysServeLog {
if localSysServeLog == nil {
panic("implement not found for interface ISysServeLog, forgot register?")
}
return localSysBlacklist
return localSysServeLog
}
func RegisterSysBlacklist(i ISysBlacklist) {
localSysBlacklist = 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 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 SysLog() ISysLog {
if localSysLog == nil {
panic("implement not found for interface ISysLog, forgot register?")
}
return localSysLog
}
func RegisterSysLog(i ISysLog) {
localSysLog = i
}
func SysLoginLog() ISysLoginLog {
if localSysLoginLog == nil {
panic("implement not found for interface ISysLoginLog, forgot register?")
}
return localSysLoginLog
}
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 SysCronGroup() ISysCronGroup {
if localSysCronGroup == nil {
panic("implement not found for interface ISysCronGroup, forgot register?")
}
return localSysCronGroup
}
func RegisterSysCronGroup(i ISysCronGroup) {
localSysCronGroup = i
}
func SysCurdDemo() ISysCurdDemo {
if localSysCurdDemo == nil {
panic("implement not found for interface ISysCurdDemo, forgot register?")
}
return localSysCurdDemo
}
func RegisterSysCurdDemo(i ISysCurdDemo) {
localSysCurdDemo = i
}
func SysDictData() ISysDictData {
if localSysDictData == nil {
panic("implement not found for interface ISysDictData, forgot register?")
}
return localSysDictData
}
func RegisterSysDictData(i ISysDictData) {
localSysDictData = i
}
func SysDictType() ISysDictType {
if localSysDictType == nil {
panic("implement not found for interface ISysDictType, forgot register?")
}
return localSysDictType
}
func RegisterSysDictType(i ISysDictType) {
localSysDictType = 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 RegisterSysServeLog(i ISysServeLog) {
localSysServeLog = i
}

View File

@@ -0,0 +1,32 @@
// ================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
)
type (
ITCPAuth interface {
Start(ctx context.Context)
Stop(ctx context.Context)
}
)
var (
localTCPAuth ITCPAuth
)
func TCPAuth() ITCPAuth {
if localTCPAuth == nil {
panic("implement not found for interface ITCPAuth, forgot register?")
}
return localTCPAuth
}
func RegisterTCPAuth(i ITCPAuth) {
localTCPAuth = i
}

View File

@@ -0,0 +1,32 @@
// ================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
)
type (
ITCPServer interface {
Start(ctx context.Context)
Stop(ctx context.Context)
}
)
var (
localTCPServer ITCPServer
)
func TCPServer() ITCPServer {
if localTCPServer == nil {
panic("implement not found for interface ITCPServer, forgot register?")
}
return localTCPServer
}
func RegisterTCPServer(i ITCPServer) {
localTCPServer = i
}