This commit is contained in:
孟帅
2023-11-25 18:36:11 +08:00
parent 40117c700d
commit 70e9f966c3
142 changed files with 5407 additions and 2058 deletions

View File

@@ -15,7 +15,6 @@ import (
"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"
"github.com/gogf/gf/v2/util/grand"
"hotgo/internal/consts"
"hotgo/internal/dao"
@@ -403,28 +402,39 @@ func (s *sAdminMember) VerifyUnique(ctx context.Context, in *adminin.VerifyUniqu
// Delete 删除用户
func (s *sAdminMember) Delete(ctx context.Context, in *adminin.MemberDeleteInp) (err error) {
if s.VerifySuperId(ctx, gconv.Int64(in.Id)) {
err = gerror.New("超管账号禁止删除!")
return
}
memberId := contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
return
}
var models *entity.AdminMember
if err = s.FilterAuthModel(ctx, memberId).WherePri(in.Id).Scan(&models); err != nil {
var list []*entity.AdminMember
if err = s.FilterAuthModel(ctx, memberId).WherePri(in.Id).Scan(&list); err != nil {
err = gerror.Wrap(err, "获取用户信息失败,请稍后重试!")
return
}
if models == nil {
if len(list) == 0 {
err = gerror.New("需要删除的用户不存在或已删除!")
return
}
for _, v := range list {
if s.VerifySuperId(ctx, v.Id) {
err = gerror.New("超管账号禁止删除!")
return
}
count, err := dao.AdminMember.Ctx(ctx).Where("pid", v.Id).Count()
if err != nil {
err = gerror.Wrap(err, "删除用户检查失败,请稍后重试!")
return err
}
if count > 0 {
err = gerror.Newf("用户[%v]存在下级请先删除TA的下级用户", v.Id)
return err
}
}
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
if _, err = s.FilterAuthModel(ctx, memberId).WherePri(in.Id).Delete(); err != nil {
err = gerror.Wrap(err, "删除用户失败,请稍后重试!")
@@ -434,6 +444,9 @@ func (s *sAdminMember) Delete(ctx context.Context, in *adminin.MemberDeleteInp)
if _, err = dao.AdminMemberPost.Ctx(ctx).Where("member_id", in.Id).Delete(); err != nil {
err = gerror.Wrap(err, "删除用户岗位失败,请稍后重试!")
}
// 这里如果需要,可以加入更多删除用户的相关处理
// ...
return
})
}
@@ -603,6 +616,14 @@ func (s *sAdminMember) List(ctx context.Context, in *adminin.MemberListInp) (lis
mod = mod.Where(cols.RoleId, in.RoleId)
}
if in.Id > 0 {
mod = mod.Where(cols.Id, in.Id)
}
if in.Pid > 0 {
mod = mod.Where(cols.Pid, in.Pid)
}
if len(in.CreatedAt) == 2 {
mod = mod.WhereBetween(cols.CreatedAt, gtime.New(in.CreatedAt[0]), gtime.New(in.CreatedAt[1]))
}

View File

@@ -7,22 +7,23 @@ package admin
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"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"
"github.com/gogf/gf/v2/util/gmode"
"hotgo/api/admin/role"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/casbin"
"hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm"
"hotgo/internal/model/do"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/adminin"
"hotgo/internal/service"
"hotgo/utility/convert"
"hotgo/utility/validate"
)
type sAdminMenu struct{}
@@ -91,44 +92,25 @@ func (s *sAdminMenu) Edit(ctx context.Context, in *adminin.MenuEditInp) (err err
return
}
var pd *do.AdminMenu
// 维护菜单等级
if in.Pid == 0 {
in.Level = 1
} else {
if err = dao.AdminMenu.Ctx(ctx).Where("id", in.Pid).Scan(&pd); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
in.Pid, in.Level, in.Tree, err = hgorm.AutoUpdateTree(ctx, &dao.AdminMenu, in.Id, in.Pid)
if err != nil {
return err
}
if pd == nil {
return gerror.New("上级菜单信息错误")
}
in.Level = gconv.Int(pd.Level) + 1
}
// 修改
in.UpdatedAt = gtime.Now()
if in.Id > 0 {
if in.Pid == in.Id {
return gerror.New("上级菜单不能是当前菜单")
}
if _, err = dao.AdminMenu.Ctx(ctx).Where("id", in.Id).Data(in).Update(); err != nil {
err = gerror.Wrap(err, "修改菜单失败!")
return err
if in.Id > 0 {
if _, err = dao.AdminMenu.Ctx(ctx).Where("id", in.Id).Data(in).Update(); err != nil {
err = gerror.Wrap(err, "修改菜单失败!")
return err
}
} else {
if _, err = dao.AdminMenu.Ctx(ctx).Data(in).Insert(); err != nil {
err = gerror.Wrap(err, "新增菜单失败!")
return err
}
}
return casbin.Refresh(ctx)
}
// 新增
in.CreatedAt = gtime.Now()
if _, err = dao.AdminMenu.Ctx(ctx).Data(in).Insert(); err != nil {
err = gerror.Wrap(err, "新增菜单失败!")
return err
}
return casbin.Refresh(ctx)
})
}
// List 获取菜单列表
@@ -215,6 +197,18 @@ func (s *sAdminMenu) GetMenuList(ctx context.Context, memberId int64) (res *role
return
}
// 生产环境下隐藏一些菜单
if gmode.IsProduct() {
newMenus := make([]*adminin.MenuRouteSummary, 0)
devMenus := []string{"Develops", "doc"} // 如果你还有其他需要在生产环境隐藏的菜单,将菜单别名加入即可
for _, menu := range allMenus {
if !validate.InSlice(devMenus, menu.Name) {
newMenus = append(newMenus, menu)
}
}
allMenus = newMenus
}
for _, v := range allMenus {
treeMap[gconv.String(v.Pid)] = append(treeMap[gconv.String(v.Pid)], v)
}

