From 9ab57916bcbbbe627efcdc55f6a884c2a3a732bd Mon Sep 17 00:00:00 2001 From: HuangZhi Date: Thu, 6 Jul 2023 11:19:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AD=97=E5=85=B8=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bean/vo/request/dict.go | 2 + src/controller/dict.go | 26 +- src/controller/log_management.go | 159 +++++++++ src/router/dict.go | 16 +- src/router/logmanagementrouter.go | 37 +++ src/router/router.go | 2 + src/service/component_dict.go | 34 +- src/service/log_management.go | 525 ++++++++++++++++++++++++++++++ 8 files changed, 786 insertions(+), 15 deletions(-) create mode 100644 src/controller/log_management.go create mode 100644 src/router/logmanagementrouter.go create mode 100644 src/service/log_management.go diff --git a/src/bean/vo/request/dict.go b/src/bean/vo/request/dict.go index e59f614..c28fb6b 100644 --- a/src/bean/vo/request/dict.go +++ b/src/bean/vo/request/dict.go @@ -7,6 +7,8 @@ type DictReq struct { Status int `json:"status" form:"status"` Class int `json:"class" form:"class" binding:"oneof=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14"` //组件分类(1开发语言与版本 2中间件类型与中间件 3云组件类型 4模块类型 5所属区域 6操作系统 7对象类型 8SQL类型 9调研评估结果 10任务阶段 11测试文档类型 12验收问题类型 13Q&A问题类型 14文档类型) ParentId string `json:"parent_id" form:"parent_id"` //父级ID + Search string `json:"search" form:"search"` + Pagination } type DictTreeReq struct { diff --git a/src/controller/dict.go b/src/controller/dict.go index 28e2d5b..07ea42f 100644 --- a/src/controller/dict.go +++ b/src/controller/dict.go @@ -27,13 +27,13 @@ func (d Dict) List(c *gin.Context) { svc := new(service.Dict) svc.Ctx = c svc.User = header.GetUser(c) - result, err := svc.List(req) + result, count, err := svc.List(req) if err != nil { SendJsonResponse(c, resp.InvalidParam.WithError(err), "") return } - SendJsonResponse(c, resp.OK, result) + SendJsonPageResponse(c, resp.OK, result, count) } // DictTree 字典列表-树结构 @@ -194,6 +194,28 @@ func (d Dict) DictSort(c *gin.Context) { SendJsonResponse(c, resp.OK, "") } +func (d Dict) UpdateDictionaryState(c *gin.Context) { + id := c.Query("id") + status := c.Query("status") + if id == "" || status == "" { + SendJsonResponse(c, resp.InvalidParam.WithData("id 或 status 字段不能为空"), "") + return + } + svc := new(service.Dict) + svc.Ctx = c + svc.User = header.GetUser(c) + total, err := svc.UpdateDictionaryState(id, status) + if err != nil { + SendJsonResponse(c, err, nil) + return + } + if total == 0 { + SendJsonResponse(c, resp.FAIL, nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + // List 组件列表 //func (d Dict) ManageList(c *gin.Context) { // diff --git a/src/controller/log_management.go b/src/controller/log_management.go new file mode 100644 index 0000000..f3d55fa --- /dev/null +++ b/src/controller/log_management.go @@ -0,0 +1,159 @@ +package controller + +import ( + "github.com/gin-gonic/gin" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service" +) + +// 系统日志树 +func GetSystemLoggerTree(c *gin.Context) { + search := c.Query("logTime") + svc := service.LogManagement{User: header.GetUser(c)} + if dir, err := svc.GetSysLogDir(search); err != nil { + SendJsonResponse(c, err, "") + } else { + SendJsonResponse(c, resp.OK, dir) + } +} + +// 系统日志 +func GetSystemLog(c *gin.Context) { + name := c.Param("name") + search := c.Query("search") + logLevel := c.Query("logLevel") + svc := service.LogManagement{User: header.GetUser(c)} + if logs, err := svc.GetSysLog(logLevel, search, name); err != nil { + SendJsonResponse(c, err, "") + } else { + SendJsonResponse(c, resp.OK, logs) + } +} + +// 用户账户审计列表 +//func LogUserAccountAuditList(c *gin.Context) { +// params := request.LogManagementListReq{} +// // 绑定分页数据 +// if err := c.ShouldBindQuery(¶ms); err != nil { +// SendJsonResponse(c, res.ParamsParserError.ErrorDetail(err), nil) +// return +// } +// // 分页数据初始化 limit page Offset +// params.PageInfo = params.PageInfo.InitPage() +// svc := service.LogManagement{User: util.GetContextUser(c)} +// list, count, err := svc.LogUserAccountAuditList(¶ms) +// if err != nil { +// SendJsonResponse(c, err, nil) +// return +// } +// SendJsonPageResponse(c, err, list, count) +//} +// +//// 用户账户审计列表导出LogUserAccountAuditExport +//func LogUserAccountAuditExport(c *gin.Context) { +// params := request.LogManagementListReq{} +// // 绑定分页数据 +// if err := c.ShouldBindQuery(¶ms); err != nil { +// SendJsonResponse(c, res.ParamsParserError.ErrorDetail(err), nil) +// return +// } +// // 分页数据初始化 limit page Offset +// params.PageInfo = params.PageInfo.InitPage() +// svc := service.LogManagement{User: util.GetContextUser(c)} +// file, fileName, err := svc.LogUserAccountAuditExport(¶ms) +// if err != nil { +// SendJsonResponse(c, err, nil) +// return +// } +// c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileName)) //fmt.Sprintf("attachment; filename=%s", filename)对下载的文件重命名 +// c.Writer.Header().Add("Content-Type", "application/octet-stream") +// c.Writer.Header().Add("Content-Transfer-Encoding", "binary") +// _ = file.Write(c.Writer) +// +//} +// +//// 用户行为审计列表 +//func LogUserBehaviorList(c *gin.Context) { +// params := request.LogUserBehaviorListReq{} +// // 绑定分页数据 +// if err := c.ShouldBindQuery(¶ms); err != nil { +// SendJsonResponse(c, res.ParamsParserError.ErrorDetail(err), nil) +// return +// } +// // 分页数据初始化 limit page Offset +// params.PageInfo = params.PageInfo.InitPage() +// svc := service.LogManagement{User: util.GetContextUser(c)} +// var ( +// list interface{} +// count int64 +// err error +// ) +// //是否ES查询用户行为审计信息 +// if conf.Options.IsBehaviorToES { +// list, count, err = svc.LogUserBehaviorListEs(¶ms) +// if err != nil { +// SendJsonResponse(c, err, nil) +// return +// } +// } else { +// list, count, err = svc.LogUserBehaviorList(¶ms) +// if err != nil { +// SendJsonResponse(c, err, nil) +// return +// } +// } +// SendJsonPageResponse(c, nil, list, count) +//} +// +//// 用户行为审计列表导出 +//func LogUserBehaviorListExport(c *gin.Context) { +// params := request.LogUserBehaviorListReq{} +// // 绑定分页数据 +// if err := c.ShouldBindQuery(¶ms); err != nil { +// SendJsonResponse(c, res.ParamsParserError.ErrorDetail(err), nil) +// return +// } +// // 分页数据初始化 limit page Offset +// params.PageInfo = params.PageInfo.InitPage() +// svc := service.LogManagement{User: util.GetContextUser(c)} +// file, fileName, err := svc.LogUserBehaviorListExport(¶ms) +// if err != nil { +// SendJsonResponse(c, err, nil) +// return +// } +// c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileName)) //fmt.Sprintf("attachment; filename=%s", filename)对下载的文件重命名 +// c.Writer.Header().Add("Content-Type", "application/octet-stream") +// c.Writer.Header().Add("Content-Transfer-Encoding", "binary") +// _ = file.Write(c.Writer) +//} +// +//func LogUserBehaviorDetail(c *gin.Context) { +// id := c.Param("id") +// if id == "" { +// SendJsonResponse(c, res.ParamsMissError.ErrorDetail(errors.New("id必填")), nil) +// return +// } +// svc := service.LogManagement{User: util.GetContextUser(c)} +// data, err := svc.LogUserBehaviorDetail(id) +// if err != nil { +// SendJsonResponse(c, err, nil) +// return +// } +// SendJsonResponse(c, nil, data) +//} +// +//func LogUserBehaviorDelete(c *gin.Context) { +// ids := strings.Split(c.Query("ids"), ",") +// if len(ids) == 0 { +// SendJsonResponse(c, res.ParamsMissError.ErrorDetail(errors.New("ids必填")), nil) +// return +// } +// svc := service.LogManagement{User: util.GetContextUser(c)} +// err := svc.LogUserBehaviorDelete(ids) +// if err != nil { +// SendJsonResponse(c, err, nil) +// return +// } +// SendJsonResponse(c, nil, "删除成功") +//} diff --git a/src/router/dict.go b/src/router/dict.go index 03b2fcf..b1e780e 100644 --- a/src/router/dict.go +++ b/src/router/dict.go @@ -15,13 +15,15 @@ func initDictRoute(e *gin.Engine) { //系统字典 dict := new(controller.Dict) - base.POST("", dict.Add) //新增字典 - base.PUT("", dict.Update) //修改字典 - base.DELETE("", dict.Del) //删除字典 - base.GET("", dict.List) //字典列表 - base.GET("/tree", dict.DictTree) //字典列表-树结构 - base.GET("/classList", dict.ClassList) //字典分类列表 - base.PUT("/sort", dict.DictSort) //字典排序 + base.POST("", dict.Add) //新增字典 + base.PUT("", dict.Update) //修改字典 + base.DELETE("", dict.Del) //删除字典 + base.GET("", dict.List) //字典列表 + base.GET("/tree", dict.DictTree) //字典列表-树结构 + base.GET("/classList", dict.ClassList) //字典分类列表 + base.PUT("/sort", dict.DictSort) //字典排序 + base.PUT("//state", dict.UpdateDictionaryState) //字典排序 + //base.GET("/manage_list", dict.ManageList) //字典管理列表 } diff --git a/src/router/logmanagementrouter.go b/src/router/logmanagementrouter.go new file mode 100644 index 0000000..999614e --- /dev/null +++ b/src/router/logmanagementrouter.go @@ -0,0 +1,37 @@ +package router + +import ( + "fmt" + "github.com/gin-gonic/gin" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header" +) + +// 初始化日志管理路由 +func InitLogManagementRouter(e *gin.Engine) { + logger := e.Group(fmt.Sprintf("%s/log", conf.Options.Prefix), header.SetContext) + + { + systemLog := logger.Group("/system", header.SetContext) + { + systemLog.GET("tree", controller.GetSystemLoggerTree) //系统日志树 + systemLog.GET("log", controller.GetSystemLog) //系统日志 + } + //userAccountAudit := logger.Group("/userAccountAudit", header.SetUserToContext) + //{ + // //用户账户审计: + // userAccountAudit.GET("list", controller.LogUserAccountAuditList, log.AddLogMiddleware("用户账户审计", "/list", constant.OpTypeIntMap[constant.Find])) //用户账户审计列表 + // userAccountAudit.GET("list/export", controller.LogUserAccountAuditExport, log.AddLogMiddleware("用户账户审计", "/export", constant.OpTypeIntMap[constant.Export])) //用户账户审计列表导出 + // + //} + //userBehavior := logger.Group("userBehavior", header.SetUserToContext) + //{ + // //用户行为审计: + // userBehavior.GET("list", controller.LogUserBehaviorList, log.AddLogMiddleware("用户行为审计", "/list", constant.OpTypeIntMap[constant.Find])) //用户行为审计列表 + // userBehavior.GET("list/export", controller.LogUserBehaviorListExport, log.AddLogMiddleware("用户行为审计", "/export", constant.OpTypeIntMap[constant.Export])) //用户行为审计列表导出 + // userBehavior.GET("detail/:id", controller.LogUserBehaviorDetail) //用户行为审计详情 + // userBehavior.DELETE("delete", controller.LogUserBehaviorDelete) //用户行为审计删除 + //} + } +} diff --git a/src/router/router.go b/src/router/router.go index 076c1e2..8d099fb 100644 --- a/src/router/router.go +++ b/src/router/router.go @@ -49,6 +49,8 @@ func Load(r *gin.Engine, middleware ...gin.HandlerFunc) { InitPreferenceConfigRouter(r) // 初始化访问控制管理路由 InitAccessRuleRouter(r) + // 初始化日志管理 + InitLogManagementRouter(r) // 初始化指标配置路由 InitMetricConfigRouter(r) // 初始化预警规则配置路由 diff --git a/src/service/component_dict.go b/src/service/component_dict.go index 710f4af..9e54fbd 100644 --- a/src/service/component_dict.go +++ b/src/service/component_dict.go @@ -55,12 +55,12 @@ func (c *Dict) Check(id, parentId string, name string) (err error) { return } -func (c *Dict) List(req request.DictReq) (dictListRes []*response.DictListRes, err error) { +func (c *Dict) List(req request.DictReq) (dictListRes []*response.DictListRes, count int64, err error) { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) - return dictListRes, err + return dictListRes, 0, err } session := db.NewSession() @@ -79,10 +79,15 @@ func (c *Dict) List(req request.DictReq) (dictListRes []*response.DictListRes, e if req.Status != 0 { session.Where("status = ? ", req.Status) } + if req.Search != "" { + keyword := util.SpecialEscape(req.Search) + session.Where("name like ?", "%"+keyword+"%") + } - err = session.OrderBy(" class,sort").Find(&dictListRes) + count, err = session.OrderBy(" class,sort").Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()). + FindAndCount(&dictListRes) if err != nil { - return dictListRes, resp.DbSelectError.WithError(err) + return dictListRes, 0, resp.DbSelectError.WithError(err) } return } @@ -90,9 +95,9 @@ func (c *Dict) List(req request.DictReq) (dictListRes []*response.DictListRes, e func (c *Dict) DictTree(req request.DictTreeReq) (componentDictTreeRes []*response.DictListRes, err error) { listReq := request.DictReq{ Class: req.Class, - ParentId: "", + ParentId: req.ParentId, } - componentDictList, err := c.List(listReq) + componentDictList, _, err := c.List(listReq) if err != nil { return } @@ -263,6 +268,23 @@ func (c *Dict) DictSort(req []request.DictSortInput) error { return err } +func (d *Dict) UpdateDictionaryState(id string, status string) (total int64, err error) { + db, err := client.GetDbClient() + if err != nil { + return 0, resp.DbConnectError.ErrorDetail(err) + } + + total, err = db.Table("dict").Where("id = ? and is_delete = 0 ", id).Update(map[string]interface{}{ + "status": status, + "updated_by": d.User.Id, + }) + if err != nil { + conf.Logger.Error("Update UpdateDictionaryState ", zap.String("erro", err.Error())) + return 0, resp.DbUpdateError.ErrorDetail(err) + } + return +} + //func (c *Dict) ManageList(req request.DictManageListReq) (componentDictTreeRes []*response.DictListRes, err error) { // listReq := request.DictReq{ // Class: req.Class, diff --git a/src/service/log_management.go b/src/service/log_management.go new file mode 100644 index 0000000..2c2b6bd --- /dev/null +++ b/src/service/log_management.go @@ -0,0 +1,525 @@ +package service + +import ( + "bufio" + "fmt" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" + "os" + "sort" + "strings" + "time" + + "go.uber.org/zap" +) + +type LogManagement struct { + User entity.SystemUserInfo +} + +func (s *LogManagement) GetSysLogDir(search string) ([]string, error) { + file, err := os.Open(conf.Options.LogDirPrefix) + if err != nil { + zap.L().Error("open file err:", zap.Error(err)) + return nil, resp.ReadFileError.WithError(err) + } + names, err := file.Readdirnames(0) + if err != nil { + zap.L().Error("read dirnames err:", zap.Error(err)) + return nil, resp.ReadFileError.WithError(err) + } + if search != "" { + var filterdNames []string + for i := range names { + if strings.Index(names[i], search) >= 0 { + filterdNames = append(filterdNames, names[i]) + } + } + sort.Slice(filterdNames, func(i, j int) bool { + st := strings.Index(filterdNames[i], "-") + ed := strings.Index(filterdNames[i], ".") + di, _ := time.Parse("2006-01-02", filterdNames[i][st+1:ed]) + dj, _ := time.Parse("2006-01-02", filterdNames[j][st+1:ed]) + return di.After(dj) + }) + return filterdNames, nil + } + sort.Slice(names, func(i, j int) bool { + st := strings.Index(names[i], "-") + ed := strings.Index(names[i], ".") + di, _ := time.Parse("2006-01-02", names[i][st+1:ed]) + dj, _ := time.Parse("2006-01-02", names[j][st+1:ed]) + return di.After(dj) + }) + return names, nil +} + +func (s *LogManagement) GetSysLog(logLevel, search, logName string) ([]string, error) { + log, err := os.Open(conf.Options.LogDirPrefix + "/" + logName) + if err != nil { + zap.L().Error("open file err", zap.Error(err)) + return nil, resp.ReadFileError.WithError(err) + } + var logArr []string + reader := bufio.NewReader(log) + for { + rawLine, _, _ := reader.ReadLine() + if len(rawLine) == 0 { + break + } + flag1, flag2 := true, true + line := string(rawLine) + if search != "" { + if strings.Index(line, search) < 0 { + flag1 = false + } + } + if logLevel != "" { + if strings.Index(line, fmt.Sprintf(`"level":"%s"`, strings.ToUpper(logLevel))) < 0 { + flag2 = false + } + } + if flag1 && flag2 { + logArr = append(logArr, line) + } + } + return logArr, nil +} + +//// LogUserAccountAuditList 行为日志列表 +//func (s *LogManagement) LogUserAccountAuditList(params *request.LogManagementListReq) ([]response.LogManagementRep, int64, error) { +// var logManagementRep = []response.LogManagementRep{} +// db, err := client.GetDbClient() +// if err != nil { +// err = res.DbConnectError.ErrorDetail(err) +// return nil, 0, err +// } +// +// modelObj := db.Table("system_user as u") +// modelObj.Join("left", "system_organization as org", "u.organization_id = org.organization_id"). +// Select(`u.ID, +// system_account, +// contact_phone, +// case is_admin when 1 then '业务系统账号' when 2 then '组织管理员账号' when 3 then '平台用户账号' when 4 then '超级管理员' end as is_admin, +// NAME, +// u.organization_id, +// last_access_time, +// case pwd_level when 1 then '弱' when 2 then '中' when 3 then '强' end as pwd_level, +// pwd_updated_time, +// date_part('day', now()-pwd_updated_time)as pwd_is_used , +// u.created_time `) +// +// // 条件查询 +// if params.Search != "" { +// keyword := util.SpecialEscape(params.Search) +// modelObj.Where("system_account ilike ? or contact_phone ilike ? or NAME ilike ?", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%") +// } +// // 用户类型 +// if params.IsAdmin != 0 { +// modelObj.Where("is_admin = ?", params.IsAdmin) +// } +// // 上次访问时间 +// if params.StartAt != "" && params.EndAt != "" { +// applyEndTime, timeErr := time.Parse(jsonTime.LocalDateFormat, params.EndAt) +// if timeErr != nil { +// conf.Logger.Error("时间转换错误", zap.Error(timeErr)) +// return nil, 0, res.DataFailError.ErrorDetail(timeErr) +// } +// EndAt := applyEndTime.AddDate(0, 0, 1).Format(jsonTime.LocalDateFormat) +// modelObj.Where("last_access_time >= ? and last_access_time < ?", params.StartAt, EndAt) +// } +// // 活跃度 1: 低 2:中 3: 高 +// if params.Active != 0 { +// switch params.Active { +// case 1: +// modelObj.Where("last_access_time <= now()-interval '1 month'") +// case 2: +// modelObj.Where("last_access_time < now()-interval '1 week'").And("last_access_time > now()-interval '1 month'") +// case 3: +// modelObj.Where("last_access_time >= now()-interval '1 week'") +// } +// } +// // 密码强度 +// if params.PwdLevel != 0 { +// modelObj.Where("pwd_level = ? ", params.PwdLevel) +// } +// count, err := modelObj.OrderBy("last_access_time desc").Limit(int(params.Limit), int(params.Offset)).FindAndCount(&logManagementRep) +// if err != nil { +// conf.Logger.Error("查询用户账户审计列表失败", zap.Error(err)) +// err = res.DbSelectError.ErrorDetail(errors.New("查询用户账户审计列表失败")) +// return nil, 0, err +// } +// for k := range logManagementRep { +// // lastAccessTime := cast.ToTime(logManagementRep[k].LastAccessTimes) +// active := getActivity(logManagementRep[k].LastAccessTimes) +// logManagementRep[k].Active = active +// logManagementRep[k].LastAccessTime = jsonTime.JsonTime(logManagementRep[k].LastAccessTimes) +// } +// +// return logManagementRep, count, nil +//} +// +//func getActivity(date time.Time) string { +// // dates := cast.ToTime(date) +// var ( +// lastAccess = date.Unix() +// pastWeek = time.Now().AddDate(0, 0, -7).Unix() +// pastMonth = time.Now().AddDate(0, -1, 0).Unix() +// ) +// if lastAccess >= pastWeek { +// return "高" +// } +// if lastAccess < pastWeek && lastAccess > pastMonth { +// return "中" +// } +// if lastAccess <= pastMonth { +// return "低" +// } +// return "不活跃" +//} +// +//// LogUserAccountAuditExport 行为日志导出 +//func (s *LogManagement) LogUserAccountAuditExport(params *request.LogManagementListReq) (xlFile *xlsx.File, fileName string, err error) { +// xlFile = xlsx.NewFile() +// sheet, err := xlFile.AddSheet("sheet") +// if err != nil { +// conf.Logger.Error("xlFile.AddSheet err", zap.Error(err)) +// return +// } +// titleRow := sheet.AddRow() +// tmp := []string{ +// "序号", "账号", "手机号", "用户类型", "所属组织", "上次访问时间", "活跃度", "密码强度", "密码使用时长/天", "创建时间", +// } +// xlsRow2 := tools.NewRow(titleRow, tmp) +// err = xlsRow2.SetRowTitle() +// if err != nil { +// return +// } +// params.Page = 0 +// params.Limit = 20000 +// list, total, err := s.LogUserAccountAuditList(params) +// if total == 0 { +// err = errors.New("没有可导出的数据") +// return +// } else { +// fileName = "用户账号审计" + ".xlsx" +// } +// id := 0 +// for _, detail := range list { +// id += 1 +// currentRow := sheet.AddRow() +// var tmp = []string{ +// strconv.Itoa(id), detail.SystemAccount, detail.ContactPhone, detail.IsAdmin, detail.Name, cast.ToString(detail.LastAccessTime), +// detail.Active, detail.PwdLevel, strconv.Itoa(detail.PwdIsUsed), cast.ToString(detail.CreatedTime), +// } +// newRow := tools.NewRow(currentRow, tmp) +// err := newRow.GenerateRow() +// if err != nil { +// return nil, "", err +// } +// } +// return +//} +// +//// 用户行为审计列表 +//func (s *LogManagement) LogUserBehaviorList(params *request.LogUserBehaviorListReq) (list []response.SystemUserBehaviorList, total int64, err error) { +// db, err := client.GetDbClient() +// if err != nil { +// err = res.DbConnectError.ErrorDetail(err) +// return nil, 0, err +// } +// modelObj := db.Table("system_user_behavior").Alias("sub") +// modelObj.Join("INNER", []string{"system_user", "su"}, "sub.system_id = su.system_id") +// modelObj.Join("INNER", []string{"system_organization_tree", "sot"}, "sot.organization_id = su.organization_id") +// modelObj.Select("sub.*, su.system_account, su.phone, su.is_admin, sot.name as org_name") +// // 条件查询 +// if params.Search != "" { +// keyword := util.SpecialEscape(params.Search) +// modelObj.Where("system_account ilike ? or system_module ilike ? or operate_addr ilike ?", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%") +// } +// // 用户类型 +// if params.IsAdmin != 0 { +// modelObj.Where("is_admin = ?", params.IsAdmin) +// } +// // 上次访问时间 +// if params.StartAt != "" && params.EndAt != "" { +// applyEndTime, timeErr := time.Parse(jsonTime.LocalDateFormat, params.EndAt) +// if timeErr != nil { +// conf.Logger.Error("时间转换错误", zap.Error(timeErr)) +// return nil, 0, res.DataFailError.ErrorDetail(timeErr) +// } +// EndAt := applyEndTime.AddDate(0, 0, 1).Format(jsonTime.LocalDateFormat) +// modelObj.Where("last_access_time >= ? and last_access_time < ?", params.StartAt, EndAt) +// } +// // 操作类型 +// if params.OperateType != "" { +// modelObj.Where("operate_type = ?", params.OperateType) +// } +// // 请求方式 +// if params.ReqMethod != 0 { +// modelObj.Where("req_method = ?", params.ReqMethod) +// } +// // 操作状态 +// if params.OperateStatus != 0 { +// modelObj.Where("operate_status = ?", params.OperateStatus) +// } +// total, err = modelObj.OrderBy("created_time desc").Limit(int(params.Limit), int(params.Offset)).FindAndCount(&list) +// if err != nil { +// conf.Logger.Error("查询用户行为审计列表失败", zap.Error(err)) +// err = res.DbSelectError.ErrorDetail(errors.New("查询用户行为审计列表失败")) +// return nil, 0, err +// } +// return list, total, nil +//} +// +//// 用户行为审计列表 +//func (s *LogManagement) LogUserBehaviorListEs(params *request.LogUserBehaviorListReq) (list []response.SystemUserBehaviorList, total int64, err error) { +// es, err := client.GetEsConnection(conf.EsDoc.Index) +// if err != nil { +// return nil, 0, res.DbConnectError.ErrorDetail(err) +// } +// // boolQuery 可用于组合查询 +// boolQuery := elastic.NewBoolQuery() +// // 条件查询 +// if params.Search != "" { +// keyword := util.SpecialEscape(params.Search) +// boolQuery.Filter( +// elastic.NewBoolQuery().Should( +// elastic.NewWildcardQuery("system_account.keyword", fmt.Sprintf("*%s*", keyword)), +// elastic.NewWildcardQuery("system_module.keyword", fmt.Sprintf("*%s*", keyword)), +// elastic.NewWildcardQuery("operate_addr.keyword", fmt.Sprintf("*%s*", keyword)), +// )) +// } +// // 用户类型 +// if params.IsAdmin != 0 { +// boolQuery.Filter(elastic.NewMatchQuery("is_admin", params.IsAdmin)) +// } +// // 上次访问时间 +// if params.StartAt != "" && params.EndAt != "" { +// applyEndTime, timeErr := time.Parse(jsonTime.LocalDateFormatEs, params.EndAt) +// if timeErr != nil { +// conf.Logger.Error("时间转换错误", zap.Error(timeErr)) +// return nil, 0, res.DataFailError.ErrorDetail(timeErr) +// } +// EndAt := applyEndTime.AddDate(0, 0, 1).Format(jsonTime.LocalDateFormatEs) +// boolQuery.Filter(elastic.NewRangeQuery("created_time").Gte(params.StartAt)) +// boolQuery.Filter(elastic.NewRangeQuery("created_time").Lt(EndAt)) +// } +// // 操作类型 +// if params.OperateType != "" { +// boolQuery.Filter(elastic.NewMatchQuery("operate_type", params.OperateType)) +// } +// // 请求方式 +// if params.ReqMethod != 0 { +// boolQuery.Filter(elastic.NewMatchQuery("req_method", params.ReqMethod)) +// } +// // 操作状态 +// if params.OperateStatus != 0 { +// boolQuery.Filter(elastic.NewMatchQuery("operate_status", params.OperateStatus)) +// } +// searchResult, err := es.Conn.Search(). +// Index(conf.EsDoc.Index). +// Query(boolQuery). +// SortWithInfo(elastic.SortInfo{Field: "created_time_unix", Ascending: false, UnmappedType: "keyword"}). +// From(int((params.Page - 1) * params.Limit)).Size(cast.ToInt(params.Limit)). +// Pretty(true). +// Do(context.Background()) +// if err != nil { +// conf.Logger.Error("查询用户行为审计列表失败", zap.Error(err)) +// return nil, 0, res.DbSelectError.ErrorDetail(err) +// } +// bytes, err := json.Marshal(searchResult) +// if err != nil { +// conf.Logger.Error("json.Marshal序列化用户行为信息失败", zap.Error(err)) +// return nil, 0, res.JsonMarshalError.ErrorDetail(err) +// } +// resultMap := map[string]interface{}{} +// err = json.Unmarshal(bytes, &resultMap) +// if err != nil { +// conf.Logger.Error("序列化用户行为信息失败", zap.Error(err)) +// return nil, 0, res.JsonMarshalError.ErrorDetail(err) +// } +// data, has := resultMap["hits"] +// esData := response.BehaviorEsListInfo{} +// if has { +// bytes, err := json.Marshal(data) +// if err != nil { +// conf.Logger.Error("序列化用户行为信息失败", zap.Error(err)) +// return nil, 0, err +// } +// err = json.Unmarshal(bytes, &esData) +// if err != nil { +// conf.Logger.Error("序列化用户行为信息失败", zap.Error(err)) +// return nil, 0, err +// } +// for k, v := range esData.Hits { +// esData.Hits[k].Source.Id = v.Id +// esData.Hits[k].Source.Xh = (params.Page) * int64(k+1) +// list = append(list, esData.Hits[k].Source) +// } +// } +// total = cast.ToInt64(esData.Total["value"]) +// return list, total, nil +//} +// +//// 用户行为审计导出 +//func (s *LogManagement) LogUserBehaviorListExport(params *request.LogUserBehaviorListReq) (xlFile *xlsx.File, fileName string, err error) { +// xlFile = xlsx.NewFile() +// sheet, err := xlFile.AddSheet("sheet") +// if err != nil { +// return nil, "", res.AddSheetError.ErrorDetail(err) +// } +// titleRow := sheet.AddRow() +// tmp := []string{ +// "序号", "账号", "手机号", "用户类型", "所属组织", "系统模块", "操作类型", "请求方式", "操作状态", "操作地址", "操作地点", "请求地址", "请求参数", "操作方法", "返回参数", "操作时间", +// } +// xlsRow2 := tools.NewRow(titleRow, tmp) +// err = xlsRow2.SetRowTitle() +// if err != nil { +// return +// } +// var ( +// list []response.SystemUserBehaviorList +// total int64 +// ) +// if conf.Options.IsBehaviorToES { +// params.Page = 1 +// params.Limit = 20000 +// list, total, err = s.LogUserBehaviorListEs(params) +// +// } else { +// list, total, err = s.LogUserBehaviorList(params) +// } +// if err != nil { +// return nil, "", res.DbSelectError.ErrorDetail(err) +// } +// if total == 0 { +// return nil, "", res.DbSelectError.ErrorDetail(errors.New("没有可导出的数据")) +// } +// fileName = "用户行为审计" + ".xlsx" +// id := 0 +// for _, detail := range list { +// id += 1 +// currentRow := sheet.AddRow() +// var tmp = []string{ +// strconv.Itoa(id), detail.SystemAccount, detail.Phone, constant.UserTypeStrMap[detail.IsAdmin], detail.OrgName, detail.SystemModule, detail.OperateType, +// constant.HttpMethodStrMap[detail.ReqMethod], constant.OperateStatusStrMap[detail.OperateStatus], detail.OperateIp, detail.OperateAddr, +// detail.ReqUrl, detail.ReqParam, constant.HttpMethodStrMap[detail.ReqMethod], detail.ResFields, cast.ToString(detail.CreatedTime), +// } +// newRow := tools.NewRow(currentRow, tmp) +// err := newRow.GenerateRow() +// if err != nil { +// return nil, "", res.AddSheetError.ErrorDetail(err) +// } +// } +// return +//} +// +//// 用户行为审计详情 +//func (s *LogManagement) LogUserBehaviorDetail(id string) (data *response.LogUserBehaviorDetailRep, err error) { +// if !conf.Options.IsBehaviorToES { +// db, err := client.GetDbClient() +// if err != nil { +// err = res.DbConnectError.ErrorDetail(err) +// return nil, err +// } +// data = new(response.LogUserBehaviorDetailRep) +// modelObj := db.Table("system_user_behavior").Alias("sub") +// modelObj.Join("INNER", []string{"system_user", "su"}, "sub.system_id = su.system_id") +// modelObj.Join("INNER", []string{"system_organization_tree", "sot"}, "sot.organization_id = su.organization_id") +// modelObj.Select("sub.*, su.system_account, su.phone, su.is_admin, sot.name as org_name") +// _, err = modelObj.Where("sub.id = ?", id).And("sub.is_deleted = 0").Get(data) +// if err != nil { +// conf.Logger.Error("获取用户行为审计详情失败", zap.Error(err)) +// return nil, res.DbSelectError.ErrorDetail(err) +// } +// data.OperateStatusStr = constant.OperateStatusStrMap[data.OperateStatus] +// data.ReqMethodStr = constant.HttpMethodStrMap[data.ReqMethod] +// data.UserType = constant.UserTypeStrMap[data.IsAdmin] +// return data, nil +// } else { +// es, err := client.GetEsConnection(conf.EsDoc.Index) +// if err != nil { +// return nil, res.DbConnectError.ErrorDetail(err) +// } +// result := response.SystemUserBehaviorList{} +// searchResult, err := es.Conn.Get(). +// Index(conf.EsDoc.Index). +// Id(id). +// Do(context.Background()) +// if err != nil { +// return nil, res.DbSelectError.ErrorDetail(err) +// } +// err = json.Unmarshal(searchResult.Source, &result) +// if err != nil { +// return nil, res.JsonMarshalError.ErrorDetail(err) +// } +// data = new(response.LogUserBehaviorDetailRep) +// db, err := client.GetDbClient() +// if err != nil { +// err = res.DbConnectError.ErrorDetail(err) +// return nil, err +// } +// modelObj := db.Table("system_user").Alias("su") +// modelObj.Join("INNER", []string{"system_organization_tree", "sot"}, "sot.organization_id = su.organization_id") +// modelObj.Select("su.system_account, su.phone, su.is_admin, sot.name as org_name") +// _, err = modelObj.Where("su.system_id = ?", result.SystemId).Get(data) +// if err != nil { +// conf.Logger.Error("获取用户行为审计详情失败", zap.Error(err)) +// return nil, res.DbSelectError.ErrorDetail(err) +// } +// data.OperateStatusStr = constant.OperateStatusStrMap[data.OperateStatus] +// data.ReqMethodStr = constant.HttpMethodStrMap[data.ReqMethod] +// data.UserType = constant.UserTypeStrMap[data.IsAdmin] +// data = &response.LogUserBehaviorDetailRep{ +// Id: cast.ToInt(result.Id), +// SystemId: result.SystemId, +// OrganizationId: result.OrganizationId, +// SystemModule: result.SystemModule, +// OperateType: result.OperateType, +// ReqMethod: result.ReqMethod, +// OperateStatus: result.OperateStatus, +// OperateIp: result.OperateIp, +// OperateAddr: result.OperateAddr, +// CreatedTime: result.CreatedTime, +// OperateMethod: result.OperateMethod, +// ResFields: result.ResFields, +// ReqParam: result.ReqParam, +// ReqUrl: result.ReqUrl, +// AppId: result.AppId, +// SystemAccount: result.SystemAccount, +// IsAdmin: result.IsAdmin, +// } +// return data, nil +// } +//} +// +//func (s *LogManagement) LogUserBehaviorDelete(ids []string) (err error) { +// if conf.Options.IsBehaviorToES { +// es, err := client.GetEsConnection(conf.EsDoc.Index) +// if err != nil { +// return res.DbConnectError.ErrorDetail(err) +// } +// bulkService := es.Conn.Bulk().Index(conf.EsDoc.Index).Refresh("true") +// for i := range ids { +// req := elastic.NewBulkDeleteRequest().Id(ids[i]) +// bulkService.Add(req) +// } +// result, err := bulkService.Do(context.Background()) +// fmt.Println("success =>", result.Succeeded()) +// if err != nil { +// return res.DbDeleteError.ErrorDetail(err) +// } +// } else { +// db, err := client.GetDbClient() +// if err != nil { +// return res.DbConnectError.ErrorDetail(err) +// } +// _, err = db.Table("system_user_behavior").Update(&map[string]interface{}{"is_deleted": 1}) +// if err != nil { +// return res.DbDeleteError.ErrorDetail(err) +// } +// } +// return nil +//} -- 2.26.0