mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-08-26 16:46:14 +08:00
更新2.1.2版本,优化部门、角色权限,增加上下级关系;增加登录、系统、短信日志;优化省市区编码
This commit is contained in:
@@ -44,6 +44,7 @@ var (
|
||||
group.Middleware(
|
||||
service.Middleware().Ctx, //必须第一个加载
|
||||
service.Middleware().CORS,
|
||||
service.Middleware().Blacklist,
|
||||
service.Middleware().DemoLimit,
|
||||
service.Middleware().ResponseHandler,
|
||||
)
|
||||
|
@@ -8,6 +8,9 @@ package consts
|
||||
|
||||
import "github.com/gogf/gf/v2/util/gconv"
|
||||
|
||||
// RequestEncryptKey 请求加密密钥用于敏感数据加密,16位字符,前后端需保持一致。安全起见请修改此值
|
||||
var RequestEncryptKey = []byte("f080a463654b2279")
|
||||
|
||||
// 配置数据类型
|
||||
const (
|
||||
ConfigTypeString = "string"
|
||||
|
@@ -8,5 +8,6 @@ package consts
|
||||
|
||||
// ContextKey 上下文
|
||||
const (
|
||||
ContextKey = "HotGoContext"
|
||||
ContextKey = "HotGoContext" // http上下文变量名称
|
||||
ContextKeyCronArgs = "args" // 定时任务参数上下文变量名称
|
||||
)
|
||||
|
@@ -9,10 +9,9 @@ package consts
|
||||
// 定时任务
|
||||
|
||||
const (
|
||||
CronArgsKey = "args" // 上下文变量名称
|
||||
CronSplitStr = "," // 变量分割符
|
||||
CronPolicySame = 1 // 并行策略
|
||||
CronPolicySingle = 2 // 单例策略
|
||||
CronPolicyOnce = 3 // 单次策略
|
||||
CronPolicyTimes = 4 // 多次策略
|
||||
CronSplitStr = "," // 变量分割符
|
||||
CronPolicySame = 1 // 并行策略
|
||||
CronPolicySingle = 2 // 单例策略
|
||||
CronPolicyOnce = 3 // 单次策略
|
||||
CronPolicyTimes = 4 // 多次策略
|
||||
)
|
||||
|
@@ -8,7 +8,7 @@ package consts
|
||||
|
||||
// 消息队列
|
||||
const (
|
||||
QueueName = `queue:`
|
||||
QueueLogPath = "queue" // 需要在config中配置queue的log
|
||||
QueueLogTopic = `request_log`
|
||||
QueueLogTopic = `request_log` // 访问日志
|
||||
QueueLoginLogTopic = `login_log` // 登录日志
|
||||
QueueServeLogTopic = `serve_log` // 服务日志
|
||||
)
|
||||
|
24
server/internal/consts/sms.go
Normal file
24
server/internal/consts/sms.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package consts
|
||||
|
||||
// 短信驱动
|
||||
|
||||
const (
|
||||
SmsDriveAliYun = "aliyun" // 阿里云
|
||||
SmsDriveTencent = "tencent" // 腾讯云
|
||||
)
|
||||
|
||||
// 短信内置模板
|
||||
const (
|
||||
SmsTemplateCode = "code" // 通用验证码
|
||||
SmsTemplateLogin = "login" // 登录
|
||||
SmsTemplateRegister = "register" // 注册
|
||||
SmsTemplateResetPwd = "resetPwd" // 重置密码
|
||||
SmsTemplateBind = "bind" // 绑定手机号
|
||||
SmsTemplateCash = "cash" // 申请提现
|
||||
)
|
||||
|
||||
// 短信状态码
|
||||
const (
|
||||
SmsStatusNotUsed = 1 // 未使用
|
||||
SmsStatusUsed = 2 // 已使用
|
||||
)
|
@@ -8,5 +8,5 @@ package consts
|
||||
|
||||
// VersionApp HotGo版本
|
||||
const (
|
||||
VersionApp = "2.1.1"
|
||||
VersionApp = "2.1.2"
|
||||
)
|
||||
|
@@ -204,14 +204,14 @@ func (c *cMember) View(ctx context.Context, req *member.ViewReq) (*member.ViewRe
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roleList, _, err := service.AdminRole().List(ctx, adminin.RoleListInp{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//roleList, _, err := service.AdminRole().List(ctx, adminin.RoleListInp{})
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
var res member.ViewRes
|
||||
res.Posts = postsList
|
||||
res.Roles = roleList
|
||||
//res.Roles = roleList
|
||||
|
||||
if req.Id <= 0 {
|
||||
return &res, err
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"hotgo/api/backend/monitor"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/model/input/form"
|
||||
@@ -46,9 +47,7 @@ func (c *cMonitor) Offline(ctx context.Context, req *monitor.OfflineReq) (res *m
|
||||
|
||||
// View 获取指定信息
|
||||
func (c *cMonitor) View(ctx context.Context, req *monitor.OnlineViewReq) (*monitor.OnlineViewRes, error) {
|
||||
var res monitor.OnlineViewRes
|
||||
// ...
|
||||
return &res, nil
|
||||
return &monitor.OnlineViewRes{}, nil
|
||||
}
|
||||
|
||||
// OnlineList 获取在线列表
|
||||
@@ -63,26 +62,31 @@ func (c *cMonitor) OnlineList(ctx context.Context, req *monitor.OnlineListReq) (
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
for c, _ := range c.wsManager.GetClients() {
|
||||
if c.SendClose || c.User == nil {
|
||||
for conn, _ := range c.wsManager.GetClients() {
|
||||
if conn.SendClose || conn.User == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if req.UserId > 0 && req.UserId != c.User.Id {
|
||||
if req.UserId > 0 && req.UserId != conn.User.Id {
|
||||
continue
|
||||
}
|
||||
|
||||
if req.Addr != "" && !gstr.Contains(conn.Addr, req.Addr) {
|
||||
continue
|
||||
}
|
||||
|
||||
clients = append(clients, &monitor.OnlineModel{
|
||||
ID: c.ID,
|
||||
Addr: c.Addr,
|
||||
Os: useragent.GetOs(c.UserAgent),
|
||||
Browser: useragent.GetBrowser(c.UserAgent),
|
||||
FirstTime: c.FirstTime,
|
||||
HeartbeatTime: c.HeartbeatTime,
|
||||
App: c.User.App,
|
||||
UserId: c.User.Id,
|
||||
Username: c.User.Username,
|
||||
Avatar: c.User.Avatar,
|
||||
ExpTime: c.User.Exp,
|
||||
ID: conn.ID,
|
||||
Addr: conn.Addr,
|
||||
Os: useragent.GetOs(conn.UserAgent),
|
||||
Browser: useragent.GetBrowser(conn.UserAgent),
|
||||
FirstTime: conn.FirstTime,
|
||||
HeartbeatTime: conn.HeartbeatTime,
|
||||
App: conn.User.App,
|
||||
UserId: conn.User.Id,
|
||||
Username: conn.User.Username,
|
||||
Avatar: conn.User.Avatar,
|
||||
ExpTime: conn.User.Exp,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -96,11 +100,11 @@ func (c *cMonitor) OnlineList(ctx context.Context, req *monitor.OnlineListReq) (
|
||||
|
||||
for k, v := range clients {
|
||||
if k >= offset && i <= perPage {
|
||||
i++
|
||||
if isDemo.Bool() {
|
||||
v.Addr = consts.DemoTips
|
||||
}
|
||||
res.List = append(res.List, v)
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,7 @@ import (
|
||||
"hotgo/internal/library/captcha"
|
||||
"hotgo/internal/library/jwt"
|
||||
"hotgo/internal/model/input/adminin"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
@@ -60,28 +61,32 @@ func (c *cSite) getWsAddr(ctx context.Context) string {
|
||||
|
||||
// Captcha 登录验证码
|
||||
func (c *cSite) Captcha(ctx context.Context, req *common.LoginCaptchaReq) (res *common.LoginCaptchaRes, err error) {
|
||||
|
||||
// 获取生成的验证码图片
|
||||
Cid, Base64 := captcha.GetVerifyImgString(ctx)
|
||||
res = &common.LoginCaptchaRes{Cid: Cid, Base64: Base64}
|
||||
|
||||
cid, base64 := captcha.Generate(ctx)
|
||||
res = &common.LoginCaptchaRes{Cid: cid, Base64: base64}
|
||||
return
|
||||
}
|
||||
|
||||
// Login 提交登录
|
||||
func (c *cSite) Login(ctx context.Context, req *common.LoginReq) (res *common.LoginRes, err error) {
|
||||
|
||||
//// 校验 验证码
|
||||
//if !captcha.VerifyString(req.Cid, req.Code) {
|
||||
// err = gerror.New("验证码错误")
|
||||
// return
|
||||
//}
|
||||
//
|
||||
var in adminin.MemberLoginInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
var response = new(adminin.MemberLoginModel)
|
||||
if res != nil && res.MemberLoginModel != nil {
|
||||
response = res.MemberLoginModel
|
||||
}
|
||||
service.SysLoginLog().Push(ctx, sysin.LoginLogPushInp{Input: in, Response: response, Err: err})
|
||||
}()
|
||||
|
||||
// 校验 验证码
|
||||
if !req.IsLock && !captcha.Verify(req.Cid, req.Code) {
|
||||
err = gerror.New("验证码错误")
|
||||
return
|
||||
}
|
||||
|
||||
model, err := service.AdminMember().Login(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
37
server/internal/controller/backend/common/sms.go
Normal file
37
server/internal/controller/backend/common/sms.go
Normal file
@@ -0,0 +1,37 @@
|
||||
// Package common
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/backend/common"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/validate"
|
||||
)
|
||||
|
||||
var Sms = new(cSms)
|
||||
|
||||
type cSms struct{}
|
||||
|
||||
// SendTest 发送测试短信
|
||||
func (c *cSms) SendTest(ctx context.Context, req *common.SendTestSmsReq) (res *common.SendTestSmsRes, err error) {
|
||||
var in sysin.SendCodeInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysSmsLog().SendCode(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
@@ -8,6 +8,7 @@ package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/backend/cron"
|
||||
"hotgo/internal/model/input/form"
|
||||
@@ -111,3 +112,17 @@ func (c *cCron) Status(ctx context.Context, req *cron.StatusReq) (res *cron.Stat
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// OnlineExec 在线执行
|
||||
func (c *cCron) OnlineExec(ctx context.Context, req *cron.OnlineExecReq) (res *cron.OnlineExecRes, err error) {
|
||||
if req.Id <= 0 {
|
||||
return nil, gerror.New("定时任务ID不能为空")
|
||||
}
|
||||
|
||||
var in sysin.OnlineExecInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, service.SysCron().OnlineExec(ctx, in)
|
||||
}
|
||||
|
@@ -40,7 +40,7 @@ func (c *sLog) Export(ctx context.Context, req *log.ExportReq) (res *log.ExportR
|
||||
return
|
||||
}
|
||||
|
||||
// List 获取全局日志列表
|
||||
// List 获取访问日志列表
|
||||
func (c *sLog) List(ctx context.Context, req *log.ListReq) (*log.ListRes, error) {
|
||||
var (
|
||||
in sysin.LogListInp
|
||||
|
104
server/internal/controller/backend/sys/login_log.go
Normal file
104
server/internal/controller/backend/sys/login_log.go
Normal file
@@ -0,0 +1,104 @@
|
||||
// Package sys
|
||||
// @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
|
||||
// @AutoGenerate Version 2.1.1
|
||||
// @AutoGenerate Date 2023-01-19 16:57:33
|
||||
//
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/backend/loginlog"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/validate"
|
||||
)
|
||||
|
||||
var (
|
||||
LoginLog = cLoginLog{}
|
||||
)
|
||||
|
||||
type cLoginLog struct{}
|
||||
|
||||
// List 查看登录日志列表
|
||||
func (c *cLoginLog) List(ctx context.Context, req *loginlog.ListReq) (res *loginlog.ListRes, err error) {
|
||||
var in sysin.LoginLogListInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, totalCount, err := service.SysLoginLog().List(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(loginlog.ListRes)
|
||||
res.List = list
|
||||
res.PageCount = form.CalPageCount(totalCount, req.PerPage)
|
||||
res.Page = req.Page
|
||||
res.PerPage = req.PerPage
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Export 导出登录日志列表
|
||||
func (c *cLoginLog) Export(ctx context.Context, req *loginlog.ExportReq) (res *loginlog.ExportRes, err error) {
|
||||
var in sysin.LoginLogListInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysLoginLog().Export(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// View 获取指定登录日志信息
|
||||
func (c *cLoginLog) View(ctx context.Context, req *loginlog.ViewReq) (res *loginlog.ViewRes, err error) {
|
||||
var in sysin.LoginLogViewInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := service.SysLoginLog().View(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(loginlog.ViewRes)
|
||||
res.LoginLogViewModel = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Delete 删除登录日志
|
||||
func (c *cLoginLog) Delete(ctx context.Context, req *loginlog.DeleteReq) (res *loginlog.DeleteRes, err error) {
|
||||
var in sysin.LoginLogDeleteInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysLoginLog().Delete(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
@@ -21,6 +21,20 @@ var (
|
||||
|
||||
type cProvinces struct{}
|
||||
|
||||
// Tree 关系树选项列表
|
||||
func (c *cProvinces) Tree(ctx context.Context, req *provinces.TreeReq) (*provinces.TreeRes, error) {
|
||||
var (
|
||||
res provinces.TreeRes
|
||||
err error
|
||||
)
|
||||
res.List, err = service.SysProvinces().Tree(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Delete 删除
|
||||
func (c *cProvinces) Delete(ctx context.Context, req *provinces.DeleteReq) (res *provinces.DeleteRes, err error) {
|
||||
var in sysin.ProvincesDeleteInp
|
||||
@@ -47,15 +61,15 @@ func (c *cProvinces) Edit(ctx context.Context, req *provinces.EditReq) (res *pro
|
||||
}
|
||||
|
||||
// MaxSort 最大排序
|
||||
func (c *cProvinces) MaxSort(ctx context.Context, req *provinces.MaxSortReq) (*provinces.MaxSortRes, error) {
|
||||
data, err := service.SysProvinces().MaxSort(ctx, sysin.ProvincesMaxSortInp{Id: req.Id})
|
||||
func (c *cProvinces) MaxSort(ctx context.Context, req *provinces.MaxSortReq) (res *provinces.MaxSortRes, err error) {
|
||||
data, err := service.SysProvinces().MaxSort(ctx, sysin.ProvincesMaxSortInp{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res provinces.MaxSortRes
|
||||
res.Sort = data.Sort
|
||||
return &res, nil
|
||||
res = new(provinces.MaxSortRes)
|
||||
res.ProvincesMaxSortModel = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// View 获取指定信息
|
||||
@@ -104,3 +118,44 @@ func (c *cProvinces) Status(ctx context.Context, req *provinces.StatusReq) (res
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ChildrenList 获取省市区下级列表
|
||||
func (c *cProvinces) ChildrenList(ctx context.Context, req *provinces.ChildrenListReq) (*provinces.ChildrenListRes, error) {
|
||||
var (
|
||||
in sysin.ProvincesChildrenListInp
|
||||
res provinces.ChildrenListRes
|
||||
)
|
||||
|
||||
if err := gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list, totalCount, err := service.SysProvinces().ChildrenList(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.List = list
|
||||
res.PageCount = form.CalPageCount(totalCount, req.PerPage)
|
||||
res.Page = req.Page
|
||||
res.PerPage = req.PerPage
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// UniqueId 地区ID是否唯一
|
||||
func (c *cProvinces) UniqueId(ctx context.Context, req *provinces.UniqueIdReq) (res *provinces.UniqueIdRes, err error) {
|
||||
var in sysin.ProvincesUniqueIdInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := service.SysProvinces().UniqueId(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(provinces.UniqueIdRes)
|
||||
res.ProvincesUniqueIdModel = data
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
102
server/internal/controller/backend/sys/serve_log.go
Normal file
102
server/internal/controller/backend/sys/serve_log.go
Normal file
@@ -0,0 +1,102 @@
|
||||
// Package sys
|
||||
// @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 sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/backend/servelog"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/validate"
|
||||
)
|
||||
|
||||
var (
|
||||
ServeLog = cServeLog{}
|
||||
)
|
||||
|
||||
type cServeLog struct{}
|
||||
|
||||
// List 查看服务日志列表
|
||||
func (c *cServeLog) List(ctx context.Context, req *servelog.ListReq) (res *servelog.ListRes, err error) {
|
||||
var in sysin.ServeLogListInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, totalCount, err := service.SysServeLog().List(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(servelog.ListRes)
|
||||
res.List = list
|
||||
res.PageCount = form.CalPageCount(totalCount, req.PerPage)
|
||||
res.Page = req.Page
|
||||
res.PerPage = req.PerPage
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Export 导出服务日志列表
|
||||
func (c *cServeLog) Export(ctx context.Context, req *servelog.ExportReq) (res *servelog.ExportRes, err error) {
|
||||
var in sysin.ServeLogListInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysServeLog().Export(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// View 获取指定服务日志信息
|
||||
func (c *cServeLog) View(ctx context.Context, req *servelog.ViewReq) (res *servelog.ViewRes, err error) {
|
||||
var in sysin.ServeLogViewInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := service.SysServeLog().View(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = new(servelog.ViewRes)
|
||||
res.ServeLogViewModel = data
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Delete 删除服务日志
|
||||
func (c *cServeLog) Delete(ctx context.Context, req *servelog.DeleteReq) (res *servelog.DeleteRes, err error) {
|
||||
var in sysin.ServeLogDeleteInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validate.PreFilter(ctx, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = service.SysServeLog().Delete(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
113
server/internal/controller/backend/sys/sms_log.go
Normal file
113
server/internal/controller/backend/sys/sms_log.go
Normal file
@@ -0,0 +1,113 @@
|
||||
// Package sys
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/backend/smslog"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var (
|
||||
SmsLog = cSmsLog{}
|
||||
)
|
||||
|
||||
type cSmsLog struct{}
|
||||
|
||||
// Delete 删除
|
||||
func (c *cSmsLog) Delete(ctx context.Context, req *smslog.DeleteReq) (res *smslog.DeleteRes, err error) {
|
||||
var in sysin.SmsLogDeleteInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = service.SysSmsLog().Delete(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Edit 更新
|
||||
func (c *cSmsLog) Edit(ctx context.Context, req *smslog.EditReq) (res *smslog.EditRes, err error) {
|
||||
|
||||
var in sysin.SmsLogEditInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = service.SysSmsLog().Edit(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// MaxSort 最大排序
|
||||
func (c *cSmsLog) MaxSort(ctx context.Context, req *smslog.MaxSortReq) (*smslog.MaxSortRes, error) {
|
||||
|
||||
data, err := service.SysSmsLog().MaxSort(ctx, sysin.SmsLogMaxSortInp{Id: req.Id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res smslog.MaxSortRes
|
||||
res.Sort = data.Sort
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// View 获取指定信息
|
||||
func (c *cSmsLog) View(ctx context.Context, req *smslog.ViewReq) (*smslog.ViewRes, error) {
|
||||
|
||||
data, err := service.SysSmsLog().View(ctx, sysin.SmsLogViewInp{Id: req.Id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res smslog.ViewRes
|
||||
res.SmsLogViewModel = data
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// List 查看列表
|
||||
func (c *cSmsLog) List(ctx context.Context, req *smslog.ListReq) (*smslog.ListRes, error) {
|
||||
|
||||
var (
|
||||
in sysin.SmsLogListInp
|
||||
res smslog.ListRes
|
||||
)
|
||||
|
||||
if err := gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, totalCount, err := service.SysSmsLog().List(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.List = list
|
||||
res.PageCount = form.CalPageCount(totalCount, req.PerPage)
|
||||
res.Page = req.Page
|
||||
res.PerPage = req.PerPage
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Status 更新部门状态
|
||||
func (c *cSmsLog) Status(ctx context.Context, req *smslog.StatusReq) (res *smslog.StatusRes, err error) {
|
||||
|
||||
var in sysin.SmsLogStatusInp
|
||||
if err = gconv.Scan(req, &in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = service.SysSmsLog().Status(ctx, in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
@@ -20,21 +20,17 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// 添加新的任务时,只需实现cronStrategy接口,并加入到cronList即可
|
||||
cronList = []cronStrategy{
|
||||
Test, // 测试无参任务
|
||||
Test2, // 测试有参任务
|
||||
Monitor, // 监控
|
||||
}
|
||||
inst = new(tasks)
|
||||
)
|
||||
|
||||
type cronStrategy interface {
|
||||
GetName() string
|
||||
Execute(ctx context.Context)
|
||||
}
|
||||
|
||||
var (
|
||||
// 添加新的任务时,只需实现cronStrategy接口,并加入到cronList即可
|
||||
cronList []cronStrategy
|
||||
inst = new(tasks)
|
||||
)
|
||||
|
||||
type tasks struct {
|
||||
list []*TaskItem
|
||||
sync.RWMutex
|
||||
@@ -49,7 +45,7 @@ type TaskItem struct {
|
||||
Count int // 执行次数,仅Policy=4时有效
|
||||
}
|
||||
|
||||
func init() {
|
||||
func LoadCronList() {
|
||||
for _, cron := range cronList {
|
||||
inst.Add(&TaskItem{
|
||||
Name: cron.GetName(),
|
||||
@@ -66,6 +62,10 @@ func StopALL() {
|
||||
|
||||
// StartALL 启动任务
|
||||
func StartALL(sysCron []*entity.SysCron) error {
|
||||
if len(inst.list) == 0 {
|
||||
LoadCronList()
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
ct = gctx.New()
|
||||
@@ -86,7 +86,7 @@ func StartALL(sysCron []*entity.SysCron) error {
|
||||
if gcron.Search(cron.Name) == nil {
|
||||
var (
|
||||
t *gcron.Entry
|
||||
ctx = context.WithValue(gctx.New(), consts.CronArgsKey, strings.Split(cron.Params, consts.CronSplitStr))
|
||||
ctx = context.WithValue(gctx.New(), consts.ContextKeyCronArgs, strings.Split(cron.Params, consts.CronSplitStr))
|
||||
)
|
||||
switch cron.Policy {
|
||||
case consts.CronPolicySame:
|
||||
@@ -130,7 +130,7 @@ func StartALL(sysCron []*entity.SysCron) error {
|
||||
}
|
||||
}
|
||||
|
||||
g.Log().Debug(ct, "load scheduled task complete..")
|
||||
g.Log().Debug(ct, "load cron success..")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -140,8 +140,15 @@ func Stop(sysCron *entity.SysCron) error {
|
||||
}
|
||||
|
||||
// Once 立即执行一次某个任务
|
||||
func Once(sysCron *entity.SysCron) error {
|
||||
return nil
|
||||
func Once(ctx context.Context, sysCron *entity.SysCron) error {
|
||||
for _, v := range cronList {
|
||||
if v.GetName() == sysCron.Name {
|
||||
go v.Execute(ctx)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return gerror.Newf("定时任务不存在:%+v", sysCron.Name)
|
||||
}
|
||||
|
||||
// Delete 删除任务
|
||||
|
@@ -18,6 +18,10 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cronList = append(cronList, Monitor)
|
||||
}
|
||||
|
||||
// Monitor 监控
|
||||
var Monitor = &cMonitor{name: "monitor"}
|
||||
|
||||
|
@@ -12,6 +12,10 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cronList = append(cronList, Test)
|
||||
}
|
||||
|
||||
// Test 测试任务
|
||||
var Test = &cTest{name: "test"}
|
||||
|
||||
|
@@ -13,6 +13,10 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cronList = append(cronList, Test2)
|
||||
}
|
||||
|
||||
// Test2 测试2任务
|
||||
var Test2 = &cTest2{name: "test2"}
|
||||
|
||||
@@ -26,7 +30,7 @@ func (c *cTest2) GetName() string {
|
||||
|
||||
// Execute 执行任务
|
||||
func (c *cTest2) Execute(ctx context.Context) {
|
||||
args, ok := ctx.Value(consts.CronArgsKey).([]string)
|
||||
args, ok := ctx.Value(consts.ContextKeyCronArgs).([]string)
|
||||
if !ok {
|
||||
g.Log().Warning(ctx, "参数解析失败!")
|
||||
return
|
||||
|
@@ -28,6 +28,8 @@ type AdminDeptColumns struct {
|
||||
Leader string // 负责人
|
||||
Phone string // 联系电话
|
||||
Email string // 邮箱
|
||||
Level string // 关系树等级
|
||||
Tree string // 关系树
|
||||
Sort string // 排序
|
||||
Status string // 部门状态
|
||||
CreatedAt string // 创建时间
|
||||
@@ -44,6 +46,8 @@ var adminDeptColumns = AdminDeptColumns{
|
||||
Leader: "leader",
|
||||
Phone: "phone",
|
||||
Email: "email",
|
||||
Level: "level",
|
||||
Tree: "tree",
|
||||
Sort: "sort",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
|
@@ -1,143 +0,0 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// DemoDao is the data access object for table hg_demo.
|
||||
type DemoDao 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 DemoColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// DemoColumns defines and stores column names for table hg_demo.
|
||||
type DemoColumns struct {
|
||||
Id string // ID
|
||||
CategoryId string // 分类ID
|
||||
Flag string // 标签
|
||||
Title string // 标题
|
||||
Description string // 描述
|
||||
Content string // 内容
|
||||
Image string // 单图
|
||||
Images string // 多图
|
||||
Attachfile string // 附件
|
||||
Attachfiles string // 多附件
|
||||
Map string // 动态键值对
|
||||
Star string // 推荐星
|
||||
Price string // 价格
|
||||
Views string // 浏览次数
|
||||
ActivityAt string // 活动时间
|
||||
StartAt string // 开启时间
|
||||
EndAt string // 结束时间
|
||||
Switch string // 开关
|
||||
Sort string // 排序
|
||||
Avatar string // 头像
|
||||
Sex string // 性别
|
||||
Qq string // qq
|
||||
Email string // 邮箱
|
||||
Mobile string // 手机号码
|
||||
Hobby string // 爱好
|
||||
Channel string // 渠道
|
||||
Pid string // 上级ID
|
||||
Level string // 树等级
|
||||
Tree string // 关系树
|
||||
Remark string // 备注
|
||||
Status string // 状态
|
||||
CreatedBy string // 创建者
|
||||
UpdatedBy string // 更新者
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 修改时间
|
||||
DeletedAt string // 删除时间
|
||||
}
|
||||
|
||||
// demoColumns holds the columns for table hg_demo.
|
||||
var demoColumns = DemoColumns{
|
||||
Id: "id",
|
||||
CategoryId: "category_id",
|
||||
Flag: "flag",
|
||||
Title: "title",
|
||||
Description: "description",
|
||||
Content: "content",
|
||||
Image: "image",
|
||||
Images: "images",
|
||||
Attachfile: "attachfile",
|
||||
Attachfiles: "attachfiles",
|
||||
Map: "map",
|
||||
Star: "star",
|
||||
Price: "price",
|
||||
Views: "views",
|
||||
ActivityAt: "activity_at",
|
||||
StartAt: "start_at",
|
||||
EndAt: "end_at",
|
||||
Switch: "switch",
|
||||
Sort: "sort",
|
||||
Avatar: "avatar",
|
||||
Sex: "sex",
|
||||
Qq: "qq",
|
||||
Email: "email",
|
||||
Mobile: "mobile",
|
||||
Hobby: "hobby",
|
||||
Channel: "channel",
|
||||
Pid: "pid",
|
||||
Level: "level",
|
||||
Tree: "tree",
|
||||
Remark: "remark",
|
||||
Status: "status",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedBy: "updated_by",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewDemoDao creates and returns a new DAO object for table data access.
|
||||
func NewDemoDao() *DemoDao {
|
||||
return &DemoDao{
|
||||
group: "default",
|
||||
table: "hg_demo",
|
||||
columns: demoColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *DemoDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *DemoDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *DemoDao) Columns() DemoColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *DemoDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *DemoDao) 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 *DemoDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
@@ -21,6 +21,7 @@ type SysLogDao struct {
|
||||
// SysLogColumns defines and stores column names for table hg_sys_log.
|
||||
type SysLogColumns struct {
|
||||
Id string // 日志ID
|
||||
ReqId string // 对外ID
|
||||
AppId string // 应用ID
|
||||
MerchantId string // 商户ID
|
||||
MemberId string // 用户ID
|
||||
@@ -36,10 +37,9 @@ type SysLogColumns struct {
|
||||
ErrorCode string // 报错code
|
||||
ErrorMsg string // 报错信息
|
||||
ErrorData string // 报错日志
|
||||
ReqId string // 对外ID
|
||||
Timestamp string // 响应时间
|
||||
UserAgent string // UA信息
|
||||
TakeUpTime string // 请求耗时
|
||||
Timestamp string // 响应时间
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 修改时间
|
||||
@@ -48,6 +48,7 @@ type SysLogColumns struct {
|
||||
// sysLogColumns holds the columns for table hg_sys_log.
|
||||
var sysLogColumns = SysLogColumns{
|
||||
Id: "id",
|
||||
ReqId: "req_id",
|
||||
AppId: "app_id",
|
||||
MerchantId: "merchant_id",
|
||||
MemberId: "member_id",
|
||||
@@ -63,10 +64,9 @@ var sysLogColumns = SysLogColumns{
|
||||
ErrorCode: "error_code",
|
||||
ErrorMsg: "error_msg",
|
||||
ErrorData: "error_data",
|
||||
ReqId: "req_id",
|
||||
Timestamp: "timestamp",
|
||||
UserAgent: "user_agent",
|
||||
TakeUpTime: "take_up_time",
|
||||
Timestamp: "timestamp",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
|
91
server/internal/dao/internal/sys_login_log.go
Normal file
91
server/internal/dao/internal/sys_login_log.go
Normal file
@@ -0,0 +1,91 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// SysLoginLogDao is the data access object for table hg_sys_login_log.
|
||||
type SysLoginLogDao 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 SysLoginLogColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// SysLoginLogColumns defines and stores column names for table hg_sys_login_log.
|
||||
type SysLoginLogColumns struct {
|
||||
Id string // 日志ID
|
||||
ReqId string // 请求ID
|
||||
MemberId string // 用户ID
|
||||
Username string // 用户名
|
||||
Response string // 响应数据
|
||||
LoginAt string // 登录时间
|
||||
ErrMsg string // 错误提示
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 修改时间
|
||||
}
|
||||
|
||||
// sysLoginLogColumns holds the columns for table hg_sys_login_log.
|
||||
var sysLoginLogColumns = SysLoginLogColumns{
|
||||
Id: "id",
|
||||
ReqId: "req_id",
|
||||
MemberId: "member_id",
|
||||
Username: "username",
|
||||
Response: "response",
|
||||
LoginAt: "login_at",
|
||||
ErrMsg: "err_msg",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewSysLoginLogDao creates and returns a new DAO object for table data access.
|
||||
func NewSysLoginLogDao() *SysLoginLogDao {
|
||||
return &SysLoginLogDao{
|
||||
group: "default",
|
||||
table: "hg_sys_login_log",
|
||||
columns: sysLoginLogColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *SysLoginLogDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *SysLoginLogDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *SysLoginLogDao) Columns() SysLoginLogColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *SysLoginLogDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *SysLoginLogDao) 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 *SysLoginLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
@@ -20,40 +20,34 @@ type SysProvincesDao struct {
|
||||
|
||||
// SysProvincesColumns defines and stores column names for table hg_sys_provinces.
|
||||
type SysProvincesColumns struct {
|
||||
Id string // 省市区ID
|
||||
Title string // 栏目名称
|
||||
ShortTitle string // 缩写
|
||||
Areacode string // 区域编码
|
||||
Zipcode string // 邮政编码
|
||||
Pinyin string // 拼音
|
||||
Lng string // 经度
|
||||
Lat string // 纬度
|
||||
Pid string // 父栏目
|
||||
Level string // 关系树等级
|
||||
Tree string // 关系
|
||||
Sort string // 排序
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
Id string // 省市区ID
|
||||
Title string // 栏目名称
|
||||
Pinyin string // 拼音
|
||||
Lng string // 经度
|
||||
Lat string // 纬度
|
||||
Pid string // 父栏目
|
||||
Level string // 关系树等级
|
||||
Tree string // 关系
|
||||
Sort string // 排序
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysProvincesColumns holds the columns for table hg_sys_provinces.
|
||||
var sysProvincesColumns = SysProvincesColumns{
|
||||
Id: "id",
|
||||
Title: "title",
|
||||
ShortTitle: "short_title",
|
||||
Areacode: "areacode",
|
||||
Zipcode: "zipcode",
|
||||
Pinyin: "pinyin",
|
||||
Lng: "lng",
|
||||
Lat: "lat",
|
||||
Pid: "pid",
|
||||
Level: "level",
|
||||
Tree: "tree",
|
||||
Sort: "sort",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
Id: "id",
|
||||
Title: "title",
|
||||
Pinyin: "pinyin",
|
||||
Lng: "lng",
|
||||
Lat: "lat",
|
||||
Pid: "pid",
|
||||
Level: "level",
|
||||
Tree: "tree",
|
||||
Sort: "sort",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewSysProvincesDao creates and returns a new DAO object for table data access.
|
||||
|
91
server/internal/dao/internal/sys_serve_log.go
Normal file
91
server/internal/dao/internal/sys_serve_log.go
Normal file
@@ -0,0 +1,91 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// SysServeLogDao is the data access object for table hg_sys_serve_log.
|
||||
type SysServeLogDao 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 SysServeLogColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// SysServeLogColumns defines and stores column names for table hg_sys_serve_log.
|
||||
type SysServeLogColumns struct {
|
||||
Id string // 日志ID
|
||||
TraceId string // 链路ID
|
||||
LevelFormat string // 日志级别
|
||||
Content string // 日志内容
|
||||
Stack string // 打印堆栈
|
||||
Line string // 调用行
|
||||
TriggerNs string // 触发时间(ns)
|
||||
Status string // 状态
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 修改时间
|
||||
}
|
||||
|
||||
// sysServeLogColumns holds the columns for table hg_sys_serve_log.
|
||||
var sysServeLogColumns = SysServeLogColumns{
|
||||
Id: "id",
|
||||
TraceId: "trace_id",
|
||||
LevelFormat: "level_format",
|
||||
Content: "content",
|
||||
Stack: "stack",
|
||||
Line: "line",
|
||||
TriggerNs: "trigger_ns",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewSysServeLogDao creates and returns a new DAO object for table data access.
|
||||
func NewSysServeLogDao() *SysServeLogDao {
|
||||
return &SysServeLogDao{
|
||||
group: "default",
|
||||
table: "hg_sys_serve_log",
|
||||
columns: sysServeLogColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *SysServeLogDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *SysServeLogDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *SysServeLogDao) Columns() SysServeLogColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *SysServeLogDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *SysServeLogDao) 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 *SysServeLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
89
server/internal/dao/internal/sys_sms_log.go
Normal file
89
server/internal/dao/internal/sys_sms_log.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// SysSmsLogDao is the data access object for table hg_sys_sms_log.
|
||||
type SysSmsLogDao 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 SysSmsLogColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// SysSmsLogColumns defines and stores column names for table hg_sys_sms_log.
|
||||
type SysSmsLogColumns struct {
|
||||
Id string // 主键
|
||||
Event string // 事件
|
||||
Mobile string // 手机号
|
||||
Code string // 验证码或短信内容
|
||||
Times string // 验证次数
|
||||
Ip string // ip地址
|
||||
Status string // 状态(1未验证,2已验证)
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// sysSmsLogColumns holds the columns for table hg_sys_sms_log.
|
||||
var sysSmsLogColumns = SysSmsLogColumns{
|
||||
Id: "id",
|
||||
Event: "event",
|
||||
Mobile: "mobile",
|
||||
Code: "code",
|
||||
Times: "times",
|
||||
Ip: "ip",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewSysSmsLogDao creates and returns a new DAO object for table data access.
|
||||
func NewSysSmsLogDao() *SysSmsLogDao {
|
||||
return &SysSmsLogDao{
|
||||
group: "default",
|
||||
table: "hg_sys_sms_log",
|
||||
columns: sysSmsLogColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *SysSmsLogDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *SysSmsLogDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *SysSmsLogDao) Columns() SysSmsLogColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *SysSmsLogDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *SysSmsLogDao) 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 *SysSmsLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
@@ -7,7 +7,6 @@ package dao
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao/internal"
|
||||
"hotgo/internal/model/entity"
|
||||
@@ -67,7 +66,6 @@ func (dao *sysDictTypeDao) GetTypes(ctx context.Context, id int64) (types []stri
|
||||
types = append(types, v.String())
|
||||
}
|
||||
|
||||
g.Log().Warningf(ctx, "types:%+v", types)
|
||||
return types, nil
|
||||
}
|
||||
|
||||
@@ -81,7 +79,6 @@ func (dao *sysDictTypeDao) GetType(ctx context.Context, id int64) (types string,
|
||||
return types, err
|
||||
}
|
||||
|
||||
g.Log().Warningf(ctx, "GetType types:%+v", list.String())
|
||||
return list.String(), nil
|
||||
}
|
||||
|
||||
|
@@ -8,19 +8,19 @@ import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalDemoDao is internal type for wrapping internal DAO implements.
|
||||
type internalDemoDao = *internal.DemoDao
|
||||
// internalSysLoginLogDao is internal type for wrapping internal DAO implements.
|
||||
type internalSysLoginLogDao = *internal.SysLoginLogDao
|
||||
|
||||
// demoDao is the data access object for table hg_demo.
|
||||
// sysLoginLogDao is the data access object for table hg_sys_login_log.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type demoDao struct {
|
||||
internalDemoDao
|
||||
type sysLoginLogDao struct {
|
||||
internalSysLoginLogDao
|
||||
}
|
||||
|
||||
var (
|
||||
// Demo is globally public accessible object for table hg_demo operations.
|
||||
Demo = demoDao{
|
||||
internal.NewDemoDao(),
|
||||
// SysLoginLog is globally public accessible object for table hg_sys_login_log operations.
|
||||
SysLoginLog = sysLoginLogDao{
|
||||
internal.NewSysLoginLogDao(),
|
||||
}
|
||||
)
|
||||
|
@@ -31,20 +31,20 @@ var (
|
||||
// Fill with you ideas below.
|
||||
|
||||
// GetRegion 获取省市编码对应的地区名称
|
||||
func (dao *sysProvincesDao) GetRegion(ctx context.Context, province int, city int, spilt ...string) (string, error) {
|
||||
|
||||
func (dao *sysProvincesDao) GetRegion(ctx context.Context, province int64, city int64, spilt ...string) (string, error) {
|
||||
var (
|
||||
provinceName *gvar.Var
|
||||
cityName *gvar.Var
|
||||
err error
|
||||
)
|
||||
// TODO 默认分隔符
|
||||
|
||||
// 分隔符
|
||||
spiltSymbol := "-"
|
||||
if len(spilt) > 0 {
|
||||
spiltSymbol = spilt[0]
|
||||
}
|
||||
|
||||
if province > 0 {
|
||||
if province > 0 && province < 999999 {
|
||||
provinceName, err = dao.Ctx(ctx).Where("id", province).Fields("title").Value()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
|
27
server/internal/dao/sys_serve_log.go
Normal file
27
server/internal/dao/sys_serve_log.go
Normal 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"
|
||||
)
|
||||
|
||||
// internalSysServeLogDao is internal type for wrapping internal DAO implements.
|
||||
type internalSysServeLogDao = *internal.SysServeLogDao
|
||||
|
||||
// sysServeLogDao is the data access object for table hg_sys_serve_log.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type sysServeLogDao struct {
|
||||
internalSysServeLogDao
|
||||
}
|
||||
|
||||
var (
|
||||
// SysServeLog is globally public accessible object for table hg_sys_serve_log operations.
|
||||
SysServeLog = sysServeLogDao{
|
||||
internal.NewSysServeLogDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
43
server/internal/dao/sys_sms_log.go
Normal file
43
server/internal/dao/sys_sms_log.go
Normal file
@@ -0,0 +1,43 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalSysSmsLogDao is internal type for wrapping internal DAO implements.
|
||||
type internalSysSmsLogDao = *internal.SysSmsLogDao
|
||||
|
||||
// sysSmsLogDao is the data access object for table hg_sys_sms_log.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type sysSmsLogDao struct {
|
||||
internalSysSmsLogDao
|
||||
}
|
||||
|
||||
var (
|
||||
// SysSmsLog is globally public accessible object for table hg_sys_sms_log operations.
|
||||
SysSmsLog = sysSmsLogDao{
|
||||
internal.NewSysSmsLogDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
||||
|
||||
// NowDayCount 当天发送次数
|
||||
func (dao *sysSmsLogDao) NowDayCount(ctx context.Context, event, mobile string) (count int, err error) {
|
||||
count, err = dao.Ctx(ctx).
|
||||
Where("mobile", mobile).
|
||||
Where("event", event).
|
||||
WhereGTE("created_at", gtime.Now().Format("Y-m-d")).
|
||||
Count()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
@@ -10,20 +10,32 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2"
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcache"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/hggen"
|
||||
"hotgo/internal/library/location"
|
||||
"hotgo/internal/library/queue"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/charset"
|
||||
"hotgo/utility/simple"
|
||||
"os"
|
||||
)
|
||||
|
||||
func Init(ctx context.Context) {
|
||||
if _, err := g.Cfg().Get(ctx, "hotgo.debug"); err != nil {
|
||||
_, err := g.Cfg().Get(ctx, "hotgo.debug")
|
||||
if err != nil {
|
||||
g.Log().Fatal(ctx, "配置读取异常:", err, "\r\n你确定 config/config.yaml 文件存在且格式正确吗?\r\n")
|
||||
return
|
||||
}
|
||||
//g.SetDebug(debug.Bool())
|
||||
|
||||
// 默认上海时区
|
||||
if err := gtime.SetTimeZone("Asia/Shanghai"); err != nil {
|
||||
g.Log().Fatalf(ctx, "时区设置异常err:%+v", err)
|
||||
@@ -33,12 +45,15 @@ func Init(ctx context.Context) {
|
||||
RootPtah, _ = os.Getwd()
|
||||
fmt.Printf("欢迎使用HotGo!\r\n当前运行环境:%v, 运行根路径为:%v \r\nHotGo版本:v%v, gf版本:%v \n", SysType, RootPtah, consts.VersionApp, gf.VERSION)
|
||||
|
||||
g.Log().SetHandlers(LoggingServeLogHandler)
|
||||
|
||||
setOrmCacheAdapter()
|
||||
|
||||
service.SysBlacklist().Load(ctx)
|
||||
|
||||
startMonitor(ctx)
|
||||
|
||||
hggen.InIt(ctx)
|
||||
|
||||
}
|
||||
|
||||
func startMonitor(ctx context.Context) {
|
||||
@@ -62,3 +77,47 @@ func setOrmCacheAdapter() {
|
||||
redisCache := gcache.NewAdapterRedis(g.Redis())
|
||||
g.DB().GetCache().SetAdapter(redisCache)
|
||||
}
|
||||
|
||||
func LoggingServeLogHandler(ctx context.Context, in *glog.HandlerInput) {
|
||||
in.Next(ctx)
|
||||
|
||||
conf, err := service.SysConfig().GetLoadServeLog(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !conf.Switch {
|
||||
return
|
||||
}
|
||||
|
||||
if in.LevelFormat == "" || !gstr.InArray(conf.LevelFormat, in.LevelFormat) {
|
||||
return
|
||||
}
|
||||
|
||||
var data entity.SysServeLog
|
||||
data.TraceId = gctx.CtxId(ctx)
|
||||
data.LevelFormat = in.LevelFormat
|
||||
data.Content = in.Content
|
||||
data.Stack = gjson.New(charset.ParseStack(in.Stack))
|
||||
data.Line = in.CallerPath
|
||||
data.TriggerNs = in.Time.UnixNano()
|
||||
data.Status = consts.StatusEnabled
|
||||
|
||||
if data.Stack.IsNil() {
|
||||
data.Stack = gjson.New(consts.NilJsonToString)
|
||||
}
|
||||
|
||||
if gstr.Contains(in.Content, `exception recovered`) {
|
||||
data.LevelFormat = "PANI"
|
||||
}
|
||||
|
||||
if conf.Queue {
|
||||
err = queue.Push(consts.QueueServeLogTopic, data)
|
||||
} else {
|
||||
err = service.SysServeLog().RealWrite(ctx, data)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
g.Log().Printf(ctx, "LoggingServeLogHandler err:%+v", err)
|
||||
}
|
||||
}
|
||||
|
@@ -18,4 +18,6 @@ var (
|
||||
SysType = runtime.GOOS
|
||||
// MonitorData 监控数据
|
||||
MonitorData model.MonitorData
|
||||
// Blacklists 黑名单列表
|
||||
Blacklists map[string]struct{}
|
||||
)
|
||||
|
@@ -11,34 +11,53 @@ import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/mojocn/base64Captcha"
|
||||
"image/color"
|
||||
)
|
||||
|
||||
// GetVerifyImgString 生成验证码
|
||||
func GetVerifyImgString(ctx context.Context) (idKeyC string, base64stringC string) {
|
||||
driver := &base64Captcha.DriverString{
|
||||
Height: 80,
|
||||
Width: 240,
|
||||
//NoiseCount: 50,
|
||||
//ShowLineOptions: 20,
|
||||
Length: 4,
|
||||
Source: "abcdefghjkmnpqrstuvwxyz23456789",
|
||||
Fonts: []string{"chromohv.ttf"},
|
||||
// Generate 生成验证码
|
||||
func Generate(ctx context.Context) (id string, base64 string) {
|
||||
// 字符
|
||||
//driver := &base64Captcha.DriverString{
|
||||
// Height: 42,
|
||||
// Width: 100,
|
||||
// //NoiseCount: 50,
|
||||
// //ShowLineOptions: 20,
|
||||
// Length: 4,
|
||||
// BgColor: &color.RGBA{
|
||||
// R: 255,
|
||||
// G: 250,
|
||||
// B: 250,
|
||||
// A: 250,
|
||||
// },
|
||||
// Source: "0123456789", // abcdefghjkmnpqrstuvwxyz23456789
|
||||
// Fonts: []string{"chromohv.ttf"},
|
||||
//}
|
||||
|
||||
// 计算
|
||||
driver := &base64Captcha.DriverMath{
|
||||
Height: 42,
|
||||
Width: 100,
|
||||
NoiseCount: 0,
|
||||
ShowLineOptions: 0,
|
||||
BgColor: &color.RGBA{
|
||||
R: 255,
|
||||
G: 250,
|
||||
B: 250,
|
||||
A: 250,
|
||||
},
|
||||
Fonts: []string{"chromohv.ttf"},
|
||||
}
|
||||
driver = driver.ConvertFonts()
|
||||
store := base64Captcha.DefaultMemStore
|
||||
c := base64Captcha.NewCaptcha(driver, store)
|
||||
idKeyC, base64stringC, err := c.Generate()
|
||||
|
||||
c := base64Captcha.NewCaptcha(driver.ConvertFonts(), base64Captcha.DefaultMemStore)
|
||||
id, base64, err := c.Generate()
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, err)
|
||||
g.Log().Errorf(ctx, "captcha.Generate err:%+v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// VerifyString 验证输入的验证码是否正确
|
||||
func VerifyString(id, answer string) bool {
|
||||
driver := new(base64Captcha.DriverString)
|
||||
store := base64Captcha.DefaultMemStore
|
||||
c := base64Captcha.NewCaptcha(driver, store)
|
||||
answer = gstr.ToLower(answer)
|
||||
return c.Verify(id, answer, true)
|
||||
// Verify 验证输入的验证码是否正确
|
||||
func Verify(id, answer string) bool {
|
||||
c := base64Captcha.NewCaptcha(new(base64Captcha.DriverString), base64Captcha.DefaultMemStore)
|
||||
return c.Verify(id, gstr.ToLower(answer), true)
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ func SetUser(ctx context.Context, user *model.Identity) {
|
||||
Get(ctx).User = user
|
||||
}
|
||||
|
||||
// SetResponse 设置组件响应 用于全局日志使用
|
||||
// SetResponse 设置组件响应 用于访问日志使用
|
||||
func SetResponse(ctx context.Context, response *model.Response) {
|
||||
Get(ctx).Response = response
|
||||
}
|
||||
|
@@ -8,10 +8,53 @@ package views
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
)
|
||||
|
||||
func (l *gCurd) webIndexTplData(ctx context.Context, in *CurdPreviewInput) (data g.Map, err error) {
|
||||
data = make(g.Map)
|
||||
return
|
||||
const (
|
||||
IndexApiImport = " import {%v } from '@/api/%s';"
|
||||
IndexIconsImport = " import {%v } from '@vicons/antd';"
|
||||
)
|
||||
|
||||
func (l *gCurd) webIndexTplData(ctx context.Context, in *CurdPreviewInput) (g.Map, error) {
|
||||
var (
|
||||
data = make(g.Map)
|
||||
apiImport = []string{" List"}
|
||||
iconsImport []string
|
||||
)
|
||||
|
||||
// 添加
|
||||
if in.options.Step.HasAdd {
|
||||
iconsImport = append(iconsImport, " PlusOutlined")
|
||||
}
|
||||
|
||||
// 编辑
|
||||
if in.options.Step.HasEdit {
|
||||
}
|
||||
|
||||
// 导出
|
||||
if in.options.Step.HasExport {
|
||||
iconsImport = append(iconsImport, " ExportOutlined")
|
||||
apiImport = append(apiImport, " Export")
|
||||
}
|
||||
|
||||
// 删除
|
||||
if in.options.Step.HasDel || in.options.Step.HasBatchDel {
|
||||
iconsImport = append(iconsImport, " DeleteOutlined")
|
||||
apiImport = append(apiImport, " Delete")
|
||||
}
|
||||
|
||||
// 导出
|
||||
if in.options.Step.HasStatus {
|
||||
apiImport = append(apiImport, " Status")
|
||||
}
|
||||
|
||||
data["apiImport"] = fmt.Sprintf(IndexApiImport, gstr.Implode(",", apiImport), gstr.LcFirst(in.In.VarName))
|
||||
if len(iconsImport) > 0 {
|
||||
data["iconsImport"] = fmt.Sprintf(IndexIconsImport, gstr.Implode(",", iconsImport))
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
@@ -259,10 +259,10 @@ func (l *gCurd) generateWebModelColumnsEach(buffer *bytes.Buffer, in *CurdPrevie
|
||||
component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s) || !isArray(row.%s)) {\n return ``;\n }\n return row.%s.map((tagKey) => {\n return h(\n NTag,\n {\n style: {\n marginRight: '6px',\n },\n type: getOptionTag(options.value.%s, tagKey),\n bordered: false,\n },\n {\n default: () => getOptionLabel(options.value.%s, tagKey),\n }\n );\n });\n },\n },\n", field.Dc, field.TsName, field.TsName, field.TsName, field.TsName, in.options.dictMap[field.TsName], in.options.dictMap[field.TsName])
|
||||
|
||||
case FormModeUploadImage:
|
||||
component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n return h(%s, {\n width: 32,\n height: 32,\n src: row.%s,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n },\n });\n },\n },\n", field.Dc, field.TsName, "NImage", field.TsName)
|
||||
component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n return h(%s, {\n width: 32,\n height: 32,\n src: row.%s,\n onError: errorImg,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n },\n });\n },\n },\n", field.Dc, field.TsName, "NImage", field.TsName)
|
||||
|
||||
case FormModeUploadImages:
|
||||
component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return row.%s.map((image) => {\n return h(%s, {\n width: 32,\n height: 32,\n src: image,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n 'margin-left': '2px',\n },\n });\n });\n },\n },\n", field.Dc, field.TsName, field.TsName, field.TsName, "NImage")
|
||||
component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return row.%s.map((image) => {\n return h(%s, {\n width: 32,\n height: 32,\n src: image,\n onError: errorImg,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n 'margin-left': '2px',\n },\n });\n });\n },\n },\n", field.Dc, field.TsName, field.TsName, field.TsName, "NImage")
|
||||
|
||||
case FormModeUploadFile:
|
||||
component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (row.%s === '') {\n return ``;\n }\n return h(\n %s,\n {\n size: 'small',\n },\n {\n default: () => getFileExt(row.%s),\n }\n );\n },\n },\n", field.Dc, field.TsName, field.TsName, "NAvatar", field.TsName)
|
||||
|
@@ -208,7 +208,7 @@ func IsUnique(ctx context.Context, dao interface{}, where g.Map, message string,
|
||||
// GenSubTree 生成下级关系树
|
||||
func GenSubTree(ctx context.Context, dao interface{}, oldPid int64) (newPid int64, newLevel int, subTree string, err error) {
|
||||
// 顶级树
|
||||
if oldPid == 0 {
|
||||
if oldPid <= 0 {
|
||||
return 0, 1, "", nil
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ func GenSubTree(ctx context.Context, dao interface{}, oldPid int64) (newPid int6
|
||||
return 0, 0, "", err
|
||||
}
|
||||
|
||||
models, err := d.Ctx(ctx).WhereNot(field, oldPid).One()
|
||||
models, err := d.Ctx(ctx).Where(field, oldPid).One()
|
||||
if err != nil {
|
||||
return 0, 0, "", err
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ import (
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/utility/tree"
|
||||
)
|
||||
|
||||
// HandlerFilterAuth 过滤数据权限
|
||||
@@ -23,7 +24,7 @@ func HandlerFilterAuth(m *gdb.Model) *gdb.Model {
|
||||
var (
|
||||
needAuth bool
|
||||
filterField string
|
||||
roleModel *entity.AdminRole
|
||||
role *entity.AdminRole
|
||||
ctx = m.GetCtx()
|
||||
fields = escapeFieldsToSlice(m.GetFieldsStr())
|
||||
co = contexts.Get(ctx)
|
||||
@@ -48,34 +49,35 @@ func HandlerFilterAuth(m *gdb.Model) *gdb.Model {
|
||||
return m
|
||||
}
|
||||
|
||||
err := g.Model("admin_role").Where("id", co.User.RoleId).Scan(&roleModel)
|
||||
err := g.Model("admin_role").Where("id", co.User.RoleId).Scan(&role)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("HandlerFilterAuth Failed to role information err:%+v", err))
|
||||
panic(fmt.Sprintf("failed to role information err:%+v", err))
|
||||
}
|
||||
|
||||
if roleModel == nil {
|
||||
panic(fmt.Sprintf("HandlerFilterAuth Failed to role information err2:%+v", err))
|
||||
if role == nil {
|
||||
panic("failed to role information roleModel == nil")
|
||||
}
|
||||
|
||||
// TODO 当前不是完整功能,预计在下个版本中完善
|
||||
switch roleModel.DataScope {
|
||||
sq := g.Model("admin_member").Fields("id")
|
||||
|
||||
switch role.DataScope {
|
||||
case consts.RoleDataAll: // 全部权限
|
||||
// ...
|
||||
case consts.RoleDataNowDept: // 当前部门
|
||||
m = m.Where(filterField, co.User.DeptId)
|
||||
m = m.WhereIn(filterField, sq.Where("dept_id", co.User.DeptId))
|
||||
case consts.RoleDataDeptAndSub: // 当前部门及以下部门
|
||||
//m = m.Where(filterField, 1)
|
||||
m = m.WhereIn(filterField, sq.WhereIn("dept_id", GetDeptAndSub(co.User.DeptId)))
|
||||
case consts.RoleDataDeptCustom: // 自定义部门
|
||||
m = m.WhereIn(filterField, roleModel.CustomDept.Var().Ints())
|
||||
m = m.WhereIn(filterField, sq.WhereIn("dept_id", role.CustomDept.Var().Ints()))
|
||||
case consts.RoleDataSelf: // 仅自己
|
||||
m = m.Where(filterField, co.User.Id)
|
||||
case consts.RoleDataSelfAndSub: // 自己和直属下级
|
||||
//m = m.Where(filterField, 1)
|
||||
m = m.WhereIn(filterField, GetSelfAndSub(co.User.Id))
|
||||
case consts.RoleDataSelfAndAllSub: // 自己和全部下级
|
||||
//m = m.Where(filterField, 1)
|
||||
m = m.WhereIn(filterField, GetSelfAndAllSub(co.User.Id))
|
||||
|
||||
default:
|
||||
panic("HandlerFilterAuth dataScope is not registered")
|
||||
panic("dataScope is not registered")
|
||||
}
|
||||
|
||||
return m
|
||||
@@ -90,3 +92,57 @@ func HandlerForceCache(m *gdb.Model) *gdb.Model {
|
||||
func escapeFieldsToSlice(s string) []string {
|
||||
return gstr.Explode(",", gstr.Replace(gstr.Replace(s, "`,`", ","), "`", ""))
|
||||
}
|
||||
|
||||
// GetDeptAndSub 获取指定部门的所有下级,含本部门
|
||||
func GetDeptAndSub(deptId int64) (ids []int64) {
|
||||
array, err := g.Model("admin_dept").
|
||||
WhereLike("tree", "%"+tree.GetIdLabel(deptId)+"%").
|
||||
Fields("id").
|
||||
Array()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range array {
|
||||
ids = append(ids, v.Int64())
|
||||
}
|
||||
|
||||
ids = append(ids, deptId)
|
||||
return
|
||||
}
|
||||
|
||||
// GetSelfAndSub 获取直属下级,包含自己
|
||||
func GetSelfAndSub(memberId int64) (ids []int64) {
|
||||
array, err := g.Model("admin_member").
|
||||
Where("pid", memberId).
|
||||
Fields("id").
|
||||
Array()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range array {
|
||||
ids = append(ids, v.Int64())
|
||||
}
|
||||
|
||||
ids = append(ids, memberId)
|
||||
return
|
||||
}
|
||||
|
||||
// GetSelfAndAllSub 获取全部下级,包含自己
|
||||
func GetSelfAndAllSub(memberId int64) (ids []int64) {
|
||||
array, err := g.Model("admin_member").
|
||||
WhereLike("tree", "%"+tree.GetIdLabel(memberId)+"%").
|
||||
Fields("id").
|
||||
Array()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range array {
|
||||
ids = append(ids, v.Int64())
|
||||
}
|
||||
|
||||
ids = append(ids, memberId)
|
||||
return
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
// GenerateLoginToken 为指定用户生成token
|
||||
func GenerateLoginToken(ctx context.Context, user *model.Identity, isRefresh bool) (interface{}, error) {
|
||||
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")
|
||||
@@ -51,7 +51,7 @@ func GenerateLoginToken(ctx context.Context, user *model.Identity, isRefresh boo
|
||||
|
||||
tokenString, err := token.SignedString(jwtSign.Bytes())
|
||||
if err != nil {
|
||||
return nil, gerror.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -65,12 +65,12 @@ func GenerateLoginToken(ctx context.Context, user *model.Identity, isRefresh boo
|
||||
|
||||
err = c.Set(ctx, key, tokenString, expires)
|
||||
if err != nil {
|
||||
return nil, gerror.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = c.Set(ctx, consts.RedisJwtUserBind+user.App+":"+gconv.String(user.Id), key, expires)
|
||||
if err != nil {
|
||||
return nil, gerror.New(err.Error())
|
||||
return "", err
|
||||
}
|
||||
return tokenString, err
|
||||
}
|
||||
|
@@ -144,6 +144,11 @@ func GetPublicIP(ctx context.Context) (ip string, err error) {
|
||||
g.Log().Warningf(ctx, "GetPublicIP alternatives are being tried err:%+v", err)
|
||||
return GetPublicIP2()
|
||||
}
|
||||
|
||||
if data == nil {
|
||||
g.Log().Warningf(ctx, "publicIP address Parsing failure, check the network and firewall blocking.")
|
||||
return "0.0.0.0", nil
|
||||
}
|
||||
return data.Ip, nil
|
||||
}
|
||||
|
||||
@@ -190,5 +195,10 @@ func GetClientIp(r *ghttp.Request) string {
|
||||
if ip == "" {
|
||||
ip = r.GetClientIp()
|
||||
}
|
||||
|
||||
// 如果存在多个,默认取第一个
|
||||
if gstr.Contains(ip, ",") {
|
||||
ip = gstr.TrimStr(ip, ",", -1)
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
@@ -93,7 +93,7 @@ func InstanceProducer() (mqClient MqProducer, err error) {
|
||||
return NewProducer(config.GroupName)
|
||||
}
|
||||
|
||||
// NewProducer 新建一个生产者实例
|
||||
// NewProducer 初始化生产者实例
|
||||
func NewProducer(groupName string) (mqClient MqProducer, err error) {
|
||||
if item, ok := mqProducerInstanceMap[groupName]; ok {
|
||||
return item, nil
|
||||
@@ -143,7 +143,7 @@ func NewProducer(groupName string) (mqClient MqProducer, err error) {
|
||||
return mqClient, nil
|
||||
}
|
||||
|
||||
// NewConsumer 新建一个消费者实例
|
||||
// NewConsumer 初始化消费者实例
|
||||
func NewConsumer(groupName string) (mqClient MqConsumer, err error) {
|
||||
randTag := string(charset.RandomCreateBytes(6))
|
||||
|
||||
|
@@ -87,30 +87,28 @@ func (r *KafkaMq) ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg))
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
go func() {
|
||||
|
||||
go func(ctx context.Context) {
|
||||
for {
|
||||
if err := r.consumerIns.Consume(ctx, []string{topic}, &consumer); err != nil {
|
||||
FatalLog(ctx, "kafka Error from consumer", err)
|
||||
g.Log().Fatalf(ctx, "kafka Error from consumer, err%+v", err)
|
||||
}
|
||||
|
||||
if ctx.Err() != nil {
|
||||
Log(ctx, fmt.Sprintf("kafka consoumer stop : %v", ctx.Err()))
|
||||
g.Log().Debugf(ctx, fmt.Sprintf("kafka consoumer stop : %v", ctx.Err()))
|
||||
return
|
||||
}
|
||||
consumer.ready = make(chan bool)
|
||||
}
|
||||
}()
|
||||
}(ctx)
|
||||
|
||||
<-consumer.ready // Await till the consumer has been set up
|
||||
Log(ctx, "kafka consumer up and running!...")
|
||||
g.Log().Debug(ctx, "kafka consumer up and running!...")
|
||||
|
||||
signal.AppDefer(func() {
|
||||
Log(ctx, "kafka consumer close...")
|
||||
g.Log().Debug(ctx, "kafka consumer close...")
|
||||
cancel()
|
||||
if err = r.consumerIns.Close(); err != nil {
|
||||
FatalLog(ctx, "kafka Error closing client", err)
|
||||
g.Log().Fatalf(ctx, "kafka Error closing client, err:%+v", err)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -193,7 +191,7 @@ func RegisterKafkaProducer(connOpt KafkaConfig, mqIns *KafkaMq) {
|
||||
}
|
||||
|
||||
signal.AppDefer(func() {
|
||||
Log(ctx, "kafka producer AsyncClose...")
|
||||
g.Log().Debug(ctx, "kafka producer AsyncClose...")
|
||||
mqIns.producerIns.AsyncClose()
|
||||
})
|
||||
}
|
||||
|
@@ -10,33 +10,28 @@ import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/utility/charset"
|
||||
)
|
||||
|
||||
const (
|
||||
ConsumerLogErrFormat = "消费 [%s] 失败, mqMsgId:%+v, mqMsgData:%+v, err:%+v, stack:%+v"
|
||||
ProducerLogErrFormat = "生产 [%s] 失败, data:%+v, err:%+v, stack:%+v"
|
||||
)
|
||||
|
||||
// ConsumerLog 消费日志
|
||||
func ConsumerLog(ctx context.Context, topic string, mqMsg MqMsg, err error) {
|
||||
if err != nil {
|
||||
g.Log(consts.QueueLogPath).Error(ctx, "消费 ["+topic+"] 失败", mqMsg, err)
|
||||
g.Log().Printf(ctx, ConsumerLogErrFormat, topic, mqMsg.MsgId, mqMsg.BodyString(), err, charset.ParseErrStack(err))
|
||||
} else {
|
||||
g.Log(consts.QueueLogPath).Debug(ctx, "消费 ["+topic+"] 成功", mqMsg.MsgId)
|
||||
g.Log().Print(ctx, "消费 ["+topic+"] 成功", mqMsg.MsgId)
|
||||
}
|
||||
}
|
||||
|
||||
// ProducerLog 生产日志
|
||||
func ProducerLog(ctx context.Context, topic string, data interface{}, err error) {
|
||||
if err != nil {
|
||||
g.Log(consts.QueueLogPath).Error(ctx, "生产 ["+topic+"] 失败", gconv.String(data))
|
||||
g.Log().Printf(ctx, ProducerLogErrFormat, topic, gconv.String(data), err, charset.ParseErrStack(err))
|
||||
} else {
|
||||
g.Log(consts.QueueLogPath).Debug(ctx, "生产 ["+topic+"] 成功", gconv.String(data))
|
||||
g.Log().Print(ctx, "生产 ["+topic+"] 成功", gconv.String(data))
|
||||
}
|
||||
}
|
||||
|
||||
// FatalLog 致命日志
|
||||
func FatalLog(ctx context.Context, text string, err error) {
|
||||
g.Log(consts.QueueLogPath).Fatal(ctx, text+":", err)
|
||||
}
|
||||
|
||||
// Log 通用日志
|
||||
func Log(ctx context.Context, text string) {
|
||||
g.Log(consts.QueueLogPath).Debug(ctx, text)
|
||||
}
|
||||
|
18
server/internal/library/queue/push.go
Normal file
18
server/internal/library/queue/push.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
// Push 推送队列
|
||||
func Push(topic string, data interface{}) (err error) {
|
||||
q, err := InstanceProducer()
|
||||
if err != nil {
|
||||
g.Log().Fatalf(ctx, "queue.InstanceProducer err:%+v", err)
|
||||
return err
|
||||
}
|
||||
mqMsg, err := q.SendMsg(topic, gconv.String(data))
|
||||
ProducerLog(ctx, topic, mqMsg.MsgId, err)
|
||||
return err
|
||||
}
|
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/utility/encrypt"
|
||||
"math/rand"
|
||||
"time"
|
||||
@@ -113,7 +112,7 @@ func (r *RedisMq) ListenReceiveMsgDo(topic string, receiveDo func(mqMsg MqMsg))
|
||||
|
||||
// 生成队列名称
|
||||
func (r *RedisMq) genQueueName(groupName string, topic string) string {
|
||||
return fmt.Sprintf(consts.QueueName+"%s_%s", groupName, topic)
|
||||
return fmt.Sprintf("queue:%s_%s", groupName, topic)
|
||||
}
|
||||
|
||||
func (r *RedisMq) loopReadQueue(queueName string) (mqMsgList []MqMsg) {
|
||||
|
@@ -26,8 +26,8 @@ type RocketMq struct {
|
||||
|
||||
// rewriteLog 重写日志
|
||||
func rewriteLog() {
|
||||
level := g.Cfg().MustGet(ctx, "queue.rocketmq.logLevel", "debug")
|
||||
rlog.SetLogger(&RocketMqLogger{Flag: "[rocket_mq]", LevelLog: level.String()})
|
||||
level := g.Cfg().MustGet(ctx, "queue.rocketmq.logLevel", "debug").String()
|
||||
rlog.SetLogger(&RocketMqLogger{Flag: "[rocket_mq]", LevelLog: level})
|
||||
}
|
||||
|
||||
// RegisterRocketProducerMust 注册并启动生产者接口实现
|
||||
|
@@ -7,7 +7,7 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type RocketMqLogger struct {
|
||||
@@ -24,16 +24,16 @@ func (l *RocketMqLogger) Debug(msg string, fields map[string]interface{}) {
|
||||
}
|
||||
|
||||
if l.LevelLog == "debug" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [debug] ", msg))
|
||||
g.Log().Debug(ctx, msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RocketMqLogger) Level(level string) {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [level] ", level))
|
||||
g.Log().Info(ctx, level)
|
||||
}
|
||||
|
||||
func (l *RocketMqLogger) OutputPath(path string) (err error) {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [path] ", path))
|
||||
g.Log().Info(ctx, path)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ func (l *RocketMqLogger) Info(msg string, fields map[string]interface{}) {
|
||||
}
|
||||
|
||||
if l.LevelLog == "info" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [info] ", msg))
|
||||
g.Log().Info(ctx, msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func (l *RocketMqLogger) Warning(msg string, fields map[string]interface{}) {
|
||||
}
|
||||
|
||||
if l.LevelLog == "warn" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [warn] ", msg))
|
||||
g.Log().Warning(ctx, msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func (l *RocketMqLogger) Error(msg string, fields map[string]interface{}) {
|
||||
return
|
||||
}
|
||||
if l.LevelLog == "error" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [error] ", msg))
|
||||
g.Log().Error(ctx, msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,6 @@ func (l *RocketMqLogger) Fatal(msg string, fields map[string]interface{}) {
|
||||
}
|
||||
|
||||
if l.LevelLog == "fatal" || l.LevelLog == "all" {
|
||||
Log(ctx, fmt.Sprint(l.Flag, " [fatal] ", msg))
|
||||
g.Log().Fatal(ctx, msg)
|
||||
}
|
||||
}
|
||||
|
112
server/internal/library/sms/aliyun/handle.go
Normal file
112
server/internal/library/sms/aliyun/handle.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package aliyun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
||||
dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v3/client"
|
||||
util "github.com/alibabacloud-go/tea-utils/v2/service"
|
||||
"github.com/alibabacloud-go/tea/tea"
|
||||
"hotgo/internal/model"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
// SendCode 发送验证码
|
||||
func SendCode(ctx context.Context, in sysin.SendCodeInp, config *model.SmsConfig) (err error) {
|
||||
if config == nil {
|
||||
config, err = service.SysConfig().GetSms(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
client, err := CreateClient(tea.String(config.SmsAliyunAccessKeyID), tea.String(config.SmsAliyunAccessKeySecret))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
|
||||
PhoneNumbers: tea.String(in.Mobile),
|
||||
SignName: tea.String(config.SmsAliyunSign),
|
||||
TemplateCode: tea.String(in.Template),
|
||||
TemplateParam: tea.String(fmt.Sprintf("{\"code\":\"%v\"}", in.Code)),
|
||||
}
|
||||
|
||||
tryErr := func() (_e error) {
|
||||
defer func() {
|
||||
if r := tea.Recover(recover()); r != nil {
|
||||
_e = r
|
||||
}
|
||||
}()
|
||||
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
_, err = client.SendSmsWithOptions(sendSmsRequest, &util.RuntimeOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
return tryErr
|
||||
}
|
||||
|
||||
// CreateClient 使用AK&SK初始化账号Client
|
||||
func CreateClient(accessKeyId *string, accessKeySecret *string) (_result *dysmsapi20170525.Client, _err error) {
|
||||
config := &openapi.Config{
|
||||
// 必填,您的 AccessKey ID
|
||||
AccessKeyId: accessKeyId,
|
||||
// 必填,您的 AccessKey Secret
|
||||
AccessKeySecret: accessKeySecret,
|
||||
}
|
||||
// 访问的域名
|
||||
config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
|
||||
_result = &dysmsapi20170525.Client{}
|
||||
_result, _err = dysmsapi20170525.NewClient(config)
|
||||
return _result, _err
|
||||
}
|
||||
|
||||
func Send(accessKeyId string, accessKeySecret string) (_err error) {
|
||||
// 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378661.html
|
||||
client, _err := CreateClient(tea.String(accessKeyId), tea.String(accessKeySecret))
|
||||
if _err != nil {
|
||||
return _err
|
||||
}
|
||||
|
||||
sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
|
||||
PhoneNumbers: tea.String("15303830571"),
|
||||
SignName: tea.String("布帆云"),
|
||||
TemplateCode: tea.String("SMS_198921686"),
|
||||
TemplateParam: tea.String("{\"code\":\"1234\"}"),
|
||||
}
|
||||
runtime := &util.RuntimeOptions{}
|
||||
tryErr := func() (_e error) {
|
||||
defer func() {
|
||||
if r := tea.Recover(recover()); r != nil {
|
||||
_e = r
|
||||
}
|
||||
}()
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
_, _err = client.SendSmsWithOptions(sendSmsRequest, runtime)
|
||||
if _err != nil {
|
||||
return _err
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
if tryErr != nil {
|
||||
var err = &tea.SDKError{}
|
||||
if _t, ok := tryErr.(*tea.SDKError); ok {
|
||||
err = _t
|
||||
} else {
|
||||
err.Message = tea.String(tryErr.Error())
|
||||
}
|
||||
// 如有需要,请打印 error
|
||||
_, _err = util.AssertAsString(err.Message)
|
||||
if _err != nil {
|
||||
return _err
|
||||
}
|
||||
}
|
||||
return _err
|
||||
}
|
1
server/internal/library/sms/aliyun/init.go
Normal file
1
server/internal/library/sms/aliyun/init.go
Normal file
@@ -0,0 +1 @@
|
||||
package aliyun
|
1
server/internal/library/sms/aliyun/model.go
Normal file
1
server/internal/library/sms/aliyun/model.go
Normal file
@@ -0,0 +1 @@
|
||||
package aliyun
|
2
server/internal/library/sms/sms.go
Normal file
2
server/internal/library/sms/sms.go
Normal file
@@ -0,0 +1,2 @@
|
||||
package sms
|
||||
|
@@ -9,11 +9,11 @@ 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/util/gconv"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/hgorm"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/adminin"
|
||||
"hotgo/internal/service"
|
||||
@@ -47,8 +47,30 @@ func (s *sAdminDept) NameUnique(ctx context.Context, in adminin.DeptNameUniqueIn
|
||||
}
|
||||
|
||||
// Delete 删除
|
||||
func (s *sAdminDept) Delete(ctx context.Context, in adminin.DeptDeleteInp) error {
|
||||
_, err := dao.AdminDept.Ctx(ctx).Where("id", in.Id).Delete()
|
||||
func (s *sAdminDept) Delete(ctx context.Context, in adminin.DeptDeleteInp) (err error) {
|
||||
|
||||
var (
|
||||
models *entity.AdminDept
|
||||
)
|
||||
err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Scan(&models)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if models == nil {
|
||||
return gerror.New("数据不存在或已删除!")
|
||||
}
|
||||
|
||||
pidExist, err := dao.AdminDept.Ctx(ctx).Where("pid", models.Id).One()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
if !pidExist.IsEmpty() {
|
||||
return gerror.New("请先删除该部门下得所有子级!")
|
||||
}
|
||||
|
||||
_, err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
@@ -75,8 +97,12 @@ func (s *sAdminDept) Edit(ctx context.Context, in adminin.DeptEditInp) (err erro
|
||||
return err
|
||||
}
|
||||
|
||||
in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, dao.AdminDept, in.Pid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 修改
|
||||
in.UpdatedAt = gtime.Now()
|
||||
if in.Id > 0 {
|
||||
_, err = dao.AdminDept.Ctx(ctx).Where("id", in.Id).Data(in).Update()
|
||||
if err != nil {
|
||||
@@ -88,7 +114,6 @@ func (s *sAdminDept) Edit(ctx context.Context, in adminin.DeptEditInp) (err erro
|
||||
}
|
||||
|
||||
// 新增
|
||||
in.CreatedAt = gtime.Now()
|
||||
_, err = dao.AdminDept.Ctx(ctx).Data(in).Insert()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
@@ -156,11 +181,10 @@ func (s *sAdminDept) View(ctx context.Context, in adminin.DeptViewInp) (res *adm
|
||||
// List 获取列表
|
||||
func (s *sAdminDept) List(ctx context.Context, in adminin.DeptListInp) (list adminin.DeptListModel, err error) {
|
||||
var (
|
||||
mod = dao.AdminDept.Ctx(ctx)
|
||||
models []*entity.AdminDept
|
||||
ids []int64
|
||||
pids []int64
|
||||
deptList []g.Map
|
||||
mod = dao.AdminDept.Ctx(ctx)
|
||||
models []*entity.AdminDept
|
||||
ids []int64
|
||||
pids []int64
|
||||
)
|
||||
|
||||
// 部门名称
|
||||
@@ -207,25 +231,14 @@ func (s *sAdminDept) List(ctx context.Context, in adminin.DeptListInp) (list adm
|
||||
return list, err
|
||||
}
|
||||
|
||||
for i := 0; i < len(models); i++ {
|
||||
deptList = append(deptList, g.Map{
|
||||
"index": models[i].Id,
|
||||
"key": models[i].Id,
|
||||
"label": models[i].Name,
|
||||
"id": models[i].Id,
|
||||
"pid": models[i].Pid,
|
||||
"name": models[i].Name,
|
||||
"code": models[i].Code,
|
||||
"leader": models[i].Leader,
|
||||
"phone": models[i].Phone,
|
||||
"email": models[i].Email,
|
||||
"sort": models[i].Sort,
|
||||
"created_at": models[i].CreatedAt,
|
||||
"status": models[i].Status,
|
||||
})
|
||||
list = gconv.SliceMap(models)
|
||||
for k, v := range list {
|
||||
list[k]["index"] = v["id"]
|
||||
list[k]["key"] = v["id"]
|
||||
list[k]["label"] = v["name"]
|
||||
}
|
||||
|
||||
return tree.GenTree(deptList), nil
|
||||
return tree.GenTree(list), nil
|
||||
}
|
||||
|
||||
type DeptTree struct {
|
||||
|
@@ -9,6 +9,7 @@ package admin
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/crypto/gmd5"
|
||||
"github.com/gogf/gf/v2/encoding/gbase64"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
@@ -20,11 +21,13 @@ import (
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/library/jwt"
|
||||
"hotgo/internal/library/location"
|
||||
"hotgo/internal/model"
|
||||
"hotgo/internal/model/do"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/adminin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/encrypt"
|
||||
"hotgo/utility/tree"
|
||||
"hotgo/utility/validate"
|
||||
)
|
||||
@@ -441,7 +444,12 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
|
||||
roleInfo *entity.AdminRole
|
||||
memberInfo *entity.AdminMember
|
||||
identity *model.Identity
|
||||
timestamp = gtime.Timestamp()
|
||||
expires = g.Cfg().MustGet(ctx, "jwt.expires", 1).Int64()
|
||||
exp = gconv.Int64(timestamp) + expires
|
||||
lastIp = location.GetClientIp(ghttp.RequestFromCtx(ctx))
|
||||
)
|
||||
|
||||
err = dao.AdminMember.Ctx(ctx).Where("username", in.Username).Scan(&memberInfo)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
@@ -457,16 +465,21 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
|
||||
return
|
||||
}
|
||||
|
||||
if memberInfo.PasswordHash != gmd5.MustEncryptString(in.Password+memberInfo.Salt) {
|
||||
// 解密密码
|
||||
password, err := gbase64.Decode([]byte(in.Password))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
password, err = encrypt.AesECBDecrypt(password, consts.RequestEncryptKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if memberInfo.PasswordHash != gmd5.MustEncryptString(string(password)+memberInfo.Salt) {
|
||||
err = gerror.New("用户密码不正确")
|
||||
return
|
||||
}
|
||||
|
||||
//// 默认设备
|
||||
//if in.Device != consts.AppAdmin && in.Device != consts.AppApi {
|
||||
// in.Device = consts.AppAdmin
|
||||
//}
|
||||
|
||||
err = dao.AdminRole.Ctx(ctx).
|
||||
Fields("id,key,status").
|
||||
Where("id", memberInfo.RoleId).
|
||||
@@ -485,12 +498,6 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
|
||||
return
|
||||
}
|
||||
|
||||
// 有效期
|
||||
expires := g.Cfg().MustGet(ctx, "jwt.expires", 1).Int64()
|
||||
|
||||
// 过期时间戳
|
||||
exp := gconv.Int64(gtime.Timestamp()) + expires
|
||||
|
||||
identity = &model.Identity{
|
||||
Id: memberInfo.Id,
|
||||
Pid: memberInfo.Pid,
|
||||
@@ -504,7 +511,7 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
|
||||
Mobile: memberInfo.Mobile,
|
||||
VisitCount: memberInfo.VisitCount,
|
||||
LastTime: memberInfo.LastTime,
|
||||
LastIp: memberInfo.LastIp,
|
||||
LastIp: lastIp,
|
||||
Exp: exp,
|
||||
Expires: expires,
|
||||
App: consts.AppAdmin,
|
||||
@@ -517,13 +524,11 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
|
||||
}
|
||||
|
||||
// 更新登录信息
|
||||
authKey := gmd5.MustEncryptString(gconv.String(token))
|
||||
|
||||
_, err = dao.AdminMember.Ctx(ctx).Data(do.AdminMember{
|
||||
AuthKey: gmd5.MustEncryptString(authKey),
|
||||
AuthKey: gmd5.MustEncryptString(token),
|
||||
VisitCount: memberInfo.VisitCount + 1,
|
||||
LastTime: gtime.Timestamp(),
|
||||
LastIp: ghttp.RequestFromCtx(ctx).GetClientIp(),
|
||||
LastTime: timestamp,
|
||||
LastIp: lastIp,
|
||||
}).Where(do.AdminMember{
|
||||
Id: memberInfo.Id,
|
||||
}).Update()
|
||||
@@ -538,7 +543,7 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
|
||||
Username: identity.Username,
|
||||
RealName: identity.RealName,
|
||||
Avatar: identity.Avatar,
|
||||
Token: gconv.String(token),
|
||||
Token: token,
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
@@ -78,7 +78,6 @@ func (s *sAdminPost) Edit(ctx context.Context, in adminin.PostEditInp) (err erro
|
||||
}
|
||||
|
||||
// 修改
|
||||
in.UpdatedAt = gtime.Now()
|
||||
if in.Id > 0 {
|
||||
_, err = dao.AdminPost.Ctx(ctx).Where("id", in.Id).Data(in).Update()
|
||||
if err != nil {
|
||||
@@ -90,7 +89,6 @@ func (s *sAdminPost) Edit(ctx context.Context, in adminin.PostEditInp) (err erro
|
||||
}
|
||||
|
||||
// 新增
|
||||
in.CreatedAt = gtime.Now()
|
||||
_, err = dao.AdminPost.Ctx(ctx).Data(in).Insert()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
@@ -181,7 +179,7 @@ func (s *sAdminPost) List(ctx context.Context, in adminin.PostListInp) (list []*
|
||||
return list, totalCount, nil
|
||||
}
|
||||
|
||||
if err = mod.Page(in.Page, in.PerPage).Order("id desc").Scan(&list); err != nil {
|
||||
if err = mod.Page(in.Page, in.PerPage).Order("id asc").Scan(&list); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ import (
|
||||
"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/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/api/backend/role"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/auth"
|
||||
"hotgo/utility/convert"
|
||||
"hotgo/utility/tree"
|
||||
"sort"
|
||||
)
|
||||
|
||||
@@ -67,21 +68,25 @@ func (s *sAdminRole) Verify(ctx context.Context, path, method string) bool {
|
||||
}
|
||||
|
||||
// List 获取列表
|
||||
func (s *sAdminRole) List(ctx context.Context, in adminin.RoleListInp) (list []*adminin.RoleListModel, totalCount int, err error) {
|
||||
mod := dao.AdminRole.Ctx(ctx)
|
||||
func (s *sAdminRole) List(ctx context.Context, in adminin.RoleListInp) (list []g.Map, totalCount int, err error) {
|
||||
var (
|
||||
mod = dao.AdminRole.Ctx(ctx)
|
||||
models []*adminin.RoleListModel
|
||||
)
|
||||
|
||||
totalCount, err = mod.Count()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
err = mod.Page(in.Page, in.PerPage).Order("id asc").Scan(&list)
|
||||
err = mod.Page(in.Page, in.PerPage).Order("id asc").Scan(&models)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
return list, totalCount, err
|
||||
return tree.GenTree(gconv.SliceMap(models)), totalCount, err
|
||||
}
|
||||
|
||||
// GetName 获取指定角色的名称
|
||||
@@ -197,7 +202,6 @@ func (s *sAdminRole) Edit(ctx context.Context, in *role.EditReq) (err error) {
|
||||
}
|
||||
|
||||
// 修改
|
||||
in.UpdatedAt = gtime.Now()
|
||||
if in.Id > 0 {
|
||||
_, err = dao.AdminRole.Ctx(ctx).Where("id", in.Id).Data(in).Update()
|
||||
if err != nil {
|
||||
@@ -209,7 +213,6 @@ func (s *sAdminRole) Edit(ctx context.Context, in *role.EditReq) (err error) {
|
||||
}
|
||||
|
||||
// 新增
|
||||
in.CreatedAt = gtime.Now()
|
||||
_, err = dao.AdminRole.Ctx(ctx).Data(in).Insert()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
@@ -222,6 +225,28 @@ func (s *sAdminRole) Delete(ctx context.Context, in *role.DeleteReq) (err error)
|
||||
if in.Id <= 0 {
|
||||
return gerror.New("ID不正确!")
|
||||
}
|
||||
|
||||
var (
|
||||
models *entity.AdminRole
|
||||
)
|
||||
err = dao.AdminRole.Ctx(ctx).Where("id", in.Id).Scan(&models)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if models == nil {
|
||||
return gerror.New("数据不存在或已删除!")
|
||||
}
|
||||
|
||||
pidExist, err := dao.AdminRole.Ctx(ctx).Where("pid", models.Id).One()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
if !pidExist.IsEmpty() {
|
||||
return gerror.New("请先删除该角色下得所有子级!")
|
||||
}
|
||||
|
||||
_, err = dao.AdminRole.Ctx(ctx).Where("id", in.Id).Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
|
@@ -14,7 +14,7 @@ import (
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
// GlobalLog 全局日志
|
||||
// GlobalLog 访问日志
|
||||
func (s *sHook) GlobalLog(r *ghttp.Request) {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
|
@@ -37,7 +37,8 @@ func New() *sMiddleware {
|
||||
return &sMiddleware{
|
||||
LoginUrl: "/common",
|
||||
DemoWhiteList: g.Map{
|
||||
"/admin/site/login": struct{}{}, // 后台登录
|
||||
"/admin/site/login": struct{}{}, // 后台登录
|
||||
"/admin/genCodes/preview": struct{}{}, // 预览代码
|
||||
},
|
||||
}
|
||||
}
|
||||
|
23
server/internal/logic/middleware/limit_blacklist.go
Normal file
23
server/internal/logic/middleware/limit_blacklist.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"hotgo/internal/global"
|
||||
"hotgo/internal/library/location"
|
||||
"hotgo/internal/library/response"
|
||||
)
|
||||
|
||||
// Blacklist IP黑名单限制中间件
|
||||
func (s *sMiddleware) Blacklist(r *ghttp.Request) {
|
||||
if global.Blacklists != nil {
|
||||
if _, ok := global.Blacklists[location.GetClientIp(r)]; ok {
|
||||
response.JsonExit(r, gcode.CodeServerBusy.Code(), "请求异常,已被封禁,如有疑问请联系管理员!")
|
||||
}
|
||||
} else {
|
||||
g.Log().Warningf(r.Context(), "blacklists uninitialized")
|
||||
}
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
@@ -42,14 +42,14 @@ func (s *sMiddleware) ResponseHandler(r *ghttp.Request) {
|
||||
|
||||
if err = r.GetError(); err != nil {
|
||||
// 记录到自定义错误日志文件
|
||||
g.Log("exception").Print(ctx, "exception:", err)
|
||||
g.Log().Warningf(ctx, "exception:%v", err)
|
||||
|
||||
code = gerror.Code(err).Code()
|
||||
message = err.Error()
|
||||
|
||||
// 是否输出错误到页面
|
||||
if g.Cfg().MustGet(ctx, "hotgo.debug", true).Bool() {
|
||||
data = charset.GetStack(err)
|
||||
data = charset.ParseErrStack(err)
|
||||
}
|
||||
} else {
|
||||
data = r.GetHandlerResponse()
|
||||
|
@@ -9,9 +9,13 @@ package sys
|
||||
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"
|
||||
"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/validate"
|
||||
@@ -28,8 +32,9 @@ func init() {
|
||||
}
|
||||
|
||||
// Delete 删除
|
||||
func (s *sSysBlacklist) Delete(ctx context.Context, in sysin.BlacklistDeleteInp) error {
|
||||
_, err := dao.SysBlacklist.Ctx(ctx).Where("id", in.Id).Delete()
|
||||
func (s *sSysBlacklist) Delete(ctx context.Context, in sysin.BlacklistDeleteInp) (err error) {
|
||||
defer s.VariableLoad(ctx, err)
|
||||
_, err = dao.SysBlacklist.Ctx(ctx).Where("id", in.Id).Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
@@ -40,6 +45,7 @@ func (s *sSysBlacklist) Delete(ctx context.Context, in sysin.BlacklistDeleteInp)
|
||||
|
||||
// Edit 修改/新增
|
||||
func (s *sSysBlacklist) Edit(ctx context.Context, in sysin.BlacklistEditInp) (err error) {
|
||||
defer s.VariableLoad(ctx, err)
|
||||
if in.Ip == "" {
|
||||
err = gerror.New("ip不能为空")
|
||||
return err
|
||||
@@ -69,6 +75,7 @@ func (s *sSysBlacklist) Edit(ctx context.Context, in sysin.BlacklistEditInp) (er
|
||||
|
||||
// Status 更新部门状态
|
||||
func (s *sSysBlacklist) Status(ctx context.Context, in sysin.BlacklistStatusInp) (err error) {
|
||||
defer s.VariableLoad(ctx, err)
|
||||
if in.Id <= 0 {
|
||||
err = gerror.New("ID不能为空")
|
||||
return err
|
||||
@@ -148,3 +155,112 @@ func (s *sSysBlacklist) List(ctx context.Context, in sysin.BlacklistListInp) (li
|
||||
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
// VariableLoad 变化加载
|
||||
func (s *sSysBlacklist) VariableLoad(ctx context.Context, err error) {
|
||||
if err == nil {
|
||||
s.Load(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// Load 加载黑名单
|
||||
func (s *sSysBlacklist) Load(ctx context.Context) {
|
||||
global.Blacklists = make(map[string]struct{})
|
||||
|
||||
array, err := dao.SysBlacklist.Ctx(ctx).
|
||||
Fields(dao.SysBlacklist.Columns().Ip).
|
||||
Where(dao.SysBlacklist.Columns().Status, consts.StatusEnabled).
|
||||
Array()
|
||||
if err != nil {
|
||||
g.Log().Fatal(ctx, "load blacklist fail:%+v", err)
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
@@ -112,6 +112,14 @@ func (s *sSysConfig) GetLoadLog(ctx context.Context) (conf *model.LogConfig, err
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
// GetLoadServeLog 获取本地服务日志配置
|
||||
func (s *sSysConfig) GetLoadServeLog(ctx context.Context) (conf *model.ServeLogConfig, err error) {
|
||||
if err = g.Cfg().MustGet(ctx, "hotgo.serveLog").Struct(&conf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
// GetConfigByGroup 获取指定分组的配置
|
||||
func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in sysin.GetConfigInp) (*sysin.GetConfigModel, error) {
|
||||
if in.Group == "" {
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/crons"
|
||||
@@ -18,6 +19,7 @@ import (
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/validate"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type sSysCron struct{}
|
||||
@@ -181,3 +183,20 @@ func (s *sSysCron) List(ctx context.Context, in sysin.CronListInp) (list []*sysi
|
||||
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
// OnlineExec 在线执行
|
||||
func (s *sSysCron) OnlineExec(ctx context.Context, in sysin.OnlineExecInp) (err error) {
|
||||
var data *entity.SysCron
|
||||
err = dao.SysCron.Ctx(ctx).Where(dao.SysCron.Columns().Id, in.Id).Scan(&data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if data == nil {
|
||||
return gerror.New("定时任务不存在")
|
||||
}
|
||||
|
||||
newCtx := context.WithValue(gctx.New(), consts.ContextKeyCronArgs, strings.Split(data.Params, consts.CronSplitStr))
|
||||
|
||||
return crons.Once(newCtx, data)
|
||||
}
|
||||
|
@@ -63,7 +63,6 @@ func (s *sSysDictType) Tree(ctx context.Context) (list []g.Map, err error) {
|
||||
|
||||
// Delete 删除
|
||||
func (s *sSysDictType) Delete(ctx context.Context, in sysin.DictTypeDeleteInp) error {
|
||||
|
||||
var (
|
||||
models *entity.SysDictType
|
||||
)
|
||||
@@ -72,7 +71,7 @@ func (s *sSysDictType) Delete(ctx context.Context, in sysin.DictTypeDeleteInp) e
|
||||
return err
|
||||
}
|
||||
|
||||
if models.Id < 1 {
|
||||
if models == nil {
|
||||
return gerror.New("数据不存在或已删除!")
|
||||
}
|
||||
|
||||
|
@@ -60,7 +60,7 @@ func (s *sSysLog) Export(ctx context.Context, in sysin.LogListInp) (err error) {
|
||||
|
||||
var (
|
||||
titleList = []string{"ID", "应用", "提交类型", "模块", "提交url", "ip地址", "报错code", "报错信息", "对外id", "请求耗时", "创建时间", "用户", "访问地"}
|
||||
fileName = "全局日志导出-" + gctx.CtxId(ctx) + ".xlsx"
|
||||
fileName = "访问日志导出-" + gctx.CtxId(ctx) + ".xlsx"
|
||||
sheetName = "HotGo"
|
||||
exportList []exportImage
|
||||
row exportImage
|
||||
@@ -97,15 +97,9 @@ func (s *sSysLog) Export(ctx context.Context, in sysin.LogListInp) (err error) {
|
||||
}
|
||||
|
||||
// RealWrite 真实写入
|
||||
func (s *sSysLog) RealWrite(ctx context.Context, commonLog entity.SysLog) error {
|
||||
result, err := dao.SysLog.Ctx(ctx).Data(commonLog).Insert()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = result.LastInsertId(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
func (s *sSysLog) RealWrite(ctx context.Context, commonLog entity.SysLog) (err error) {
|
||||
_, err = dao.SysLog.Ctx(ctx).Data(commonLog).Insert()
|
||||
return
|
||||
}
|
||||
|
||||
// AutoLog 根据配置自动记录请求日志
|
||||
@@ -129,48 +123,31 @@ func (s *sSysLog) AutoLog(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
if config.Queue {
|
||||
q, err := queue.InstanceProducer()
|
||||
if err != nil {
|
||||
queue.FatalLog(ctx, "queue.InstanceProducer err:%+v", err)
|
||||
return err
|
||||
}
|
||||
mqMsg, err := q.SendMsg(consts.QueueLogTopic, gconv.String(data))
|
||||
queue.ProducerLog(ctx, consts.QueueLogTopic, mqMsg.MsgId, err)
|
||||
return err
|
||||
return queue.Push(consts.QueueLogTopic, data)
|
||||
}
|
||||
return s.RealWrite(ctx, data)
|
||||
}
|
||||
|
||||
// QueueJob 队列消费
|
||||
func (s *sSysLog) QueueJob(ctx context.Context, mqMsg queue.MqMsg) (err error) {
|
||||
var data entity.SysLog
|
||||
if err = json.Unmarshal(mqMsg.Body, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.RealWrite(ctx, data)
|
||||
}
|
||||
|
||||
// AnalysisLog 解析日志数据
|
||||
func (s *sSysLog) AnalysisLog(ctx context.Context) entity.SysLog {
|
||||
var (
|
||||
modelContext = contexts.Get(ctx)
|
||||
response = modelContext.Response
|
||||
user = modelContext.User
|
||||
request = ghttp.RequestFromCtx(ctx)
|
||||
module = modelContext.Module
|
||||
clientIp = request.GetClientIp()
|
||||
postData = gjson.New(consts.NilJsonToString)
|
||||
getData = gjson.New(consts.NilJsonToString)
|
||||
headerData = gjson.New(consts.NilJsonToString)
|
||||
data = entity.SysLog{}
|
||||
memberId int64 = 0
|
||||
errorCode = 0
|
||||
errorMsg = ""
|
||||
errorData = gjson.New(consts.NilJsonToString)
|
||||
traceID = ""
|
||||
timestamp int64 = 0
|
||||
appId = ""
|
||||
modelContext = contexts.Get(ctx)
|
||||
response = modelContext.Response
|
||||
user = modelContext.User
|
||||
request = ghttp.RequestFromCtx(ctx)
|
||||
module = modelContext.Module
|
||||
clientIp = location.GetClientIp(request)
|
||||
postData = gjson.New(request.GetBodyString())
|
||||
getData = gjson.New(request.URL.Query())
|
||||
headerData = gjson.New(consts.NilJsonToString)
|
||||
errorData = gjson.New(consts.NilJsonToString)
|
||||
data entity.SysLog
|
||||
memberId int64
|
||||
errorCode int
|
||||
errorMsg string
|
||||
traceID string
|
||||
timestamp int64
|
||||
appId string
|
||||
)
|
||||
|
||||
// 响应数据
|
||||
@@ -190,17 +167,14 @@ func (s *sSysLog) AnalysisLog(ctx context.Context) entity.SysLog {
|
||||
}
|
||||
|
||||
// post参数
|
||||
if gconv.String(request.PostForm) != "" {
|
||||
postData = gjson.New(gconv.String(request.PostForm))
|
||||
postForm := gjson.New(gconv.String(request.PostForm)).Map()
|
||||
if len(postForm) > 0 {
|
||||
for k, v := range postForm {
|
||||
postData.MustAppend(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
if postData.IsNil() {
|
||||
postData = gjson.New(request.GetBodyString())
|
||||
}
|
||||
|
||||
// get参数
|
||||
if len(request.URL.Query()) > 0 {
|
||||
getData = gjson.New(request.URL.Query())
|
||||
if postData.IsNil() || len(postData.Map()) == 0 {
|
||||
postData = gjson.New(consts.NilJsonToString)
|
||||
}
|
||||
|
||||
// 当前登录用户
|
||||
@@ -210,22 +184,14 @@ func (s *sSysLog) AnalysisLog(ctx context.Context) entity.SysLog {
|
||||
}
|
||||
|
||||
var ipData = new(location.IpLocationData)
|
||||
//if validate.IsPublicIp(clientIp) {
|
||||
// ipData, err := location.GetLocation(ctx, clientIp)
|
||||
// if err != nil {
|
||||
// g.Log().Errorf(ctx, "location.GetLocation err:%+v", err)
|
||||
// }
|
||||
// if ipData == nil {
|
||||
// ipData = new(location.IpLocationData)
|
||||
// }
|
||||
//}
|
||||
|
||||
ipData, err := location.GetLocation(ctx, clientIp)
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "location.GetLocation err:%+v", err)
|
||||
}
|
||||
if ipData == nil {
|
||||
ipData = new(location.IpLocationData)
|
||||
if validate.IsPublicIp(clientIp) {
|
||||
ipData, err := location.GetLocation(ctx, clientIp)
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "location.GetLocation err:%+v", err)
|
||||
}
|
||||
if ipData == nil {
|
||||
ipData = new(location.IpLocationData)
|
||||
}
|
||||
}
|
||||
|
||||
data = entity.SysLog{
|
||||
|
190
server/internal/logic/sys/login_log.go
Normal file
190
server/internal/logic/sys/login_log.go
Normal file
@@ -0,0 +1,190 @@
|
||||
// Package sys
|
||||
// @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 sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"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/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/hgorm"
|
||||
"hotgo/internal/library/queue"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/convert"
|
||||
"hotgo/utility/excel"
|
||||
"hotgo/utility/useragent"
|
||||
)
|
||||
|
||||
type sSysLoginLog struct{}
|
||||
|
||||
func NewSysLoginLog() *sSysLoginLog {
|
||||
return &sSysLoginLog{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterSysLoginLog(NewSysLoginLog())
|
||||
}
|
||||
|
||||
// Model 登录日志Orm模型
|
||||
func (s *sSysLoginLog) Model(ctx context.Context) *gdb.Model {
|
||||
return dao.SysLoginLog.Ctx(ctx)
|
||||
}
|
||||
|
||||
// List 获取登录日志列表
|
||||
func (s *sSysLoginLog) List(ctx context.Context, in sysin.LoginLogListInp) (list []*sysin.LoginLogListModel, totalCount int, err error) {
|
||||
mod := dao.SysLoginLog.Ctx(ctx)
|
||||
|
||||
// 查询状态
|
||||
if in.Status > 0 {
|
||||
mod = mod.Where(dao.SysLoginLog.Columns().Status, in.Status)
|
||||
}
|
||||
|
||||
// 查询登录时间
|
||||
if len(in.LoginAt) == 2 {
|
||||
mod = mod.WhereBetween(dao.SysLoginLog.Columns().LoginAt, in.LoginAt[0], in.LoginAt[1])
|
||||
}
|
||||
|
||||
// 查询IP地址
|
||||
if in.SysLogIp != "" {
|
||||
mod = mod.Where("sysLog."+dao.SysLog.Columns().Ip, in.SysLogIp)
|
||||
}
|
||||
|
||||
// 用户名
|
||||
if in.Username != "" {
|
||||
mod = mod.Where(dao.SysLoginLog.Columns().Username, in.Username)
|
||||
}
|
||||
|
||||
// 关联表sysLog
|
||||
mod = mod.LeftJoin(hgorm.GenJoinOnRelation(
|
||||
dao.SysLoginLog.Table(), dao.SysLoginLog.Columns().ReqId, // 主表表名,关联条件
|
||||
dao.SysLog.Table(), "sysLog", dao.SysLog.Columns().ReqId, // 关联表表名,别名,关联条件
|
||||
)...)
|
||||
|
||||
totalCount, err = mod.Clone().Count(1)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
if totalCount == 0 {
|
||||
return list, totalCount, nil
|
||||
}
|
||||
|
||||
//关联表select
|
||||
fields, err := hgorm.GenJoinSelect(ctx, sysin.LoginLogListModel{}, dao.SysLoginLog, []*hgorm.Join{
|
||||
{Dao: dao.SysLog, Alias: "sysLog"},
|
||||
})
|
||||
|
||||
if err = mod.Fields(fields).Handler(hgorm.HandlerFilterAuth).Page(in.Page, in.PerPage).OrderDesc(dao.SysLoginLog.Columns().Id).Scan(&list); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
for _, v := range list {
|
||||
// 获取省市编码对应的地区名称
|
||||
region, err := dao.SysProvinces.GetRegion(ctx, v.SysLogProvinceId, v.SysLogCityId)
|
||||
if err != nil {
|
||||
return list, totalCount, err
|
||||
}
|
||||
v.Region = region
|
||||
v.Os = useragent.GetOs(v.SysLogUserAgent)
|
||||
v.Browser = useragent.GetBrowser(v.SysLogUserAgent)
|
||||
}
|
||||
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
// Export 导出登录日志
|
||||
func (s *sSysLoginLog) Export(ctx context.Context, in sysin.LoginLogListInp) (err error) {
|
||||
list, totalCount, err := s.List(ctx, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 字段的排序是依据tags的字段顺序,如果你不想使用默认的排序方式,可以直接定义 tags = []string{"字段名称", "字段名称2", ...}
|
||||
tags, err := convert.GetEntityDescTags(sysin.LoginLogExportModel{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
fileName = "导出登录日志-" + gctx.CtxId(ctx) + ".xlsx"
|
||||
sheetName = fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list))
|
||||
exports []sysin.LoginLogExportModel
|
||||
)
|
||||
|
||||
err = gconv.Scan(list, &exports)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = excel.ExportByStructs(ctx, tags, exports, fileName, sheetName); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Delete 删除登录日志
|
||||
func (s *sSysLoginLog) Delete(ctx context.Context, in sysin.LoginLogDeleteInp) (err error) {
|
||||
_, err = dao.SysLoginLog.Ctx(ctx).Where(dao.SysLoginLog.Columns().Id, in.Id).Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// View 获取登录日志指定信息
|
||||
func (s *sSysLoginLog) View(ctx context.Context, in sysin.LoginLogViewInp) (res *sysin.LoginLogViewModel, err error) {
|
||||
if err = dao.SysLoginLog.Ctx(ctx).Where(dao.SysLoginLog.Columns().Id, in.Id).Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Push 推送登录日志
|
||||
func (s *sSysLoginLog) Push(ctx context.Context, in sysin.LoginLogPushInp) {
|
||||
var models entity.SysLoginLog
|
||||
models.ReqId = gctx.CtxId(ctx)
|
||||
models.MemberId = in.Response.UserId
|
||||
models.Username = in.Input.Username
|
||||
models.LoginAt = gtime.Now()
|
||||
models.Status = consts.StatusEnabled
|
||||
|
||||
if in.Err != nil {
|
||||
models.Status = consts.StatusDisable
|
||||
models.ErrMsg = in.Err.Error()
|
||||
}
|
||||
|
||||
models.Response = gjson.New(consts.NilJsonToString)
|
||||
if in.Response != nil && in.Response.UserId > 0 {
|
||||
models.Response = gjson.New(in.Response)
|
||||
}
|
||||
|
||||
if err := queue.Push(consts.QueueLoginLogTopic, models); err != nil {
|
||||
g.Log().Warningf(ctx, "sSysLoginLog.Push err:%+v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RealWrite 真实写入
|
||||
func (s *sSysLoginLog) RealWrite(ctx context.Context, models entity.SysLoginLog) (err error) {
|
||||
_, err = dao.SysLoginLog.Ctx(ctx).Data(models).Insert()
|
||||
return
|
||||
}
|
@@ -9,11 +9,16 @@ package sys
|
||||
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/util/gconv"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/hgorm"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/tree"
|
||||
"hotgo/utility/validate"
|
||||
)
|
||||
|
||||
@@ -27,10 +32,48 @@ func init() {
|
||||
service.RegisterSysProvinces(NewSysProvinces())
|
||||
}
|
||||
|
||||
// Tree 关系树选项列表
|
||||
func (s *sSysProvinces) Tree(ctx context.Context) (list []g.Map, err error) {
|
||||
var models []*entity.SysProvinces
|
||||
if err = dao.SysProvinces.Ctx(ctx).Order("pid asc,id asc,sort asc").Scan(&models); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, err
|
||||
}
|
||||
|
||||
list = gconv.SliceMap(models)
|
||||
for k, v := range list {
|
||||
list[k]["key"] = v["id"]
|
||||
list[k]["label"] = v["title"]
|
||||
}
|
||||
|
||||
return tree.GenTree(list), nil
|
||||
}
|
||||
|
||||
// Delete 删除
|
||||
func (s *sSysProvinces) Delete(ctx context.Context, in sysin.ProvincesDeleteInp) error {
|
||||
|
||||
_, err := dao.SysProvinces.Ctx(ctx).Where("id", in.Id).Delete()
|
||||
var (
|
||||
models *entity.SysProvinces
|
||||
)
|
||||
err := dao.SysProvinces.Ctx(ctx).Where("id", in.Id).Scan(&models)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if models == nil {
|
||||
return gerror.New("数据不存在或已删除!")
|
||||
}
|
||||
|
||||
pidExist, err := dao.SysProvinces.Ctx(ctx).Where("pid", models.Id).One()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
if !pidExist.IsEmpty() {
|
||||
return gerror.New("请先删除该地区下得所有子级!")
|
||||
}
|
||||
|
||||
_, err = dao.SysProvinces.Ctx(ctx).Where("id", in.Id).Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
@@ -43,12 +86,32 @@ func (s *sSysProvinces) Delete(ctx context.Context, in sysin.ProvincesDeleteInp)
|
||||
func (s *sSysProvinces) Edit(ctx context.Context, in sysin.ProvincesEditInp) (err error) {
|
||||
if in.Title == "" {
|
||||
err = gerror.New("标题不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
if in.Id <= 0 {
|
||||
err = gerror.New("地区Id必须大于0")
|
||||
return
|
||||
}
|
||||
|
||||
// 关系树
|
||||
in.Pid, in.Level, in.Tree, err = hgorm.GenSubTree(ctx, dao.SysProvinces, in.Pid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isUpdate := false
|
||||
models, err := s.View(ctx, sysin.ProvincesViewInp{Id: in.Id})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if models != nil {
|
||||
isUpdate = true
|
||||
}
|
||||
|
||||
// 修改
|
||||
in.UpdatedAt = gtime.Now()
|
||||
if in.Id > 0 {
|
||||
if isUpdate {
|
||||
_, err = dao.SysProvinces.Ctx(ctx).Where("id", in.Id).Data(in).Update()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
@@ -59,7 +122,6 @@ func (s *sSysProvinces) Edit(ctx context.Context, in sysin.ProvincesEditInp) (er
|
||||
}
|
||||
|
||||
// 新增
|
||||
in.CreatedAt = gtime.Now()
|
||||
_, err = dao.SysProvinces.Ctx(ctx).Data(in).Insert()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
@@ -97,19 +159,14 @@ func (s *sSysProvinces) Status(ctx context.Context, in sysin.ProvincesStatusInp)
|
||||
}
|
||||
|
||||
// MaxSort 最大排序
|
||||
func (s *sSysProvinces) MaxSort(ctx context.Context, in sysin.ProvincesMaxSortInp) (*sysin.ProvincesMaxSortModel, error) {
|
||||
var res sysin.ProvincesMaxSortModel
|
||||
|
||||
if in.Id > 0 {
|
||||
if err := dao.SysProvinces.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
func (s *sSysProvinces) MaxSort(ctx context.Context, in sysin.ProvincesMaxSortInp) (res *sysin.ProvincesMaxSortModel, err error) {
|
||||
if err = dao.SysProvinces.Ctx(ctx).Fields(dao.SysProvinces.Columns().Sort).OrderDesc(dao.SysProvinces.Columns().Sort).Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.Sort = res.Sort + 10
|
||||
|
||||
return &res, nil
|
||||
res.Sort = res.Sort + g.Cfg().MustGet(ctx, "hotgo.admin.maxSortIncrement").Int()
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// View 获取指定字典类型信息
|
||||
@@ -126,12 +183,10 @@ func (s *sSysProvinces) View(ctx context.Context, in sysin.ProvincesViewInp) (re
|
||||
func (s *sSysProvinces) List(ctx context.Context, in sysin.ProvincesListInp) (list []*sysin.ProvincesListModel, totalCount int, err error) {
|
||||
mod := dao.SysProvinces.Ctx(ctx)
|
||||
|
||||
// 访问路径
|
||||
if in.Title != "" {
|
||||
mod = mod.WhereLike("title", "%"+in.Title+"%")
|
||||
}
|
||||
|
||||
// 请求方式
|
||||
if in.Status > 0 {
|
||||
mod = mod.Where("status", in.Status)
|
||||
}
|
||||
@@ -153,3 +208,53 @@ func (s *sSysProvinces) List(ctx context.Context, in sysin.ProvincesListInp) (li
|
||||
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
// ChildrenList 获取省市区下级列表
|
||||
func (s *sSysProvinces) ChildrenList(ctx context.Context, in sysin.ProvincesChildrenListInp) (list []*sysin.ProvincesChildrenListModel, totalCount int, err error) {
|
||||
mod := dao.SysProvinces.Ctx(ctx)
|
||||
|
||||
if in.Title != "" {
|
||||
mod = mod.WhereLike("title", "%"+in.Title+"%")
|
||||
}
|
||||
|
||||
if in.Pid > 0 {
|
||||
mod = mod.Where("pid", in.Pid)
|
||||
}
|
||||
|
||||
if in.Id > 0 {
|
||||
mod = mod.Where("id", in.Id)
|
||||
}
|
||||
|
||||
totalCount, err = mod.Count()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
if totalCount == 0 {
|
||||
return list, totalCount, nil
|
||||
}
|
||||
|
||||
if err = mod.Page(in.Page, in.PerPage).Order("sort asc,id desc").Scan(&list); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
// UniqueId 获取省市区下级列表
|
||||
func (s *sSysProvinces) UniqueId(ctx context.Context, in sysin.ProvincesUniqueIdInp) (res *sysin.ProvincesUniqueIdModel, err error) {
|
||||
res = new(sysin.ProvincesUniqueIdModel)
|
||||
res.IsUnique = true
|
||||
if in.NewId == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if err = hgorm.IsUnique(ctx, dao.SysProvinces, g.Map{dao.Test.Columns().Id: in.NewId}, "", in.OldId); err != nil {
|
||||
res.IsUnique = false
|
||||
return res, nil
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
148
server/internal/logic/sys/serve_log.go
Normal file
148
server/internal/logic/sys/serve_log.go
Normal file
@@ -0,0 +1,148 @@
|
||||
// Package sys
|
||||
// @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 sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/hgorm"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/convert"
|
||||
"hotgo/utility/excel"
|
||||
)
|
||||
|
||||
type sSysServeLog struct{}
|
||||
|
||||
func NewSysServeLog() *sSysServeLog {
|
||||
return &sSysServeLog{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterSysServeLog(NewSysServeLog())
|
||||
}
|
||||
|
||||
// Model 服务日志Orm模型
|
||||
func (s *sSysServeLog) Model(ctx context.Context) *gdb.Model {
|
||||
return dao.SysServeLog.Ctx(ctx)
|
||||
}
|
||||
|
||||
// List 获取服务日志列表
|
||||
func (s *sSysServeLog) List(ctx context.Context, in sysin.ServeLogListInp) (list []*sysin.ServeLogListModel, totalCount int, err error) {
|
||||
mod := dao.SysServeLog.Ctx(ctx)
|
||||
|
||||
// 查询链路ID
|
||||
if in.TraceId != "" {
|
||||
mod = mod.Where(dao.SysServeLog.Columns().TraceId, in.TraceId)
|
||||
}
|
||||
|
||||
// 查询日志级别
|
||||
if in.LevelFormat != "" {
|
||||
mod = mod.WhereLike(dao.SysServeLog.Columns().LevelFormat, in.LevelFormat)
|
||||
}
|
||||
|
||||
// 查询触发时间(ns)
|
||||
if len(in.TriggerNs) == 2 {
|
||||
mod = mod.WhereBetween(dao.SysServeLog.Columns().TriggerNs, in.TriggerNs[0], in.TriggerNs[1])
|
||||
}
|
||||
|
||||
// 查询创建时间
|
||||
if len(in.CreatedAt) == 2 {
|
||||
mod = mod.WhereBetween(dao.SysServeLog.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
|
||||
}
|
||||
|
||||
// 关联表sysLog
|
||||
mod = mod.LeftJoin(hgorm.GenJoinOnRelation(
|
||||
dao.SysServeLog.Table(), dao.SysServeLog.Columns().TraceId, // 主表表名,关联条件
|
||||
dao.SysLog.Table(), "sysLog", dao.SysLog.Columns().ReqId, // 关联表表名,别名,关联条件
|
||||
)...)
|
||||
|
||||
totalCount, err = mod.Clone().Count(1)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
if totalCount == 0 {
|
||||
return list, totalCount, nil
|
||||
}
|
||||
|
||||
//关联表select
|
||||
fields, err := hgorm.GenJoinSelect(ctx, sysin.ServeLogListModel{}, dao.SysServeLog, []*hgorm.Join{
|
||||
{Dao: dao.SysLog, Alias: "sysLog"},
|
||||
})
|
||||
if err = mod.Fields(fields).Handler(hgorm.HandlerFilterAuth).Page(in.Page, in.PerPage).OrderDesc(dao.SysServeLog.Columns().Id).Scan(&list); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
// Export 导出服务日志
|
||||
func (s *sSysServeLog) Export(ctx context.Context, in sysin.ServeLogListInp) (err error) {
|
||||
list, totalCount, err := s.List(ctx, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 字段的排序是依据tags的字段顺序,如果你不想使用默认的排序方式,可以直接定义 tags = []string{"字段名称", "字段名称2", ...}
|
||||
tags, err := convert.GetEntityDescTags(sysin.ServeLogExportModel{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
fileName = "导出服务日志-" + gctx.CtxId(ctx) + ".xlsx"
|
||||
sheetName = fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list))
|
||||
exports []sysin.ServeLogExportModel
|
||||
)
|
||||
|
||||
err = gconv.Scan(list, &exports)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = excel.ExportByStructs(ctx, tags, exports, fileName, sheetName); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Delete 删除服务日志
|
||||
func (s *sSysServeLog) Delete(ctx context.Context, in sysin.ServeLogDeleteInp) (err error) {
|
||||
_, err = dao.SysServeLog.Ctx(ctx).Where(dao.SysServeLog.Columns().Id, in.Id).Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// View 获取服务日志指定信息
|
||||
func (s *sSysServeLog) View(ctx context.Context, in sysin.ServeLogViewInp) (res *sysin.ServeLogViewModel, err error) {
|
||||
if err = dao.SysServeLog.Ctx(ctx).Where(dao.SysServeLog.Columns().Id, in.Id).Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// RealWrite 真实写入
|
||||
func (s *sSysServeLog) RealWrite(ctx context.Context, models entity.SysServeLog) (err error) {
|
||||
_, err = dao.SysServeLog.Ctx(ctx).Data(models).Insert()
|
||||
return
|
||||
}
|
343
server/internal/logic/sys/sms_log.go
Normal file
343
server/internal/logic/sys/sms_log.go
Normal file
@@ -0,0 +1,343 @@
|
||||
// Package sys
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"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/util/grand"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/location"
|
||||
"hotgo/internal/library/sms/aliyun"
|
||||
"hotgo/internal/model"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/validate"
|
||||
"time"
|
||||
)
|
||||
|
||||
type sSysSmsLog struct{}
|
||||
|
||||
func NewSysSmsLog() *sSysSmsLog {
|
||||
return &sSysSmsLog{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterSysSmsLog(NewSysSmsLog())
|
||||
}
|
||||
|
||||
// Delete 删除
|
||||
func (s *sSysSmsLog) Delete(ctx context.Context, in sysin.SmsLogDeleteInp) error {
|
||||
_, err := dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Delete()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Edit 修改/新增
|
||||
func (s *sSysSmsLog) Edit(ctx context.Context, in sysin.SmsLogEditInp) (err error) {
|
||||
if in.Ip == "" {
|
||||
err = gerror.New("ip不能为空")
|
||||
return err
|
||||
}
|
||||
|
||||
// 修改
|
||||
in.UpdatedAt = gtime.Now()
|
||||
if in.Id > 0 {
|
||||
_, err = dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Data(in).Update()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 新增
|
||||
in.CreatedAt = gtime.Now()
|
||||
_, err = dao.SysSmsLog.Ctx(ctx).Data(in).Insert()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status 更新部门状态
|
||||
func (s *sSysSmsLog) Status(ctx context.Context, in sysin.SmsLogStatusInp) (err error) {
|
||||
if in.Id <= 0 {
|
||||
err = gerror.New("ID不能为空")
|
||||
return err
|
||||
}
|
||||
|
||||
if in.Status <= 0 {
|
||||
err = gerror.New("状态不能为空")
|
||||
return err
|
||||
}
|
||||
|
||||
if !validate.InSliceInt(consts.StatusMap, in.Status) {
|
||||
err = gerror.New("状态不正确")
|
||||
return err
|
||||
}
|
||||
|
||||
// 修改
|
||||
in.UpdatedAt = gtime.Now()
|
||||
_, err = dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Data("status", in.Status).Update()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MaxSort 最大排序
|
||||
func (s *sSysSmsLog) MaxSort(ctx context.Context, in sysin.SmsLogMaxSortInp) (*sysin.SmsLogMaxSortModel, error) {
|
||||
var res sysin.SmsLogMaxSortModel
|
||||
if in.Id > 0 {
|
||||
if err := dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
res.Sort = res.Sort + 10
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// View 获取指定字典类型信息
|
||||
func (s *sSysSmsLog) View(ctx context.Context, in sysin.SmsLogViewInp) (res *sysin.SmsLogViewModel, err error) {
|
||||
if err = dao.SysSmsLog.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// List 获取列表
|
||||
func (s *sSysSmsLog) List(ctx context.Context, in sysin.SmsLogListInp) (list []*sysin.SmsLogListModel, totalCount int, err error) {
|
||||
mod := dao.SysSmsLog.Ctx(ctx)
|
||||
|
||||
if in.Status > 0 {
|
||||
mod = mod.Where("status", in.Status)
|
||||
}
|
||||
|
||||
totalCount, err = mod.Count()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
if totalCount == 0 {
|
||||
return list, totalCount, nil
|
||||
}
|
||||
|
||||
if err = mod.Page(int(in.Page), int(in.PerPage)).Order("id desc").Scan(&list); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
return list, totalCount, err
|
||||
}
|
||||
|
||||
// SendCode 发送验证码
|
||||
func (s *sSysSmsLog) SendCode(ctx context.Context, in sysin.SendCodeInp) (err error) {
|
||||
if in.Event == "" {
|
||||
return gerror.New("事件不能为空")
|
||||
}
|
||||
if in.Mobile == "" {
|
||||
return gerror.New("手机号不能为空")
|
||||
}
|
||||
|
||||
var (
|
||||
models *entity.SysSmsLog
|
||||
)
|
||||
if err = dao.SysSmsLog.Ctx(ctx).Where("event", in.Event).Where("mobile", in.Mobile).Scan(&models); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
config, err := service.SysConfig().GetSms(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
in.Template, err = s.GetTemplate(ctx, in.Event, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.AllowSend(ctx, models, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if in.Code == "" {
|
||||
in.Code = grand.Digits(4)
|
||||
}
|
||||
|
||||
switch config.SmsDrive {
|
||||
case consts.SmsDriveAliYun:
|
||||
err = aliyun.SendCode(ctx, in, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case consts.SmsDriveTencent:
|
||||
return gerror.Newf("暂不支持短信驱动:%v", config.SmsDrive)
|
||||
default:
|
||||
return gerror.Newf("暂不支持短信驱动:%v", config.SmsDrive)
|
||||
}
|
||||
|
||||
var data = new(entity.SysSmsLog)
|
||||
data.Event = in.Event
|
||||
data.Mobile = in.Mobile
|
||||
data.Code = in.Code
|
||||
data.Ip = location.GetClientIp(ghttp.RequestFromCtx(ctx))
|
||||
data.Status = consts.SmsStatusNotUsed
|
||||
data.CreatedAt = gtime.Now()
|
||||
data.UpdatedAt = gtime.Now()
|
||||
|
||||
_, err = dao.SysSmsLog.Ctx(ctx).Data(data).Insert()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTemplate 获取指定短信模板
|
||||
func (s *sSysSmsLog) GetTemplate(ctx context.Context, template string, config *model.SmsConfig) (val string, err error) {
|
||||
if template == "" {
|
||||
return "", gerror.New("模板不能为空")
|
||||
}
|
||||
if config == nil {
|
||||
config, err = service.SysConfig().GetSms(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
switch config.SmsDrive {
|
||||
case consts.SmsDriveAliYun:
|
||||
if len(config.SmsAliyunTemplate) == 0 {
|
||||
return "", gerror.New("管理员还没有配置任何模板!")
|
||||
}
|
||||
|
||||
for _, v := range config.SmsAliyunTemplate {
|
||||
if v.Key == template {
|
||||
return v.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
case consts.SmsDriveTencent:
|
||||
return "", gerror.Newf("暂不支持短信驱动:%v", config.SmsDrive)
|
||||
default:
|
||||
return "", gerror.Newf("暂不支持短信驱动:%v", config.SmsDrive)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// AllowSend 是否允许发送
|
||||
func (s *sSysSmsLog) AllowSend(ctx context.Context, models *entity.SysSmsLog, config *model.SmsConfig) (err error) {
|
||||
if models == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if config == nil {
|
||||
config, err = service.SysConfig().GetSms(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if gtime.Now().Before(models.CreatedAt.Add(time.Second * time.Duration(config.SmsMinInterval))) {
|
||||
return gerror.New("发送频繁,请稍后再试!")
|
||||
}
|
||||
|
||||
if config.SmsMaxIpLimit > 0 {
|
||||
count, err := dao.SysSmsLog.NowDayCount(ctx, models.Event, models.Mobile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if count >= config.SmsMaxIpLimit {
|
||||
return gerror.New("今天发送短信过多,请次日后再试!")
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// VerifyCode 效验验证码
|
||||
func (s *sSysSmsLog) VerifyCode(ctx context.Context, in sysin.VerifyCodeInp) (err error) {
|
||||
if in.Event == "" {
|
||||
return gerror.New("事件不能为空")
|
||||
}
|
||||
if in.Mobile == "" {
|
||||
return gerror.New("手机号不能为空")
|
||||
}
|
||||
|
||||
config, err := service.SysConfig().GetSms(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
models *entity.SysSmsLog
|
||||
)
|
||||
if err = dao.SysSmsLog.Ctx(ctx).Where("event", in.Event).Where("mobile", in.Mobile).Order("id desc").Scan(&models); err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
if models == nil {
|
||||
return gerror.New("验证码错误")
|
||||
}
|
||||
|
||||
if models.Times >= 10 {
|
||||
return gerror.New("验证码错误次数过多,请重新发送!")
|
||||
}
|
||||
|
||||
if in.Event != consts.SmsTemplateCode {
|
||||
if models.Status == consts.SmsStatusUsed {
|
||||
return gerror.New("验证码已使用,请重新发送!")
|
||||
}
|
||||
}
|
||||
|
||||
if gtime.Now().After(models.CreatedAt.Add(time.Second * time.Duration(config.SmsCodeExpire))) {
|
||||
return gerror.New("验证码已过期,请重新发送")
|
||||
}
|
||||
|
||||
if models.Code != in.Code {
|
||||
_, err = dao.SysSmsLog.Ctx(ctx).Where("id", models.Id).Increment("times", 1)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
return gerror.New("验证码错误!")
|
||||
}
|
||||
|
||||
_, err = dao.SysSmsLog.Ctx(ctx).Where("id", models.Id).Data(g.Map{
|
||||
"times": models.Times + 1,
|
||||
"status": consts.SmsStatusUsed,
|
||||
"updated_at": gtime.Now(),
|
||||
}).Update()
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, consts.ErrorORM)
|
||||
return err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
@@ -82,6 +82,13 @@ type LogConfig struct {
|
||||
SkipCode []string `json:"skipCode"`
|
||||
}
|
||||
|
||||
// ServeLogConfig 服务日志配置
|
||||
type ServeLogConfig struct {
|
||||
Switch bool `json:"switch"`
|
||||
Queue bool `json:"queue"`
|
||||
LevelFormat []string `json:"levelFormat"`
|
||||
}
|
||||
|
||||
// GenerateAppCrudTemplate curd模板
|
||||
type GenerateAppCrudTemplate struct {
|
||||
Group string `json:"group"`
|
||||
|
@@ -20,6 +20,8 @@ type AdminDept struct {
|
||||
Leader interface{} // 负责人
|
||||
Phone interface{} // 联系电话
|
||||
Email interface{} // 邮箱
|
||||
Level interface{} // 关系树等级
|
||||
Tree interface{} // 关系树
|
||||
Sort interface{} // 排序
|
||||
Status interface{} // 部门状态
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
type SysLog struct {
|
||||
g.Meta `orm:"table:hg_sys_log, do:true"`
|
||||
Id interface{} // 日志ID
|
||||
ReqId interface{} // 对外ID
|
||||
AppId interface{} // 应用ID
|
||||
MerchantId interface{} // 商户ID
|
||||
MemberId interface{} // 用户ID
|
||||
@@ -29,10 +30,9 @@ type SysLog struct {
|
||||
ErrorCode interface{} // 报错code
|
||||
ErrorMsg interface{} // 报错信息
|
||||
ErrorData *gjson.Json // 报错日志
|
||||
ReqId interface{} // 对外ID
|
||||
Timestamp interface{} // 响应时间
|
||||
UserAgent interface{} // UA信息
|
||||
TakeUpTime interface{} // 请求耗时
|
||||
Timestamp interface{} // 响应时间
|
||||
Status interface{} // 状态
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 修改时间
|
||||
|
26
server/internal/model/do/sys_login_log.go
Normal file
26
server/internal/model/do/sys_login_log.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// =================================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// SysLoginLog is the golang structure of table hg_sys_login_log for DAO operations like Where/Data.
|
||||
type SysLoginLog struct {
|
||||
g.Meta `orm:"table:hg_sys_login_log, do:true"`
|
||||
Id interface{} // 日志ID
|
||||
ReqId interface{} // 请求ID
|
||||
MemberId interface{} // 用户ID
|
||||
Username interface{} // 用户名
|
||||
Response *gjson.Json // 响应数据
|
||||
LoginAt *gtime.Time // 登录时间
|
||||
ErrMsg interface{} // 错误提示
|
||||
Status interface{} // 状态
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 修改时间
|
||||
}
|
@@ -11,20 +11,17 @@ import (
|
||||
|
||||
// SysProvinces is the golang structure of table hg_sys_provinces for DAO operations like Where/Data.
|
||||
type SysProvinces struct {
|
||||
g.Meta `orm:"table:hg_sys_provinces, do:true"`
|
||||
Id interface{} // 省市区ID
|
||||
Title interface{} // 栏目名称
|
||||
ShortTitle interface{} // 缩写
|
||||
Areacode interface{} // 区域编码
|
||||
Zipcode interface{} // 邮政编码
|
||||
Pinyin interface{} // 拼音
|
||||
Lng interface{} // 经度
|
||||
Lat interface{} // 纬度
|
||||
Pid interface{} // 父栏目
|
||||
Level interface{} // 关系树等级
|
||||
Tree interface{} // 关系
|
||||
Sort interface{} // 排序
|
||||
Status interface{} // 状态
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
g.Meta `orm:"table:hg_sys_provinces, do:true"`
|
||||
Id interface{} // 省市区ID
|
||||
Title interface{} // 栏目名称
|
||||
Pinyin interface{} // 拼音
|
||||
Lng interface{} // 经度
|
||||
Lat interface{} // 纬度
|
||||
Pid interface{} // 父栏目
|
||||
Level interface{} // 关系树等级
|
||||
Tree interface{} // 关系
|
||||
Sort interface{} // 排序
|
||||
Status interface{} // 状态
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
}
|
||||
|
26
server/internal/model/do/sys_serve_log.go
Normal file
26
server/internal/model/do/sys_serve_log.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// =================================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// SysServeLog is the golang structure of table hg_sys_serve_log for DAO operations like Where/Data.
|
||||
type SysServeLog struct {
|
||||
g.Meta `orm:"table:hg_sys_serve_log, do:true"`
|
||||
Id interface{} // 日志ID
|
||||
TraceId interface{} // 链路ID
|
||||
LevelFormat interface{} // 日志级别
|
||||
Content interface{} // 日志内容
|
||||
Stack *gjson.Json // 打印堆栈
|
||||
Line interface{} // 调用行
|
||||
TriggerNs interface{} // 触发时间(ns)
|
||||
Status interface{} // 状态
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 修改时间
|
||||
}
|
24
server/internal/model/do/sys_sms_log.go
Normal file
24
server/internal/model/do/sys_sms_log.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// =================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// SysSmsLog is the golang structure of table hg_sys_sms_log for DAO operations like Where/Data.
|
||||
type SysSmsLog struct {
|
||||
g.Meta `orm:"table:hg_sys_sms_log, do:true"`
|
||||
Id interface{} // 主键
|
||||
Event interface{} // 事件
|
||||
Mobile interface{} // 手机号
|
||||
Code interface{} // 验证码或短信内容
|
||||
Times interface{} // 验证次数
|
||||
Ip interface{} // ip地址
|
||||
Status interface{} // 状态(1未验证,2已验证)
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
}
|
@@ -18,6 +18,8 @@ type AdminDept struct {
|
||||
Leader string `json:"leader" description:"负责人"`
|
||||
Phone string `json:"phone" description:"联系电话"`
|
||||
Email string `json:"email" description:"邮箱"`
|
||||
Level int `json:"level" description:"关系树等级"`
|
||||
Tree string `json:"tree" description:"关系树"`
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
Status int `json:"status" description:"部门状态"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
// SysLog is the golang structure for table sys_log.
|
||||
type SysLog struct {
|
||||
Id int64 `json:"id" description:"日志ID"`
|
||||
ReqId string `json:"reqId" description:"对外ID"`
|
||||
AppId string `json:"appId" description:"应用ID"`
|
||||
MerchantId uint64 `json:"merchantId" description:"商户ID"`
|
||||
MemberId int64 `json:"memberId" description:"用户ID"`
|
||||
@@ -27,10 +28,9 @@ type SysLog struct {
|
||||
ErrorCode int `json:"errorCode" description:"报错code"`
|
||||
ErrorMsg string `json:"errorMsg" description:"报错信息"`
|
||||
ErrorData *gjson.Json `json:"errorData" description:"报错日志"`
|
||||
ReqId string `json:"reqId" description:"对外ID"`
|
||||
Timestamp int64 `json:"timestamp" description:"响应时间"`
|
||||
UserAgent string `json:"userAgent" description:"UA信息"`
|
||||
TakeUpTime int64 `json:"takeUpTime" description:"请求耗时"`
|
||||
Timestamp int64 `json:"timestamp" description:"响应时间"`
|
||||
Status int `json:"status" description:"状态"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" description:"修改时间"`
|
||||
|
24
server/internal/model/entity/sys_login_log.go
Normal file
24
server/internal/model/entity/sys_login_log.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// =================================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// SysLoginLog is the golang structure for table sys_login_log.
|
||||
type SysLoginLog struct {
|
||||
Id int64 `json:"id" description:"日志ID"`
|
||||
ReqId string `json:"reqId" description:"请求ID"`
|
||||
MemberId int64 `json:"memberId" description:"用户ID"`
|
||||
Username string `json:"username" description:"用户名"`
|
||||
Response *gjson.Json `json:"response" description:"响应数据"`
|
||||
LoginAt *gtime.Time `json:"loginAt" description:"登录时间"`
|
||||
ErrMsg string `json:"errMsg" description:"错误提示"`
|
||||
Status int `json:"status" description:"状态"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" description:"修改时间"`
|
||||
}
|
@@ -10,19 +10,16 @@ import (
|
||||
|
||||
// SysProvinces is the golang structure for table sys_provinces.
|
||||
type SysProvinces struct {
|
||||
Id int64 `json:"id" description:"省市区ID"`
|
||||
Title string `json:"title" description:"栏目名称"`
|
||||
ShortTitle string `json:"shortTitle" description:"缩写"`
|
||||
Areacode int `json:"areacode" description:"区域编码"`
|
||||
Zipcode int `json:"zipcode" description:"邮政编码"`
|
||||
Pinyin string `json:"pinyin" description:"拼音"`
|
||||
Lng string `json:"lng" description:"经度"`
|
||||
Lat string `json:"lat" description:"纬度"`
|
||||
Pid int64 `json:"pid" description:"父栏目"`
|
||||
Level int `json:"level" description:"关系树等级"`
|
||||
Tree string `json:"tree" description:"关系"`
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
Status int `json:"status" description:"状态"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"`
|
||||
Id int64 `json:"id" description:"省市区ID"`
|
||||
Title string `json:"title" description:"栏目名称"`
|
||||
Pinyin string `json:"pinyin" description:"拼音"`
|
||||
Lng string `json:"lng" description:"经度"`
|
||||
Lat string `json:"lat" description:"纬度"`
|
||||
Pid int64 `json:"pid" description:"父栏目"`
|
||||
Level int `json:"level" description:"关系树等级"`
|
||||
Tree string `json:"tree" description:"关系"`
|
||||
Sort int `json:"sort" description:"排序"`
|
||||
Status int `json:"status" description:"状态"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"`
|
||||
}
|
||||
|
24
server/internal/model/entity/sys_serve_log.go
Normal file
24
server/internal/model/entity/sys_serve_log.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// =================================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// SysServeLog is the golang structure for table sys_serve_log.
|
||||
type SysServeLog struct {
|
||||
Id int64 `json:"id" description:"日志ID"`
|
||||
TraceId string `json:"traceId" description:"链路ID"`
|
||||
LevelFormat string `json:"levelFormat" description:"日志级别"`
|
||||
Content string `json:"content" description:"日志内容"`
|
||||
Stack *gjson.Json `json:"stack" description:"打印堆栈"`
|
||||
Line string `json:"line" description:"调用行"`
|
||||
TriggerNs int64 `json:"triggerNs" description:"触发时间(ns)"`
|
||||
Status int `json:"status" description:"状态"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" description:"修改时间"`
|
||||
}
|
22
server/internal/model/entity/sys_sms_log.go
Normal file
22
server/internal/model/entity/sys_sms_log.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// SysSmsLog is the golang structure for table sys_sms_log.
|
||||
type SysSmsLog struct {
|
||||
Id int64 `json:"id" description:"主键"`
|
||||
Event string `json:"event" description:"事件"`
|
||||
Mobile string `json:"mobile" description:"手机号"`
|
||||
Code string `json:"code" description:"验证码或短信内容"`
|
||||
Times int64 `json:"times" description:"验证次数"`
|
||||
Ip string `json:"ip" description:"ip地址"`
|
||||
Status int `json:"status" description:"状态(1未验证,2已验证)"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"`
|
||||
}
|
@@ -46,7 +46,7 @@ func DefaultPage(ctx context.Context) int {
|
||||
// PageReq 分页
|
||||
type PageReq struct {
|
||||
Page int `json:"page" example:"10" d:"1" v:"min:1#页码最小值不能低于1" dc:"当前页码"`
|
||||
PerPage int `json:"pageSize" example:"1" d:"10" v:"min:1|max:100#|每页数量最小值不能低于1|最大值不能大于100" dc:"每页数量"`
|
||||
PerPage int `json:"pageSize" example:"1" d:"10" v:"min:1|max:200#|每页数量最小值不能低于1|最大值不能大于200" dc:"每页数量"`
|
||||
}
|
||||
type PageRes struct {
|
||||
PageReq
|
||||
|
@@ -59,3 +59,9 @@ type CronStatusInp struct {
|
||||
entity.SysCron
|
||||
}
|
||||
type CronStatusModel struct{}
|
||||
|
||||
// OnlineExecInp 在线执行
|
||||
type OnlineExecInp struct {
|
||||
entity.SysCron
|
||||
}
|
||||
type OnlineExecModel struct{}
|
||||
|
90
server/internal/model/input/sysin/login_log.go
Normal file
90
server/internal/model/input/sysin/login_log.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Package sysin
|
||||
// @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 sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/adminin"
|
||||
"hotgo/internal/model/input/form"
|
||||
)
|
||||
|
||||
// LoginLogDeleteInp 删除登录日志
|
||||
type LoginLogDeleteInp struct {
|
||||
Id interface{} `json:"id" v:"required#日志ID不能为空" dc:"日志ID"`
|
||||
}
|
||||
|
||||
type LoginLogDeleteModel struct{}
|
||||
|
||||
// LoginLogViewInp 获取指定登录日志信息
|
||||
type LoginLogViewInp struct {
|
||||
Id int64 `json:"id" v:"required#日志ID不能为空" dc:"日志ID"`
|
||||
}
|
||||
|
||||
type LoginLogViewModel struct {
|
||||
entity.Test
|
||||
}
|
||||
|
||||
// LoginLogListInp 获取登录日志列表
|
||||
type LoginLogListInp struct {
|
||||
form.PageReq
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
LoginAt []*gtime.Time `json:"loginAt" dc:"登录时间"`
|
||||
SysLogIp string `json:"sysLogIp" dc:"IP地址"`
|
||||
}
|
||||
|
||||
type LoginLogListModel struct {
|
||||
Id int64 `json:"id" dc:"日志ID"`
|
||||
ReqId string `json:"reqId" dc:"请求ID"`
|
||||
MemberId int64 `json:"memberId" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
LoginAt *gtime.Time `json:"loginAt" dc:"登录时间"`
|
||||
ErrMsg string `json:"errMsg" dc:"错误提示"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"`
|
||||
SysLogId int64 `json:"sysLogId" dc:"日志ID"`
|
||||
SysLogIp string `json:"sysLogIp" dc:"IP地址"`
|
||||
SysLogProvinceId int64 `json:"sysLogProvinceId" dc:"省编码"`
|
||||
SysLogCityId int64 `json:"sysLogCityId" dc:"市编码"`
|
||||
SysLogErrorCode int `json:"sysLogErrorCode" dc:"报错code"`
|
||||
SysLogUserAgent string `json:"sysLogUserAgent" dc:"UA信息"`
|
||||
Region string `json:"region" dc:"地区"`
|
||||
Os string `json:"os" dc:"系统信息"`
|
||||
Browser string `json:"browser" dc:"浏览器信息"`
|
||||
}
|
||||
|
||||
func (in *LoginLogListInp) Filter(ctx context.Context) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// LoginLogExportModel 导出登录日志
|
||||
type LoginLogExportModel struct {
|
||||
Id int64 `json:"id" dc:"日志ID"`
|
||||
ReqId string `json:"reqId" dc:"请求ID"`
|
||||
MemberId int64 `json:"memberId" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
LoginAt int64 `json:"loginAt" dc:"登录时间"`
|
||||
ErrMsg string `json:"errMsg" dc:"错误提示"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"`
|
||||
SysLogIp string `json:"sysLogIp" dc:"IP地址"`
|
||||
SysLogProvinceId int64 `json:"sysLogProvinceId" dc:"省编码"`
|
||||
SysLogCityId int64 `json:"sysLogCityId" dc:"市编码"`
|
||||
SysLogErrorCode int `json:"sysLogErrorCode" dc:"报错code"`
|
||||
SysLogUserAgent string `json:"sysLogUserAgent" dc:"UA信息"`
|
||||
}
|
||||
|
||||
// LoginLogPushInp 解推送登录日志
|
||||
type LoginLogPushInp struct {
|
||||
Input adminin.MemberLoginInp
|
||||
Response *adminin.MemberLoginModel
|
||||
Err error
|
||||
}
|
@@ -13,11 +13,10 @@ import (
|
||||
|
||||
// ProvincesMaxSortInp 最大排序
|
||||
type ProvincesMaxSortInp struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
type ProvincesMaxSortModel struct {
|
||||
Sort int
|
||||
Sort int `json:"sort" dc:"排序"`
|
||||
}
|
||||
|
||||
// ProvincesEditInp 修改/新增字典数据
|
||||
@@ -28,7 +27,7 @@ type ProvincesEditModel struct{}
|
||||
|
||||
// ProvincesDeleteInp 删除字典类型
|
||||
type ProvincesDeleteInp struct {
|
||||
Id interface{}
|
||||
Id interface{} `json:"id" v:"required#省市区ID不能为空" dc:"省市区ID"`
|
||||
}
|
||||
type ProvincesDeleteModel struct{}
|
||||
|
||||
@@ -59,3 +58,26 @@ type ProvincesStatusInp struct {
|
||||
entity.SysProvinces
|
||||
}
|
||||
type ProvincesStatusModel struct{}
|
||||
|
||||
// ProvincesChildrenListInp 获取省市区下级列表
|
||||
type ProvincesChildrenListInp struct {
|
||||
form.PageReq
|
||||
form.StatusReq
|
||||
Pid int64 `json:"pid" dc:"上级ID"`
|
||||
Id int64 `json:"id" dc:"地区ID"`
|
||||
Title string `json:"title" dc:"地区名称"`
|
||||
}
|
||||
|
||||
type ProvincesChildrenListModel struct {
|
||||
entity.SysProvinces
|
||||
}
|
||||
|
||||
// ProvincesUniqueIdInp 获取省市区下级列表
|
||||
type ProvincesUniqueIdInp struct {
|
||||
OldId int64 `json:"oldId" dc:"原始ID"`
|
||||
NewId int64 `json:"newId" dc:"新的ID"`
|
||||
}
|
||||
|
||||
type ProvincesUniqueIdModel struct {
|
||||
IsUnique bool `json:"unique" dc:"是否唯一"`
|
||||
}
|
||||
|
69
server/internal/model/input/sysin/serve_log.go
Normal file
69
server/internal/model/input/sysin/serve_log.go
Normal file
@@ -0,0 +1,69 @@
|
||||
// Package sysin
|
||||
// @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 sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/form"
|
||||
)
|
||||
|
||||
// ServeLogDeleteInp 删除服务日志
|
||||
type ServeLogDeleteInp struct {
|
||||
Id interface{} `json:"id" v:"required#日志ID不能为空" dc:"日志ID"`
|
||||
}
|
||||
|
||||
type ServeLogDeleteModel struct{}
|
||||
|
||||
// ServeLogViewInp 获取指定服务日志信息
|
||||
type ServeLogViewInp struct {
|
||||
Id int64 `json:"id" v:"required#日志ID不能为空" dc:"日志ID"`
|
||||
}
|
||||
|
||||
type ServeLogViewModel struct {
|
||||
entity.Test
|
||||
}
|
||||
|
||||
// ServeLogListInp 获取服务日志列表
|
||||
type ServeLogListInp struct {
|
||||
form.PageReq
|
||||
TraceId string `json:"traceId" dc:"链路ID"`
|
||||
LevelFormat string `json:"levelFormat" dc:"日志级别"`
|
||||
TriggerNs []int64 `json:"triggerNs" dc:"触发时间(ns)"`
|
||||
CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
|
||||
}
|
||||
|
||||
type ServeLogListModel struct {
|
||||
Id int64 `json:"id" dc:"日志ID"`
|
||||
TraceId string `json:"traceId" dc:"链路ID"`
|
||||
LevelFormat string `json:"levelFormat" dc:"日志级别"`
|
||||
Content string `json:"content" dc:"日志内容"`
|
||||
Stack string `json:"stack" dc:"堆栈"`
|
||||
Line string `json:"line" dc:"调用行"`
|
||||
TriggerNs int64 `json:"triggerNs" dc:"触发时间(ns)"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"`
|
||||
SysLogId int64 `json:"sysLogId" dc:"访问日志ID"`
|
||||
}
|
||||
|
||||
func (in *ServeLogListInp) Filter(ctx context.Context) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// ServeLogExportModel 导出服务日志
|
||||
type ServeLogExportModel struct {
|
||||
Id int64 `json:"id" dc:"日志ID"`
|
||||
Env string `json:"env" dc:"环境"`
|
||||
TraceId string `json:"traceId" dc:"链路ID"`
|
||||
LevelFormat string `json:"levelFormat" dc:"日志级别"`
|
||||
Content string `json:"content" dc:"日志内容"`
|
||||
Line string `json:"line" dc:"调用行"`
|
||||
TriggerNs int64 `json:"triggerNs" dc:"触发时间(ns)"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"`
|
||||
}
|
76
server/internal/model/input/sysin/sms_log.go
Normal file
76
server/internal/model/input/sysin/sms_log.go
Normal file
@@ -0,0 +1,76 @@
|
||||
// Package sysin
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/form"
|
||||
)
|
||||
|
||||
// SmsLogMaxSortInp 最大排序
|
||||
type SmsLogMaxSortInp struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
type SmsLogMaxSortModel struct {
|
||||
Sort int
|
||||
}
|
||||
|
||||
// SmsLogEditInp 修改/新增数据
|
||||
type SmsLogEditInp struct {
|
||||
entity.SysSmsLog
|
||||
}
|
||||
type SmsLogEditModel struct{}
|
||||
|
||||
// SmsLogDeleteInp 删除
|
||||
type SmsLogDeleteInp struct {
|
||||
Id interface{}
|
||||
}
|
||||
type SmsLogDeleteModel struct{}
|
||||
|
||||
// SmsLogViewInp 获取信息
|
||||
type SmsLogViewInp struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
type SmsLogViewModel struct {
|
||||
entity.SysSmsLog
|
||||
}
|
||||
|
||||
// SmsLogListInp 获取列表
|
||||
type SmsLogListInp struct {
|
||||
form.PageReq
|
||||
form.RangeDateReq
|
||||
form.StatusReq
|
||||
Title string
|
||||
Content string
|
||||
}
|
||||
|
||||
type SmsLogListModel struct {
|
||||
entity.SysSmsLog
|
||||
}
|
||||
|
||||
// SmsLogStatusInp 更新状态
|
||||
type SmsLogStatusInp struct {
|
||||
entity.SysSmsLog
|
||||
}
|
||||
type SmsLogStatusModel struct{}
|
||||
|
||||
// SendCodeInp 发送验证码
|
||||
type SendCodeInp struct {
|
||||
Event string `json:"event" description:"事件"` // 必填
|
||||
Mobile string `json:"mobile" description:"手机号"` // 必填
|
||||
Code string `json:"code" description:"验证码或短信内容"`
|
||||
Template string `json:"-" description:"发信模板 "`
|
||||
}
|
||||
|
||||
// VerifyCodeInp 效验验证码
|
||||
type VerifyCodeInp struct {
|
||||
Event string `json:"event" description:"事件"` // 必填
|
||||
Mobile string `json:"mobile" description:"手机号"` // 必填
|
||||
Code string `json:"code" description:"验证码或短信内容"` // 必填
|
||||
}
|
@@ -8,22 +8,63 @@ package queues
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"hotgo/internal/library/queue"
|
||||
)
|
||||
|
||||
type jobStrategy interface {
|
||||
Listen(ctx context.Context)
|
||||
getTopic() string
|
||||
handle(ctx context.Context, mqMsg queue.MqMsg) (err error)
|
||||
}
|
||||
|
||||
var (
|
||||
jobList = []jobStrategy{
|
||||
SysLog,
|
||||
}
|
||||
)
|
||||
var jobList []jobStrategy
|
||||
|
||||
func Run(ctx context.Context) {
|
||||
for _, job := range jobList {
|
||||
job.Listen(ctx)
|
||||
for _, job := range uniqueJob(jobList) {
|
||||
go func(job jobStrategy) {
|
||||
listen(ctx, job)
|
||||
}(job)
|
||||
}
|
||||
}
|
||||
|
||||
func listen(ctx context.Context, job jobStrategy) {
|
||||
var (
|
||||
topic = job.getTopic()
|
||||
consumer, err = queue.InstanceConsumer()
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
g.Log().Fatalf(ctx, "InstanceConsumer %s err:%+v", topic, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 访问日志
|
||||
if listenErr := consumer.ListenReceiveMsgDo(topic, func(mqMsg queue.MqMsg) {
|
||||
err = job.handle(ctx, mqMsg)
|
||||
|
||||
if err != nil {
|
||||
// 遇到错误,重新加入到队列
|
||||
//queue.Push(topic, mqMsg.Body)
|
||||
}
|
||||
|
||||
// 记录队列日志
|
||||
queue.ConsumerLog(ctx, topic, mqMsg, err)
|
||||
|
||||
}); listenErr != nil {
|
||||
g.Log().Fatalf(ctx, "队列:%s 监听失败, err:%+v", topic, listenErr)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// uniqueJob 去重
|
||||
func uniqueJob(languages []jobStrategy) []jobStrategy {
|
||||
result := make([]jobStrategy, 0, len(languages))
|
||||
temp := map[jobStrategy]struct{}{}
|
||||
for _, item := range languages {
|
||||
if _, ok := temp[item]; !ok {
|
||||
temp[item] = struct{}{}
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
39
server/internal/queues/login_log.go
Normal file
39
server/internal/queues/login_log.go
Normal file
@@ -0,0 +1,39 @@
|
||||
// Package queues
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package queues
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/queue"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
func init() {
|
||||
jobList = append(jobList, LoginLog)
|
||||
}
|
||||
|
||||
// LoginLog 登录日志
|
||||
var LoginLog = &qLoginLog{}
|
||||
|
||||
type qLoginLog struct{}
|
||||
|
||||
// getTopic 主题
|
||||
func (q *qLoginLog) getTopic() string {
|
||||
return consts.QueueLoginLogTopic
|
||||
}
|
||||
|
||||
// handle 处理消息
|
||||
func (q *qLoginLog) handle(ctx context.Context, mqMsg queue.MqMsg) (err error) {
|
||||
var data entity.SysLoginLog
|
||||
if err = json.Unmarshal(mqMsg.Body, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
return service.SysLoginLog().RealWrite(ctx, data)
|
||||
}
|
39
server/internal/queues/serve_log.go
Normal file
39
server/internal/queues/serve_log.go
Normal file
@@ -0,0 +1,39 @@
|
||||
// Package queues
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2022 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
//
|
||||
package queues
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/queue"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
func init() {
|
||||
jobList = append(jobList, ServeLog)
|
||||
}
|
||||
|
||||
// ServeLog 登录日志
|
||||
var ServeLog = &qServeLog{}
|
||||
|
||||
type qServeLog struct{}
|
||||
|
||||
// getTopic 主题
|
||||
func (q *qServeLog) getTopic() string {
|
||||
return consts.QueueServeLogTopic
|
||||
}
|
||||
|
||||
// handle 处理消息
|
||||
func (q *qServeLog) handle(ctx context.Context, mqMsg queue.MqMsg) (err error) {
|
||||
var data entity.SysServeLog
|
||||
if err = json.Unmarshal(mqMsg.Body, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
return service.SysServeLog().RealWrite(ctx, data)
|
||||
}
|
@@ -8,40 +8,32 @@ package queues
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/queue"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
// SysLog 系统日志
|
||||
var SysLog = &qSysLog{topic: consts.QueueLogTopic}
|
||||
func init() {
|
||||
jobList = append(jobList, SysLog)
|
||||
}
|
||||
|
||||
type qSysLog struct {
|
||||
topic string
|
||||
// SysLog 系统日志
|
||||
var SysLog = &qSysLog{}
|
||||
|
||||
type qSysLog struct{}
|
||||
|
||||
// getTopic 主题
|
||||
func (q *qSysLog) getTopic() string {
|
||||
return consts.QueueLogTopic
|
||||
}
|
||||
|
||||
// handle 处理消息
|
||||
func (q *qSysLog) handle(ctx context.Context, mqMsg queue.MqMsg) (err error) {
|
||||
return service.SysLog().QueueJob(ctx, mqMsg)
|
||||
}
|
||||
|
||||
// Listen 监听
|
||||
func (q *qSysLog) Listen(ctx context.Context) {
|
||||
consumer, err := queue.InstanceConsumer()
|
||||
if err != nil {
|
||||
queue.FatalLog(ctx, "InstanceConsumer "+q.topic+"异常:", err)
|
||||
return
|
||||
var data entity.SysLog
|
||||
if err = json.Unmarshal(mqMsg.Body, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 全局日志
|
||||
if listenErr := consumer.ListenReceiveMsgDo(q.topic, func(mqMsg queue.MqMsg) {
|
||||
err = q.handle(ctx, mqMsg)
|
||||
|
||||
// 记录队列日志
|
||||
queue.ConsumerLog(ctx, q.topic, mqMsg, err)
|
||||
|
||||
}); listenErr != nil {
|
||||
queue.FatalLog(ctx, "队列:"+q.topic+" 监听失败", listenErr)
|
||||
}
|
||||
|
||||
return service.SysLog().RealWrite(ctx, data)
|
||||
}
|
||||
|
@@ -30,8 +30,8 @@ func Admin(ctx context.Context, group *ghttp.RouterGroup) {
|
||||
common.Site, // 基础
|
||||
common.Console, // 控制台
|
||||
common.Ems, // 邮件
|
||||
common.Sms, // 短信
|
||||
common.Upload, // 上传
|
||||
sys.Log, // 日志
|
||||
sys.Config, // 配置
|
||||
sys.DictType, // 字典类型
|
||||
sys.DictData, // 字典数据
|
||||
@@ -41,6 +41,10 @@ func Admin(ctx context.Context, group *ghttp.RouterGroup) {
|
||||
sys.CronGroup, // 定时任务分组
|
||||
sys.Blacklist, // 黑名单
|
||||
sys.GenCodes, // 生成代码
|
||||
sys.Log, // 访问日志
|
||||
sys.LoginLog, // 登录日志
|
||||
sys.ServeLog, // 服务日志
|
||||
sys.SmsLog, // 短信记录
|
||||
admin.Member, // 用户
|
||||
admin.Monitor, // 监控
|
||||
admin.Role, // 路由
|
||||
|
@@ -14,12 +14,45 @@ import (
|
||||
"hotgo/internal/model/input/form"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type (
|
||||
IAdminMenu interface {
|
||||
RoleList(ctx context.Context, in adminin.MenuRoleListInp) (*adminin.MenuRoleListModel, error)
|
||||
SearchList(ctx context.Context, req *menu.SearchListReq) (*menu.SearchListRes, error)
|
||||
MaxSort(ctx context.Context, req *menu.MaxSortReq) (*menu.MaxSortRes, error)
|
||||
NameUnique(ctx context.Context, req *menu.NameUniqueReq) (*menu.NameUniqueRes, error)
|
||||
CodeUnique(ctx context.Context, req *menu.CodeUniqueReq) (*menu.CodeUniqueRes, error)
|
||||
Delete(ctx context.Context, req *menu.DeleteReq) error
|
||||
Edit(ctx context.Context, req *menu.EditReq) (err error)
|
||||
View(ctx context.Context, req *menu.ViewReq) (res *menu.ViewRes, err error)
|
||||
List(ctx context.Context, req *menu.ListReq) (lists []map[string]interface{}, err error)
|
||||
GetMenuList(ctx context.Context, memberId int64) (lists role.DynamicRes, err error)
|
||||
LoginPermissions(ctx context.Context, memberId int64) (lists []*adminin.MemberLoginPermissions, err error)
|
||||
}
|
||||
IAdminNotice interface {
|
||||
Delete(ctx context.Context, in adminin.NoticeDeleteInp) 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) (*adminin.NoticeMaxSortModel, 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)
|
||||
}
|
||||
IAdminPost interface {
|
||||
Delete(ctx context.Context, in adminin.PostDeleteInp) error
|
||||
Edit(ctx context.Context, in adminin.PostEditInp) (err error)
|
||||
MaxSort(ctx context.Context, in adminin.PostMaxSortInp) (*adminin.PostMaxSortModel, error)
|
||||
NameUnique(ctx context.Context, in adminin.PostNameUniqueInp) (*adminin.PostNameUniqueModel, error)
|
||||
CodeUnique(ctx context.Context, in adminin.PostCodeUniqueInp) (*adminin.PostCodeUniqueModel, error)
|
||||
View(ctx context.Context, in adminin.PostViewInp) (res *adminin.PostViewModel, err error)
|
||||
List(ctx context.Context, in adminin.PostListInp) (list []*adminin.PostListModel, totalCount int, err error)
|
||||
GetMemberByStartName(ctx context.Context, memberId int64) (name string, err error)
|
||||
Status(ctx context.Context, in adminin.PostStatusInp) (err error)
|
||||
}
|
||||
IAdminRole interface {
|
||||
Verify(ctx context.Context, path, method string) bool
|
||||
List(ctx context.Context, in adminin.RoleListInp) (list []*adminin.RoleListModel, totalCount int, err error)
|
||||
List(ctx context.Context, in adminin.RoleListInp) (list []g.Map, 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)
|
||||
@@ -74,38 +107,6 @@ type (
|
||||
UpdatePostIds(ctx context.Context, member_id int64, post_ids []int64) (err error)
|
||||
GetMemberByIds(ctx context.Context, member_id int64) (post_ids []int64, err error)
|
||||
}
|
||||
IAdminMenu interface {
|
||||
RoleList(ctx context.Context, in adminin.MenuRoleListInp) (*adminin.MenuRoleListModel, error)
|
||||
SearchList(ctx context.Context, req *menu.SearchListReq) (*menu.SearchListRes, error)
|
||||
MaxSort(ctx context.Context, req *menu.MaxSortReq) (*menu.MaxSortRes, error)
|
||||
NameUnique(ctx context.Context, req *menu.NameUniqueReq) (*menu.NameUniqueRes, error)
|
||||
CodeUnique(ctx context.Context, req *menu.CodeUniqueReq) (*menu.CodeUniqueRes, error)
|
||||
Delete(ctx context.Context, req *menu.DeleteReq) error
|
||||
Edit(ctx context.Context, req *menu.EditReq) (err error)
|
||||
View(ctx context.Context, req *menu.ViewReq) (res *menu.ViewRes, err error)
|
||||
List(ctx context.Context, req *menu.ListReq) (lists []map[string]interface{}, err error)
|
||||
GetMenuList(ctx context.Context, memberId int64) (lists role.DynamicRes, err error)
|
||||
LoginPermissions(ctx context.Context, memberId int64) (lists []*adminin.MemberLoginPermissions, err error)
|
||||
}
|
||||
IAdminNotice interface {
|
||||
Delete(ctx context.Context, in adminin.NoticeDeleteInp) 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) (*adminin.NoticeMaxSortModel, 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)
|
||||
}
|
||||
IAdminPost interface {
|
||||
Delete(ctx context.Context, in adminin.PostDeleteInp) error
|
||||
Edit(ctx context.Context, in adminin.PostEditInp) (err error)
|
||||
MaxSort(ctx context.Context, in adminin.PostMaxSortInp) (*adminin.PostMaxSortModel, error)
|
||||
NameUnique(ctx context.Context, in adminin.PostNameUniqueInp) (*adminin.PostNameUniqueModel, error)
|
||||
CodeUnique(ctx context.Context, in adminin.PostCodeUniqueInp) (*adminin.PostCodeUniqueModel, error)
|
||||
View(ctx context.Context, in adminin.PostViewInp) (res *adminin.PostViewModel, err error)
|
||||
List(ctx context.Context, in adminin.PostListInp) (list []*adminin.PostListModel, totalCount int, err error)
|
||||
GetMemberByStartName(ctx context.Context, memberId int64) (name string, err error)
|
||||
Status(ctx context.Context, in adminin.PostStatusInp) (err error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -119,39 +120,6 @@ var (
|
||||
localAdminMember IAdminMember
|
||||
)
|
||||
|
||||
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?")
|
||||
@@ -206,3 +174,36 @@ func AdminTest() IAdminTest {
|
||||
func RegisterAdminTest(i IAdminTest) {
|
||||
localAdminTest = 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
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ type (
|
||||
Ctx(r *ghttp.Request)
|
||||
CORS(r *ghttp.Request)
|
||||
DemoLimit(r *ghttp.Request)
|
||||
Blacklist(r *ghttp.Request)
|
||||
ResponseHandler(r *ghttp.Request)
|
||||
WebSocketToken(r *ghttp.Request)
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/internal/library/queue"
|
||||
"hotgo/internal/model"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
@@ -17,24 +16,6 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
ISysLog interface {
|
||||
Export(ctx context.Context, in sysin.LogListInp) (err error)
|
||||
RealWrite(ctx context.Context, commonLog entity.SysLog) error
|
||||
AutoLog(ctx context.Context) (err error)
|
||||
QueueJob(ctx context.Context, mqMsg queue.MqMsg) (err 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) error
|
||||
List(ctx context.Context, in sysin.LogListInp) (list []*sysin.LogListModel, totalCount int, err error)
|
||||
}
|
||||
ISysProvinces interface {
|
||||
Delete(ctx context.Context, in sysin.ProvincesDeleteInp) 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) (*sysin.ProvincesMaxSortModel, 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)
|
||||
}
|
||||
ISysAttachment interface {
|
||||
Delete(ctx context.Context, in sysin.AttachmentDeleteInp) error
|
||||
Edit(ctx context.Context, in sysin.AttachmentEditInp) (err error)
|
||||
@@ -44,22 +25,48 @@ type (
|
||||
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)
|
||||
}
|
||||
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) 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)
|
||||
}
|
||||
ISysBlacklist interface {
|
||||
Delete(ctx context.Context, in sysin.BlacklistDeleteInp) error
|
||||
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)
|
||||
}
|
||||
ISysCron interface {
|
||||
StartCron(ctx context.Context)
|
||||
Delete(ctx context.Context, in sysin.CronDeleteInp) error
|
||||
Edit(ctx context.Context, in sysin.CronEditInp) (err error)
|
||||
Status(ctx context.Context, in sysin.CronStatusInp) (err error)
|
||||
MaxSort(ctx context.Context, in sysin.CronMaxSortInp) (*sysin.CronMaxSortModel, error)
|
||||
View(ctx context.Context, in sysin.CronViewInp) (res *sysin.CronViewModel, err error)
|
||||
List(ctx context.Context, in sysin.CronListInp) (list []*sysin.CronListModel, totalCount int, err error)
|
||||
ISysConfig interface {
|
||||
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)
|
||||
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
|
||||
}
|
||||
ISysCronGroup interface {
|
||||
Delete(ctx context.Context, in sysin.CronGroupDeleteInp) error
|
||||
@@ -87,17 +94,44 @@ type (
|
||||
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)
|
||||
}
|
||||
ISysConfig interface {
|
||||
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)
|
||||
GetLoadSSL(ctx context.Context) (conf *model.SSLConfig, err error)
|
||||
GetLoadLog(ctx context.Context) (conf *model.LogConfig, 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) (err 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) error
|
||||
List(ctx context.Context, in sysin.LogListInp) (list []*sysin.LogListModel, totalCount int, 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)
|
||||
}
|
||||
ISysCron interface {
|
||||
StartCron(ctx context.Context)
|
||||
Delete(ctx context.Context, in sysin.CronDeleteInp) error
|
||||
Edit(ctx context.Context, in sysin.CronEditInp) (err error)
|
||||
Status(ctx context.Context, in sysin.CronStatusInp) (err error)
|
||||
MaxSort(ctx context.Context, in sysin.CronMaxSortInp) (*sysin.CronMaxSortModel, error)
|
||||
View(ctx context.Context, in sysin.CronViewInp) (res *sysin.CronViewModel, err error)
|
||||
List(ctx context.Context, in sysin.CronListInp) (list []*sysin.CronListModel, totalCount int, err error)
|
||||
OnlineExec(ctx context.Context, in sysin.OnlineExecInp) (err error)
|
||||
}
|
||||
ISysDictType interface {
|
||||
Tree(ctx context.Context) (list []g.Map, err error)
|
||||
@@ -123,28 +157,75 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
localSysBlacklist ISysBlacklist
|
||||
localSysCron ISysCron
|
||||
localSysCronGroup ISysCronGroup
|
||||
localSysBlacklist ISysBlacklist
|
||||
localSysConfig ISysConfig
|
||||
localSysCurdDemo ISysCurdDemo
|
||||
localSysDictData ISysDictData
|
||||
localSysGenCodes ISysGenCodes
|
||||
localSysLog ISysLog
|
||||
localSysServeLog ISysServeLog
|
||||
localSysSmsLog ISysSmsLog
|
||||
localSysCron ISysCron
|
||||
localSysDictType ISysDictType
|
||||
localSysProvinces ISysProvinces
|
||||
localSysAttachment ISysAttachment
|
||||
localSysDictType ISysDictType
|
||||
localSysGenCodes ISysGenCodes
|
||||
localSysConfig ISysConfig
|
||||
localSysLoginLog ISysLoginLog
|
||||
)
|
||||
|
||||
func SysBlacklist() ISysBlacklist {
|
||||
if localSysBlacklist == nil {
|
||||
panic("implement not found for interface ISysBlacklist, forgot register?")
|
||||
func SysDictType() ISysDictType {
|
||||
if localSysDictType == nil {
|
||||
panic("implement not found for interface ISysDictType, forgot register?")
|
||||
}
|
||||
return localSysBlacklist
|
||||
return localSysDictType
|
||||
}
|
||||
|
||||
func RegisterSysBlacklist(i ISysBlacklist) {
|
||||
localSysBlacklist = i
|
||||
func RegisterSysDictType(i ISysDictType) {
|
||||
localSysDictType = 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 SysLog() ISysLog {
|
||||
if localSysLog == nil {
|
||||
panic("implement not found for interface ISysLog, forgot register?")
|
||||
}
|
||||
return localSysLog
|
||||
}
|
||||
|
||||
func RegisterSysLog(i ISysLog) {
|
||||
localSysLog = 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?")
|
||||
}
|
||||
return localSysSmsLog
|
||||
}
|
||||
|
||||
func RegisterSysSmsLog(i ISysSmsLog) {
|
||||
localSysSmsLog = i
|
||||
}
|
||||
|
||||
func SysCron() ISysCron {
|
||||
@@ -158,48 +239,15 @@ func RegisterSysCron(i ISysCron) {
|
||||
localSysCron = i
|
||||
}
|
||||
|
||||
func SysCronGroup() ISysCronGroup {
|
||||
if localSysCronGroup == nil {
|
||||
panic("implement not found for interface ISysCronGroup, forgot register?")
|
||||
func SysLoginLog() ISysLoginLog {
|
||||
if localSysLoginLog == nil {
|
||||
panic("implement not found for interface ISysLoginLog, forgot register?")
|
||||
}
|
||||
return localSysCronGroup
|
||||
return localSysLoginLog
|
||||
}
|
||||
|
||||
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 SysLog() ISysLog {
|
||||
if localSysLog == nil {
|
||||
panic("implement not found for interface ISysLog, forgot register?")
|
||||
}
|
||||
return localSysLog
|
||||
}
|
||||
|
||||
func RegisterSysLog(i ISysLog) {
|
||||
localSysLog = i
|
||||
func RegisterSysLoginLog(i ISysLoginLog) {
|
||||
localSysLoginLog = i
|
||||
}
|
||||
|
||||
func SysProvinces() ISysProvinces {
|
||||
@@ -224,28 +272,6 @@ func RegisterSysAttachment(i ISysAttachment) {
|
||||
localSysAttachment = 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 SysGenCodes() ISysGenCodes {
|
||||
if localSysGenCodes == nil {
|
||||
panic("implement not found for interface ISysGenCodes, forgot register?")
|
||||
}
|
||||
return localSysGenCodes
|
||||
}
|
||||
|
||||
func RegisterSysGenCodes(i ISysGenCodes) {
|
||||
localSysGenCodes = i
|
||||
}
|
||||
|
||||
func SysConfig() ISysConfig {
|
||||
if localSysConfig == nil {
|
||||
panic("implement not found for interface ISysConfig, forgot register?")
|
||||
@@ -256,3 +282,47 @@ func SysConfig() ISysConfig {
|
||||
func RegisterSysConfig(i ISysConfig) {
|
||||
localSysConfig = 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 SysBlacklist() ISysBlacklist {
|
||||
if localSysBlacklist == nil {
|
||||
panic("implement not found for interface ISysBlacklist, forgot register?")
|
||||
}
|
||||
return localSysBlacklist
|
||||
}
|
||||
|
||||
func RegisterSysBlacklist(i ISysBlacklist) {
|
||||
localSysBlacklist = 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 SysCurdDemo() ISysCurdDemo {
|
||||
if localSysCurdDemo == nil {
|
||||
panic("implement not found for interface ISysCurdDemo, forgot register?")
|
||||
}
|
||||
return localSysCurdDemo
|
||||
}
|
||||
|
||||
func RegisterSysCurdDemo(i ISysCurdDemo) {
|
||||
localSysCurdDemo = i
|
||||
}
|
||||
|
Reference in New Issue
Block a user