View File

@@ -27,7 +27,7 @@ func (s *sHook) accessLog(r *ghttp.Request) {
}
contexts.SetDataMap(ctx, g.Map{
"request.takeUpTime": gtime.TimestampMilli() - r.EnterTime,
"request.takeUpTime": gtime.Now().Sub(gtime.New(r.EnterTime)).Milliseconds(),
// ...
})

View File

@@ -63,12 +63,18 @@ func (s *sMiddleware) Ctx(r *ghttp.Request) {
r.SetCtx(ctx)
}
data := g.Map{
"request.body": gjson.New(r.GetBodyString()),
}
contexts.Init(r, &model.Context{
Data: make(g.Map),
Data: data,
Module: getModule(r.URL.Path),
})
contexts.SetData(r.Context(), "request.body", gjson.New(r.GetBodyString()))
if len(r.Cookie.GetSessionId()) == 0 {
r.Cookie.SetSessionId(gctx.CtxId(r.Context()))
}
r.Middleware.Next()
}

View File

@@ -1,7 +1,7 @@
package middleware
import (
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/internal/library/response"
@@ -68,7 +68,8 @@ func (s *sMiddleware) PreFilter(r *ghttp.Request) {
// 先验证基本校验规则
if err := r.Parse(inputObject.Interface()); err != nil {
response.JsonExit(r, gcode.CodeInvalidRequest.Code(), err.Error())
resp := gerror.Code(err)
response.JsonExit(r, resp.Code(), gerror.Current(err).Error(), resp.Detail())
return
}
@@ -80,7 +81,8 @@ func (s *sMiddleware) PreFilter(r *ghttp.Request) {
// 执行预处理
if err := validate.PreFilter(r.Context(), inputObject.Interface()); err != nil {
response.JsonExit(r, gcode.CodeInvalidParameter.Code(), err.Error())
resp := gerror.Code(err)
response.JsonExit(r, resp.Code(), gerror.Current(err).Error(), resp.Detail())
return
}

View File

@@ -87,8 +87,10 @@ func parseResponse(r *ghttp.Request) (code int, message string, resp interface{}
code = gerror.Code(err).Code()
// 记录异常日志
// 如果你想对错误做不同的处理,可以通过定义不同的错误码来区分
// 默认-1为安全可控错误码只记录文件日志非-1为不可控错误记录文件日志+服务日志并打印堆栈
if code == gcode.CodeNil.Code() {
g.Log().Stdout(false).Printf(ctx, "exception:%v", err)
g.Log().Stdout(false).Infof(ctx, "exception:%v", err)
} else {
g.Log().Errorf(ctx, "exception:%v", err)
}

View File

@@ -20,7 +20,6 @@ import (
"hotgo/internal/service"
"hotgo/utility/simple"
"hotgo/utility/validate"
"strings"
)
type sSysCron struct{}
@@ -90,7 +89,16 @@ func (s *sSysCron) Edit(ctx context.Context, in *sysin.CronEditInp) (err error)
}
// 新增
_, err = dao.SysCron.Ctx(ctx).Data(in).Insert()
in.SysCron.Id, err = dao.SysCron.Ctx(ctx).Data(in).InsertAndGetId()
if err != nil || in.SysCron.Id < 1 {
return
}
if in.SysCron.Status == consts.StatusEnabled {
simple.SafeGo(ctx, func(ctx context.Context) {
_ = cron.Start(&in.SysCron)
})
}
return
}
@@ -163,6 +171,10 @@ func (s *sSysCron) List(ctx context.Context, in *sysin.CronListInp) (list []*sys
mod = mod.WhereLike("name", "%"+in.Name+"%")
}
if in.GroupId > 0 {
mod = mod.Where("group_id", in.GroupId)
}
if in.Status > 0 {
mod = mod.Where("status", in.Status)
}
@@ -210,7 +222,22 @@ func (s *sSysCron) OnlineExec(ctx context.Context, in *sysin.OnlineExecInp) (err
err = gerror.New("定时任务不存在")
return
}
newCtx := context.WithValue(gctx.New(), consts.ContextKeyCronArgs, strings.Split(data.Params, consts.CronSplitStr))
return cron.Once(newCtx, data)
return cron.Once(gctx.New(), data)
}
// DispatchLog 查看指定任务的调度日志
func (s *sSysCron) DispatchLog(ctx context.Context, in *sysin.DispatchLogInp) (res *sysin.DispatchLogModel, err error) {
var data *entity.SysCron
if err = dao.SysCron.Ctx(ctx).Where(dao.SysCron.Columns().Id, in.Id).Scan(&data); err != nil {
return
}
if data == nil {
err = gerror.New("定时任务不存在")
return
}
res = new(sysin.DispatchLogModel)
res.Log, err = cron.DispatchLog(data)
return
}

View File

@@ -107,6 +107,17 @@ func (s *sSysCronGroup) List(ctx context.Context, in *sysin.CronGroupListInp) (l
if err = mod.Page(in.Page, in.PerPage).Order("id desc").Scan(&list); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
}
for _, v := range list {
if v.Pid < 1 {
continue
}
name, err := dao.SysCronGroup.Ctx(ctx).Fields("name").WherePri(v.Pid).Value()
if err != nil {
return nil, 0, err
}
v.SupName = name.String()
}
return
}

View File

@@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.9.3
// @AutoGenerate Version 2.11.5
package sys
import (

View File

@@ -66,10 +66,11 @@ func (s *sCronClient) Start(ctx context.Context) {
// 注册RPC路由
s.client.RegisterRPCRouter(
s.OnCronDelete, // 删除任务
s.OnCronEdit, // 编辑任务
s.OnCronStatus, // 修改任务状态
s.OnCronOnlineExec, // 执行一次任务
s.OnCronDelete, // 删除任务
s.OnCronEdit, // 编辑任务
s.OnCronStatus, // 修改任务状态
s.OnCronOnlineExec, // 执行一次任务
s.OnCronDispatchLog, // 查看调度日志
)
// 注册拦截器

View File

@@ -34,3 +34,10 @@ func (s *sCronClient) OnCronOnlineExec(ctx context.Context, req *servmsg.CronOnl
err = service.SysCron().OnlineExec(ctx, req.OnlineExecInp)
return
}
// OnCronDispatchLog 查看调度日志
func (s *sCronClient) OnCronDispatchLog(ctx context.Context, req *servmsg.CronDispatchLogReq) (res *servmsg.CronDispatchLogRes, err error) {
res = new(servmsg.CronDispatchLogRes)
res.DispatchLogModel, err = service.SysCron().DispatchLog(ctx, req.DispatchLogInp)
return
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/gogf/gf/v2/errors/gerror"
"hotgo/api/servmsg"
"hotgo/internal/consts"
"hotgo/internal/library/cron"
)
// CronDelete 删除任务
@@ -95,3 +96,22 @@ func (s *sTCPServer) CronOnlineExec(ctx context.Context, in *servmsg.CronOnlineE
}
return
}
// DispatchLog 查看调度日志
func (s *sTCPServer) DispatchLog(ctx context.Context, in *servmsg.CronDispatchLogReq) (log *cron.Log, err error) {
clients := s.serv.GetGroupClients(consts.LicenseGroupCron)
if len(clients) == 0 {
err = gerror.New("没有在线的定时任务服务")
return
}
var res servmsg.CronDispatchLogRes
if err = s.serv.RequestScan(ctx, clients[0], in, &res); err != nil {
return
}
if err = res.GetError(); err != nil {
return
}
return res.Log, nil
}