diff --git a/apps/job/api/job.go b/apps/job/api/job.go index 291270f..44dc78b 100644 --- a/apps/job/api/job.go +++ b/apps/job/api/job.go @@ -133,6 +133,7 @@ func (l *JobApi) StartJobForService(rc *ctx.ReqCtx) { j.CronExpression = job.CronExpression j.JobId = job.JobId j.Name = job.JobName + j.JobGroup = job.JobGroup j.MisfirePolicy = job.MisfirePolicy job.EntryId, err = jobs.AddJob(jobs.Crontab, j) biz.ErrIsNil(err, "添加JOB失败") @@ -142,6 +143,7 @@ func (l *JobApi) StartJobForService(rc *ctx.ReqCtx) { j.CronExpression = job.CronExpression j.JobId = job.JobId j.Name = job.JobName + j.JobGroup = job.JobGroup j.Args = job.Args j.MisfirePolicy = job.MisfirePolicy job.EntryId, err = jobs.AddJob(jobs.Crontab, j) diff --git a/apps/job/entity/job.go b/apps/job/entity/job.go index 59761a5..11d6e63 100644 --- a/apps/job/entity/job.go +++ b/apps/job/entity/job.go @@ -13,7 +13,7 @@ type SysJob struct { MisfirePolicy string `json:"misfirePolicy" gorm:"type:varchar(1);"` // 执行策略 Concurrent string `json:"concurrent" gorm:"type:varchar(1);"` // 是否并发 Status string `json:"status" gorm:"type:varchar(1);"` // 状态 - EntryId int `json:"entry_id" gorm:"type:int(11);"` // job启动时返回的id + EntryId int `json:"entryId" gorm:"type:int(11);"` // job启动时返回的id CreateBy string `json:"createBy" gorm:"type:varchar(128);comment:创建人"` UpdateBy string `json:"updateBy" gorm:"type:varchar(128);comment:更新者"` model.BaseModel diff --git a/apps/job/jobs/examples.go b/apps/job/jobs/examples.go index cc0ba85..e64457d 100644 --- a/apps/job/jobs/examples.go +++ b/apps/job/jobs/examples.go @@ -9,26 +9,24 @@ import ( // 字典 key 可以配置到 自动任务 调用目标 中; func InitJob() { jobList = map[string]JobsExec{ - "ExamplesOne": ExamplesOne{}, + "cronHandle": CronHandle{}, // ... } } // 新添加的job 必须按照以下格式定义,并实现Exec函数 -type ExamplesOne struct { +type CronHandle struct { } -func (t ExamplesOne) Exec(arg interface{}) error { +func (t CronHandle) Exec(arg interface{}) error { str := time.Now().Format(timeFormat) + " [INFO] JobCore ExamplesOne exec success" // TODO: 这里需要注意 Examples 传入参数是 string 所以 arg.(string);请根据对应的类型进行转化; switch arg.(type) { case string: if arg.(string) != "" { - fmt.Println("string", arg.(string)) fmt.Println(str, arg.(string)) } else { - fmt.Println("arg is nil") fmt.Println(str, "arg is nil") } break diff --git a/apps/job/jobs/jobbase.go b/apps/job/jobs/jobbase.go index 64cd5ff..2373f2d 100644 --- a/apps/job/jobs/jobbase.go +++ b/apps/job/jobs/jobbase.go @@ -4,6 +4,10 @@ import ( "fmt" "pandax/apps/job/entity" "pandax/apps/job/services" + + logEntity "pandax/apps/log/entity" + logServices "pandax/apps/log/services" + "pandax/base/global" "pandax/base/httpclient" "sync" @@ -23,6 +27,7 @@ var Crontab = new(cron.Cron) type JobCore struct { InvokeTarget string Name string + JobGroup string JobId int64 EntryId int CronExpression string // 任务表达式 @@ -45,7 +50,6 @@ func (e *ExecJob) Run() { startTime := time.Now() var obj = jobList[e.InvokeTarget] if obj == nil { - global.Log.Warn("[Job] ExecJob Run job nil") if e.MisfirePolicy == "2" { Remove(e.cron, e.EntryId) } @@ -53,22 +57,16 @@ func (e *ExecJob) Run() { } err := CallExec(obj.(JobsExec), e.Args) if err != nil { - // 如果失败暂停一段时间重试 - fmt.Println(time.Now().Format(timeFormat), " [ERROR] mission failed! ", err) if e.MisfirePolicy == "2" { Remove(e.cron, e.EntryId) return } } - // 结束时间 - endTime := time.Now() - // 执行时间 - latencyTime := endTime.Sub(startTime) - //TODO: 待完善部分 - //str := time.Now().Format(timeFormat) + " [INFO] JobCore " + string(e.EntryId) + "exec success , spend :" + latencyTime.String() - //ws.SendAll(str) - global.Log.Info("[Job] JobCore %s exec success , spend :%v", e.Name, latencyTime) + latencyTime := time.Now().Sub(startTime) + + logInfo := fmt.Sprintf("任务运行总耗时 %f", latencyTime.Seconds()) + logServices.LogJobModelDao.Insert(logEntity.LogJob{Name: e.Name, JobGroup: e.JobGroup, EntryId: e.EntryId, InvokeTarget: e.InvokeTarget, LogInfo: logInfo, Status: "0"}) // 执行一次 if e.MisfirePolicy == "1" { Remove(e.cron, e.EntryId) @@ -90,13 +88,11 @@ LOOP: goto LOOP } } - // 结束时间 - endTime := time.Now() - // 执行时间 - latencyTime := endTime.Sub(startTime) + latencyTime := time.Now().Sub(startTime) - global.Log.Infof("[Job] JobCore %s exec success , spend :%v", h.Name, latencyTime) + logInfo := fmt.Sprintf("任务运行总耗时 %f", latencyTime.Seconds()) + logServices.LogJobModelDao.Insert(logEntity.LogJob{Name: h.Name, JobGroup: h.JobGroup, EntryId: h.EntryId, InvokeTarget: h.InvokeTarget, LogInfo: logInfo, Status: "0"}) if h.MisfirePolicy == "1" { Remove(h.cron, h.EntryId) } @@ -105,8 +101,8 @@ LOOP: func Setup() { Crontab = NewWithSeconds() - // 获取系统job 0是默认,1是系统 - jl := services.JobModelDao.FindList(entity.SysJob{JobGroup: "1"}) + // 获取系统job SYSTEM是系统 + jl := services.JobModelDao.FindList(entity.SysJob{JobGroup: "SYSTEM"}) jobList := *jl if len(jobList) == 0 { global.Log.Info(time.Now().Format(timeFormat), " [INFO] JobCore total:0") @@ -127,6 +123,7 @@ func Setup() { j.CronExpression = jobList[i].CronExpression j.JobId = jobList[i].JobId j.Name = jobList[i].JobName + j.JobGroup = jobList[i].JobGroup j.MisfirePolicy = jobList[i].MisfirePolicy sysJob.EntryId, err = AddJob(Crontab, j) } else if jobList[i].JobType == "2" { @@ -135,6 +132,7 @@ func Setup() { j.CronExpression = jobList[i].CronExpression j.JobId = jobList[i].JobId j.Name = jobList[i].JobName + j.JobGroup = jobList[i].JobGroup j.Args = jobList[i].Args j.MisfirePolicy = jobList[i].MisfirePolicy sysJob.EntryId, err = AddJob(Crontab, j) diff --git a/apps/job/router/job.go b/apps/job/router/job.go index 86e5511..f30e2d0 100644 --- a/apps/job/router/job.go +++ b/apps/job/router/job.go @@ -40,12 +40,12 @@ func InitJobRouter(router *gin.RouterGroup) { }) stopJobLog := ctx.NewLogInfo("停止一个job") - job.DELETE(":jobId", func(c *gin.Context) { + job.GET("/stop/:jobId", func(c *gin.Context) { ctx.NewReqCtxWithGin(c).WithLog(stopJobLog).Handle(jobApi.StopJobForService) }) starteJobLog := ctx.NewLogInfo("开启一个job") - job.DELETE(":jobId", func(c *gin.Context) { + job.GET("/start/:jobId", func(c *gin.Context) { ctx.NewReqCtxWithGin(c).WithLog(starteJobLog).Handle(jobApi.StartJobForService) }) } diff --git a/apps/job/services/job.go b/apps/job/services/job.go index d661b6f..dea7770 100644 --- a/apps/job/services/job.go +++ b/apps/job/services/job.go @@ -47,7 +47,7 @@ func (m *jobModelImpl) FindListPage(page, pageSize int, data entity.SysJob) (*[] db := global.Db.Table(m.table) // 此处填写 where参数判断 if data.JobName != "" { - db = db.Where("job_name = ?", data.JobName) + db = db.Where("job_name like ? ", "%"+data.JobName+"%") } if data.Status != "" { db = db.Where("status = ?", data.Status) @@ -67,7 +67,7 @@ func (m *jobModelImpl) FindList(data entity.SysJob) *[]entity.SysJob { db := global.Db.Table(m.table) // 此处填写 where参数判断 if data.JobName != "" { - db = db.Where("job_name = ?", data.JobName) + db = db.Where("job_name like ? ", "%"+data.JobName+"%") } if data.Status != "" { db = db.Where("status = ?", data.Status) diff --git a/apps/log/api/log_job.go b/apps/log/api/log_job.go new file mode 100644 index 0000000..c6d5dae --- /dev/null +++ b/apps/log/api/log_job.go @@ -0,0 +1,63 @@ +package api + +import ( + "pandax/apps/log/entity" + "pandax/apps/log/services" + "pandax/base/ctx" + "pandax/base/ginx" + "pandax/base/utils" +) + +type LogJobApi struct { + LogJobApp services.LogJobModel +} + +// @Summary Job日志列表 +// @Description 获取JSON +// @Tags 任务日志 +// @Param status query string false "status" +// @Param jobGroup query string false "jobGroup" +// @Param name query string false "name" +// @Param pageSize query int false "页条数" +// @Param pageNum query int false "页码" +// @Success 200 {string} string "{"code": 200, "data": [...]}" +// @Router /log/logJob/list [get] +// @Security +func (l *LogJobApi) GetJobLogList(rc *ctx.ReqCtx) { + pageNum := ginx.QueryInt(rc.GinCtx, "pageNum", 1) + pageSize := ginx.QueryInt(rc.GinCtx, "pageSize", 10) + name := rc.GinCtx.Query("name") + jobGroup := rc.GinCtx.Query("jobGroup") + status := rc.GinCtx.Query("status") + + list, total := l.LogJobApp.FindListPage(pageNum, pageSize, entity.LogJob{Name: name, JobGroup: jobGroup, Status: status}) + rc.ResData = map[string]interface{}{ + "data": list, + "total": total, + "pageNum": pageNum, + "pageSize": pageSize, + } +} + +// @Summary 批量删除登录日志 +// @Description 删除数据 +// @Tags 任务日志 +// @Param logId path string true "以逗号(,)分割的logId" +// @Success 200 {string} string "{"code": 200, "message": "删除成功"}" +// @Success 200 {string} string "{"code": 400, "message": "删除失败"}" +// @Router /log/logJob/{logId} [delete] +func (l *LogJobApi) DeleteJobLog(rc *ctx.ReqCtx) { + logIds := rc.GinCtx.Param("logId") + group := utils.IdsStrToIdsIntGroup(logIds) + l.LogJobApp.Delete(group) +} + +// @Summary 清空登录日志 +// @Description 删除数据 +// @Tags 任务日志 +// @Success 200 {string} string "{"code": 200, "message": "删除成功"}" +// @Success 200 {string} string "{"code": 400, "message": "删除失败"}" +// @Router /log/logJob/all [delete] +func (l *LogJobApi) DeleteAll(rc *ctx.ReqCtx) { + l.LogJobApp.DeleteAll() +} diff --git a/apps/log/api/log_login.go b/apps/log/api/log_login.go index 0c32fb8..5009538 100644 --- a/apps/log/api/log_login.go +++ b/apps/log/api/log_login.go @@ -20,7 +20,7 @@ type LogLoginApi struct { // @Param pageSize query int false "页条数" // @Param pageNum query int false "页码" // @Success 200 {string} string "{"code": 200, "data": [...]}" -// @Router /system/log/list [get] +// @Router /log/logLogin/list [get] // @Security func (l *LogLoginApi) GetLoginLogList(rc *ctx.ReqCtx) { pageNum := ginx.QueryInt(rc.GinCtx, "pageNum", 1) @@ -42,7 +42,7 @@ func (l *LogLoginApi) GetLoginLogList(rc *ctx.ReqCtx) { // @Tags 登录日志 // @Param infoId path int true "infoId" // @Success 200 {string} string "{"code": 200, "data": [...]}" -// @Router /system/log/logLogin/{infoId} [get] +// @Router /log/logLogin/{infoId} [get] // @Security func (l *LogLoginApi) GetLoginLog(rc *ctx.ReqCtx) { infoId := ginx.PathParamInt(rc.GinCtx, rc.GinCtx.Param("infoId")) @@ -57,7 +57,7 @@ func (l *LogLoginApi) GetLoginLog(rc *ctx.ReqCtx) { // @Param data body entity.LogLogin true "body" // @Success 200 {string} string "{"code": 200, "message": "添加成功"}" // @Success 200 {string} string "{"code": 400, "message": "添加失败"}" -// @Router /system/log/logLogin [put] +// @Router /log/logLogin [put] // @Security X-TOKEN func (l *LogLoginApi) UpdateLoginLog(rc *ctx.ReqCtx) { var log entity.LogLogin @@ -71,7 +71,7 @@ func (l *LogLoginApi) UpdateLoginLog(rc *ctx.ReqCtx) { // @Param infoId path string true "以逗号(,)分割的infoId" // @Success 200 {string} string "{"code": 200, "message": "删除成功"}" // @Success 200 {string} string "{"code": 400, "message": "删除失败"}" -// @Router /system/log/logLogin/{infoId} [delete] +// @Router /log/logLogin/{infoId} [delete] func (l *LogLoginApi) DeleteLoginLog(rc *ctx.ReqCtx) { infoIds := rc.GinCtx.Param("infoId") group := utils.IdsStrToIdsIntGroup(infoIds) @@ -83,7 +83,7 @@ func (l *LogLoginApi) DeleteLoginLog(rc *ctx.ReqCtx) { // @Tags 登录日志 // @Success 200 {string} string "{"code": 200, "message": "删除成功"}" // @Success 200 {string} string "{"code": 400, "message": "删除失败"}" -// @Router /system/log/logLogin/all [delete] +// @Router /log/logLogin/all [delete] func (l *LogLoginApi) DeleteAll(rc *ctx.ReqCtx) { l.LogLoginApp.DeleteAll() } diff --git a/apps/log/api/log_oper.go b/apps/log/api/log_oper.go index def2565..4f37e76 100644 --- a/apps/log/api/log_oper.go +++ b/apps/log/api/log_oper.go @@ -21,7 +21,7 @@ type LogOperApi struct { // @Param pageSize query int false "页条数" // @Param pageNum query int false "页码" // @Success 200 {string} string "{"code": 200, "data": [...]}" -// @Router /system/log/list [get] +// @Router /log/logOper/list [get] // @Security func (l *LogOperApi) GetOperLogList(rc *ctx.ReqCtx) { pageNum := ginx.QueryInt(rc.GinCtx, "pageNum", 1) @@ -44,7 +44,7 @@ func (l *LogOperApi) GetOperLogList(rc *ctx.ReqCtx) { // @Tags 操作日志 // @Param operId path int true "operId" // @Success 200 {string} string "{"code": 200, "data": [...]}" -// @Router /system/log/logOper/{operId} [get] +// @Router /log/logOper/{operId} [get] // @Security func (l *LogOperApi) GetOperLog(rc *ctx.ReqCtx) { operId := ginx.PathParamInt(rc.GinCtx, rc.GinCtx.Param("operId")) @@ -57,7 +57,7 @@ func (l *LogOperApi) GetOperLog(rc *ctx.ReqCtx) { // @Param operId path string true "以逗号(,)分割的operId" // @Success 200 {string} string "{"code": 200, "message": "删除成功"}" // @Success 200 {string} string "{"code": 400, "message": "删除失败"}" -// @Router /system/log/logOper/{operId} [delete] +// @Router /log/logOper/{operId} [delete] func (l *LogOperApi) DeleteOperLog(rc *ctx.ReqCtx) { operIds := rc.GinCtx.Param("operId") group := utils.IdsStrToIdsIntGroup(operIds) @@ -70,7 +70,7 @@ func (l *LogOperApi) DeleteOperLog(rc *ctx.ReqCtx) { // @Tags 操作日志 // @Success 200 {string} string "{"code": 200, "message": "删除成功"}" // @Success 200 {string} string "{"code": 400, "message": "删除失败"}" -// @Router /system/log/logOper/all [delete] +// @Router /log/logOper/all [delete] func (l *LogOperApi) DeleteAll(rc *ctx.ReqCtx) { l.LogOperApp.DeleteAll() } diff --git a/apps/log/entity/log_job.go b/apps/log/entity/log_job.go new file mode 100644 index 0000000..94aaa4f --- /dev/null +++ b/apps/log/entity/log_job.go @@ -0,0 +1,16 @@ +package entity + +import ( + "pandax/base/model" +) + +type LogJob struct { + LogId int64 `json:"logId" gorm:"primary_key;AUTO_INCREMENT"` //主键 + Name string `json:"name" gorm:"type:varchar(128);comment:任务名称"` + JobGroup string `json:"jobGroup" gorm:"type:varchar(128);comment:分组"` + EntryId int `json:"entryId" gorm:"type:int(11);comment:任务id"` + InvokeTarget string `json:"invokeTarget" gorm:"type:varchar(128);comment:调用方法"` + LogInfo string `json:"logInfo" gorm:"type:varchar(255);comment:日志信息"` + Status string `json:"status" gorm:"type:varchar(1);comment:状态"` + model.BaseModel +} diff --git a/apps/log/router/log.go b/apps/log/router/log.go index 92e221c..c80b574 100644 --- a/apps/log/router/log.go +++ b/apps/log/router/log.go @@ -29,7 +29,7 @@ func InitLogRouter(router *gin.RouterGroup) { ctx.NewReqCtxWithGin(c).WithLog(updateLogLoginLog).Handle(login.UpdateLoginLog) }) - deleteLogLoginAllLog := ctx.NewLogInfo("删除登录日志信息") + deleteLogLoginAllLog := ctx.NewLogInfo("清空登录日志信息") logLogin.DELETE("all", func(c *gin.Context) { ctx.NewReqCtxWithGin(c).WithLog(deleteLogLoginAllLog).Handle(login.DeleteAll) }) @@ -55,7 +55,7 @@ func InitLogRouter(router *gin.RouterGroup) { ctx.NewReqCtxWithGin(c).WithLog(getLogOperLog).Handle(oper.GetOperLog) }) - deleteLogOperAllLog := ctx.NewLogInfo("删除操作日志信息") + deleteLogOperAllLog := ctx.NewLogInfo("清空操作日志信息") logOper.DELETE("all", func(c *gin.Context) { ctx.NewReqCtxWithGin(c).WithLog(deleteLogOperAllLog).Handle(oper.DeleteAll) }) @@ -64,4 +64,25 @@ func InitLogRouter(router *gin.RouterGroup) { logOper.DELETE(":operId", func(c *gin.Context) { ctx.NewReqCtxWithGin(c).WithLog(deleteLogOperLog).Handle(oper.DeleteOperLog) }) + + // Job日志 + job := &api.LogJobApi{ + LogJobApp: services.LogJobModelDao, + } + logJob := router.Group("logJob") + + logJobListLog := ctx.NewLogInfo("获取操作日志列表") + logJob.GET("list", func(c *gin.Context) { + ctx.NewReqCtxWithGin(c).WithLog(logJobListLog).Handle(job.GetJobLogList) + }) + + deleteLogJobAllLog := ctx.NewLogInfo("清空操作日志信息") + logJob.DELETE("all", func(c *gin.Context) { + ctx.NewReqCtxWithGin(c).WithLog(deleteLogJobAllLog).Handle(job.DeleteAll) + }) + + deleteLogJobLog := ctx.NewLogInfo("删除操作日志信息") + logJob.DELETE(":logId", func(c *gin.Context) { + ctx.NewReqCtxWithGin(c).WithLog(deleteLogJobLog).Handle(job.DeleteJobLog) + }) } diff --git a/apps/log/services/log_job.go b/apps/log/services/log_job.go new file mode 100644 index 0000000..4056fb6 --- /dev/null +++ b/apps/log/services/log_job.go @@ -0,0 +1,61 @@ +package services + +import ( + "pandax/apps/log/entity" + "pandax/base/biz" + "pandax/base/global" +) + +type ( + LogJobModel interface { + Insert(data entity.LogJob) *entity.LogJob + FindListPage(page, pageSize int, data entity.LogJob) (*[]entity.LogJob, int64) + Delete(infoId []int64) + DeleteAll() + } + + logJobModelImpl struct { + table string + } +) + +var LogJobModelDao LogJobModel = &logJobModelImpl{ + table: `log_jobs`, +} + +func (m *logJobModelImpl) Insert(data entity.LogJob) *entity.LogJob { + global.Db.Table(m.table).Create(&data) + return &data +} + +func (m *logJobModelImpl) FindListPage(page, pageSize int, data entity.LogJob) (*[]entity.LogJob, int64) { + list := make([]entity.LogJob, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Status != "" { + db = db.Where("status = ?", data.Status) + } + if data.JobGroup != "" { + db = db.Where("job_group = ?", data.JobGroup) + } + if data.Name != "" { + db = db.Where("name like ?", "%"+data.Name+"%") + } + err := db.Where("`delete_time` IS NULL").Count(&total).Error + err = db.Order("log_id desc").Limit(pageSize).Offset(offset).Find(&list).Error + + biz.ErrIsNil(err, "查询登录分页日志信息失败") + return &list, total +} + +func (m *logJobModelImpl) Delete(logIds []int64) { + err := global.Db.Table(m.table).Delete(&entity.LogJob{}, "`log_id` in (?)", logIds).Error + biz.ErrIsNil(err, "删除登录日志信息失败") + return +} + +func (m *logJobModelImpl) DeleteAll() { + global.Db.Exec("DELETE FROM log_jobs") +} diff --git a/apps/system/api/notice.go b/apps/system/api/notice.go new file mode 100644 index 0000000..68ac897 --- /dev/null +++ b/apps/system/api/notice.go @@ -0,0 +1,92 @@ +package api + +import ( + "pandax/apps/system/entity" + "pandax/apps/system/services" + "pandax/base/ctx" + "pandax/base/ginx" + "pandax/base/utils" + "strings" +) + +type NoticeApi struct { + DeptApp services.SysDeptModel + NoticeApp services.SysNoticeModel +} + +// @Summary 通知列表数据 +// @Description 获取JSON +// @Tags 通知 +// @Param noticeType query string false "noticeType" +// @Param title query string false "title" +// @Param pageSize query int false "页条数" +// @Param pageNum query int false "页码" +// @Success 200 {string} string "{"code": 200, "data": [...]}" +// @Router /system/post [get] +// @Security +func (p *NoticeApi) GetNoticeList(rc *ctx.ReqCtx) { + pageNum := ginx.QueryInt(rc.GinCtx, "pageNum", 1) + pageSize := ginx.QueryInt(rc.GinCtx, "pageSize", 10) + noticeType := rc.GinCtx.Query("noticeType") + title := rc.GinCtx.Query("title") + + // 获取部门的子部门id + one := p.DeptApp.FindOne(rc.LoginAccount.DeptId) + split := strings.Split(strings.Trim(one.DeptPath, "/"), "/") + ids := utils.DeptPCIds(split, rc.LoginAccount.DeptId, false) + notice := entity.SysNotice{NoticeType: noticeType, Title: title, DeptIds: ids} + list, total := p.NoticeApp.FindListPage(pageNum, pageSize, notice) + + rc.ResData = map[string]interface{}{ + "data": list, + "total": total, + "pageNum": pageNum, + "pageSize": pageSize, + } +} + +// @Summary 添加通知 +// @Description 获取JSON +// @Tags 通知 +// @Accept application/json +// @Product application/json +// @Param data body entity.SysNotice true "data" +// @Success 200 {string} string "{"code": 200, "message": "添加成功"}" +// @Success 200 {string} string "{"code": 400, "message": "添加失败"}" +// @Router /system/notice [post] +// @Security X-TOKEN +func (p *NoticeApi) InsertNotice(rc *ctx.ReqCtx) { + var notice entity.SysNotice + ginx.BindJsonAndValid(rc.GinCtx, ¬ice) + p.NoticeApp.Insert(notice) +} + +// @Summary 修改通知 +// @Description 获取JSON +// @Tags 通知 +// @Accept application/json +// @Product application/json +// @Param data body entity.SysNotice true "body" +// @Success 200 {string} string "{"code": 200, "message": "添加成功"}" +// @Success 200 {string} string "{"code": 400, "message": "添加失败"}" +// @Router /system/notice [put] +// @Security X-TOKEN +func (p *NoticeApi) UpdateNotice(rc *ctx.ReqCtx) { + var notice entity.SysNotice + ginx.BindJsonAndValid(rc.GinCtx, ¬ice) + + p.NoticeApp.Update(notice) +} + +// @Summary 删除通知 +// @Description 删除数据 +// @Tags 通知 +// @Param noticeId path string true "noticeId " +// @Success 200 {string} string "{"code": 200, "message": "删除成功"}" +// @Success 200 {string} string "{"code": 400, "message": "删除失败"}" +// @Router /system/notice/{noticeId} [delete] +func (p *NoticeApi) DeleteNotice(rc *ctx.ReqCtx) { + noticeId := rc.GinCtx.Param("noticeId") + noticeIds := utils.IdsStrToIdsIntGroup(noticeId) + p.NoticeApp.Delete(noticeIds) +} diff --git a/apps/system/entity/notice.go b/apps/system/entity/notice.go new file mode 100644 index 0000000..c77d117 --- /dev/null +++ b/apps/system/entity/notice.go @@ -0,0 +1,14 @@ +package entity + +import "pandax/base/model" + +type SysNotice struct { + NoticeId int64 `json:"noticeId" gorm:"primary_key;AUTO_INCREMENT"` + Title string `json:"title" gorm:"type:varchar(128);comment:标题"` + Content string `json:"content" gorm:"type:text;comment:标题"` + NoticeType string `json:"notice_type" gorm:"type:varchar(1);comment:通知类型"` + DeptId int64 `json:"deptId" gorm:"type:int(11);comment:部门Id,部门及子部门"` + + DeptIds []int64 `json:"deptIds" gorm:"-"` + model.BaseModel +} diff --git a/apps/system/router/api.go b/apps/system/router/api.go index e342333..d7920a4 100644 --- a/apps/system/router/api.go +++ b/apps/system/router/api.go @@ -2,13 +2,13 @@ package router import ( "github.com/gin-gonic/gin" - api2 "pandax/apps/system/api" - services "pandax/apps/system/services" + "pandax/apps/system/api" + "pandax/apps/system/services" "pandax/base/ctx" ) func InitApiRouter(router *gin.RouterGroup) { - s := &api2.SystemApiApi{ + s := &api.SystemApiApi{ ApiApp: services.SysSysApiModelDao, } api := router.Group("api") diff --git a/apps/system/router/config.go b/apps/system/router/config.go index 1135105..9737073 100644 --- a/apps/system/router/config.go +++ b/apps/system/router/config.go @@ -2,13 +2,13 @@ package router import ( "github.com/gin-gonic/gin" - api2 "pandax/apps/system/api" - services "pandax/apps/system/services" + "pandax/apps/system/api" + "pandax/apps/system/services" "pandax/base/ctx" ) func InitConfigRouter(router *gin.RouterGroup) { - s := &api2.ConfigApi{ + s := &api.ConfigApi{ ConfigApp: services.SysSysConfigModelDao, } config := router.Group("config") diff --git a/apps/system/router/dept.go b/apps/system/router/dept.go index 5681fc0..8c6c86c 100644 --- a/apps/system/router/dept.go +++ b/apps/system/router/dept.go @@ -2,13 +2,13 @@ package router import ( "github.com/gin-gonic/gin" - api2 "pandax/apps/system/api" - services "pandax/apps/system/services" + "pandax/apps/system/api" + "pandax/apps/system/services" "pandax/base/ctx" ) func InitDeptRouter(router *gin.RouterGroup) { - r := &api2.DeptApi{ + r := &api.DeptApi{ DeptApp: services.SysDeptModelDao, RoleApp: services.SysRoleModelDao, UserApp: services.SysUserModelDao, diff --git a/apps/system/router/dict.go b/apps/system/router/dict.go index efbd868..abaccf9 100644 --- a/apps/system/router/dict.go +++ b/apps/system/router/dict.go @@ -2,13 +2,13 @@ package router import ( "github.com/gin-gonic/gin" - api2 "pandax/apps/system/api" - services "pandax/apps/system/services" + "pandax/apps/system/api" + "pandax/apps/system/services" "pandax/base/ctx" ) func InitDictRouter(router *gin.RouterGroup) { - s := &api2.DictApi{ + s := &api.DictApi{ DictType: services.SysDictTypeModelDao, DictData: services.SysDictDataModelDao, } diff --git a/apps/system/router/menu.go b/apps/system/router/menu.go index 14c4192..72fff4f 100644 --- a/apps/system/router/menu.go +++ b/apps/system/router/menu.go @@ -2,13 +2,13 @@ package router import ( "github.com/gin-gonic/gin" - api2 "pandax/apps/system/api" - services "pandax/apps/system/services" + "pandax/apps/system/api" + "pandax/apps/system/services" "pandax/base/ctx" ) func InitMenuRouter(router *gin.RouterGroup) { - s := &api2.MenuApi{ + s := &api.MenuApi{ MenuApp: services.SysMenuModelDao, RoleApp: services.SysRoleModelDao, RoleMenuApp: services.SysRoleMenuModelDao, diff --git a/apps/system/router/notice.go b/apps/system/router/notice.go new file mode 100644 index 0000000..2f5c9cc --- /dev/null +++ b/apps/system/router/notice.go @@ -0,0 +1,36 @@ +package router + +import ( + "github.com/gin-gonic/gin" + "pandax/apps/system/api" + "pandax/apps/system/services" + "pandax/base/ctx" +) + +func InitNoticeRouter(router *gin.RouterGroup) { + s := &api.NoticeApi{ + DeptApp: services.SysDeptModelDao, + NoticeApp: services.SysNoticeModelDao, + } + notice := router.Group("notice") + + noticetList := ctx.NewLogInfo("获取通知分页列表") + notice.GET("list", func(c *gin.Context) { + ctx.NewReqCtxWithGin(c).WithLog(noticetList).Handle(s.GetNoticeList) + }) + + insertNoticeLog := ctx.NewLogInfo("添加通知信息") + notice.POST("", func(c *gin.Context) { + ctx.NewReqCtxWithGin(c).WithLog(insertNoticeLog).Handle(s.InsertNotice) + }) + + updateNoticeLog := ctx.NewLogInfo("修改通知信息") + notice.PUT("", func(c *gin.Context) { + ctx.NewReqCtxWithGin(c).WithLog(updateNoticeLog).Handle(s.UpdateNotice) + }) + + deleteNoticeLog := ctx.NewLogInfo("删除通知信息") + notice.DELETE(":postId", func(c *gin.Context) { + ctx.NewReqCtxWithGin(c).WithLog(deleteNoticeLog).Handle(s.DeleteNotice) + }) +} diff --git a/apps/system/router/post.go b/apps/system/router/post.go index 3ccdb55..09fe42c 100644 --- a/apps/system/router/post.go +++ b/apps/system/router/post.go @@ -2,13 +2,13 @@ package router import ( "github.com/gin-gonic/gin" - api2 "pandax/apps/system/api" - services "pandax/apps/system/services" + "pandax/apps/system/api" + "pandax/apps/system/services" "pandax/base/ctx" ) func InitPostRouter(router *gin.RouterGroup) { - s := &api2.PostApi{ + s := &api.PostApi{ PostApp: services.SysPostModelDao, UserApp: services.SysUserModelDao, RoleApp: services.SysRoleModelDao, diff --git a/apps/system/router/role.go b/apps/system/router/role.go index 4711f07..de031be 100644 --- a/apps/system/router/role.go +++ b/apps/system/router/role.go @@ -2,13 +2,13 @@ package router import ( "github.com/gin-gonic/gin" - api2 "pandax/apps/system/api" - services "pandax/apps/system/services" + "pandax/apps/system/api" + "pandax/apps/system/services" "pandax/base/ctx" ) func InitRoleRouter(router *gin.RouterGroup) { - s := &api2.RoleApi{ + s := &api.RoleApi{ RoleApp: services.SysRoleModelDao, RoleMenuApp: services.SysRoleMenuModelDao, RoleDeptApp: services.SysRoleDeptModelDao, diff --git a/apps/system/router/system.go b/apps/system/router/system.go index 7910d48..0c186d8 100644 --- a/apps/system/router/system.go +++ b/apps/system/router/system.go @@ -2,11 +2,11 @@ package router import ( "github.com/gin-gonic/gin" - api2 "pandax/apps/system/api" + "pandax/apps/system/api" ) func InitSystemRouter(router *gin.RouterGroup) { - s := &api2.System{} + s := &api.System{} sys := router.Group("") { diff --git a/apps/system/router/user.go b/apps/system/router/user.go index c2c014c..9f69a3f 100644 --- a/apps/system/router/user.go +++ b/apps/system/router/user.go @@ -2,7 +2,7 @@ package router import ( "github.com/gin-gonic/gin" - api2 "pandax/apps/system/api" + "pandax/apps/system/api" "pandax/apps/system/services" logServices "pandax/apps/log/services" @@ -10,7 +10,7 @@ import ( ) func InitUserRouter(router *gin.RouterGroup) { - s := &api2.UserApi{ + s := &api.UserApi{ RoleApp: services.SysRoleModelDao, MenuApp: services.SysMenuModelDao, RoleMenuApp: services.SysRoleMenuModelDao, diff --git a/apps/system/services/dept.go b/apps/system/services/dept.go index 83e06a0..9954e0a 100644 --- a/apps/system/services/dept.go +++ b/apps/system/services/dept.go @@ -1,6 +1,8 @@ package services import ( + "errors" + "github.com/kakuilan/kgo" "pandax/apps/system/entity" "pandax/base/biz" "pandax/base/global" @@ -29,6 +31,15 @@ var SysDeptModelDao = &sysDeptModelImpl{ func (m *sysDeptModelImpl) Insert(data entity.SysDept) *entity.SysDept { biz.ErrIsNil(global.Db.Table(m.table).Create(&data).Error, "新增部门信息失败") + deptPath := "/" + kgo.KConv.Int2Str(data.DeptId) + if int(data.ParentId) != 0 { + deptP := m.FindOne(data.ParentId) + deptPath = deptP.DeptPath + deptPath + } else { + deptPath = "/0" + deptPath + } + data.DeptPath = deptPath + biz.ErrIsNil(global.Db.Table(m.table).Model(&data).Updates(&data).Error, "修改部门信息失败") return &data } @@ -86,8 +97,21 @@ func (m *sysDeptModelImpl) FindList(data entity.SysDept) *[]entity.SysDept { } func (m *sysDeptModelImpl) Update(data entity.SysDept) *entity.SysDept { - err := global.Db.Table(m.table).Model(&data).Updates(&data).Error - biz.ErrIsNil(err, "修改部门信息失败") + one := m.FindOne(data.DeptId) + + deptPath := "/" + kgo.KConv.Int2Str(data.DeptId) + if int(data.ParentId) != 0 { + deptP := m.FindOne(data.ParentId) + deptPath = deptP.DeptPath + deptPath + } else { + deptPath = "/0" + deptPath + } + data.DeptPath = deptPath + + if data.DeptPath != "" && data.DeptPath != one.DeptPath { + biz.ErrIsNil(errors.New("上级部门不允许修改!"), "上级部门不允许修改") + } + biz.ErrIsNil(global.Db.Table(m.table).Model(&data).Updates(&data).Error, "修改部门信息失败") return &data } diff --git a/apps/system/services/notice.go b/apps/system/services/notice.go new file mode 100644 index 0000000..1f86b12 --- /dev/null +++ b/apps/system/services/notice.go @@ -0,0 +1,69 @@ +package services + +import ( + "pandax/apps/system/entity" + "pandax/base/biz" + "pandax/base/global" +) + +type ( + SysNoticeModel interface { + Insert(data entity.SysNotice) *entity.SysNotice + FindOne(postId int64) *entity.SysNotice + FindListPage(page, pageSize int, data entity.SysNotice) (*[]entity.SysNotice, int64) + Update(data entity.SysNotice) *entity.SysNotice + Delete(postId []int64) + } + + sysNoticeModelImpl struct { + table string + } +) + +var SysNoticeModelDao SysNoticeModel = &sysNoticeModelImpl{ + table: `sys_notices`, +} + +func (m *sysNoticeModelImpl) Insert(data entity.SysNotice) *entity.SysNotice { + err := global.Db.Table(m.table).Create(&data).Error + biz.ErrIsNil(err, "添加通知失败") + return &data +} + +func (m *sysNoticeModelImpl) FindOne(postId int64) *entity.SysNotice { + resData := new(entity.SysNotice) + err := global.Db.Table(m.table).Where("`post_id` = ?", postId).First(resData).Error + biz.ErrIsNil(err, "查询通知失败") + return resData +} + +func (m *sysNoticeModelImpl) FindListPage(page, pageSize int, data entity.SysNotice) (*[]entity.SysNotice, int64) { + list := make([]entity.SysNotice, 0) + var total int64 = 0 + offset := pageSize * (page - 1) + db := global.Db.Table(m.table) + // 此处填写 where参数判断 + if data.Title != "" { + db = db.Where("title like ?", "%"+data.Title+"%") + } + if data.NoticeType != "" { + db = db.Where("notice_type = ?", data.NoticeType) + } + if len(data.DeptIds) > 0 { + db = db.Where("`dept_id` in (?)", data.DeptIds) + } + db.Where("delete_time IS NULL") + err := db.Count(&total).Error + err = db.Order("create_time").Limit(pageSize).Offset(offset).Find(&list).Error + biz.ErrIsNil(err, "查询通知分页列表失败") + return &list, total +} + +func (m *sysNoticeModelImpl) Update(data entity.SysNotice) *entity.SysNotice { + biz.ErrIsNil(global.Db.Table(m.table).Updates(&data).Error, "修改通知失败") + return &data +} + +func (m *sysNoticeModelImpl) Delete(postIds []int64) { + biz.ErrIsNil(global.Db.Table(m.table).Delete(&entity.SysNotice{}, "`notice_id` in (?)", postIds).Error, "删除通知失败") +} diff --git a/base/utils/str_utils.go b/base/utils/str_utils.go index 652ea6c..9a8305e 100644 --- a/base/utils/str_utils.go +++ b/base/utils/str_utils.go @@ -3,6 +3,7 @@ package utils import ( "bytes" "github.com/kakuilan/kgo" + "log" "strings" "text/template" ) @@ -68,3 +69,29 @@ func IdsStrToIdsIntGroup(keys string) []int64 { } return IDS } + +// 获取部门 +// isP 是父ID 否则子ID +func DeptPCIds(deptIds []string, id int64, isP bool) []int64 { + pRes := make([]int64, 0) + cRes := make([]int64, 0) + is := true + for _, deptId := range deptIds { + did := kgo.KConv.Str2Int64(deptId) + log.Println(did) + if is { + pRes = append(pRes, did) + } + if kgo.KConv.Str2Int64(deptId) == id { + is = false + } + if !is { + cRes = append(cRes, did) + } + } + if isP { + return pRes + } else { + return cRes + } +} diff --git a/base/utils/str_utils_test.go b/base/utils/str_utils_test.go index d488ee2..6bf14d3 100644 --- a/base/utils/str_utils_test.go +++ b/base/utils/str_utils_test.go @@ -1,6 +1,10 @@ package utils -import "testing" +import ( + "log" + "strings" + "testing" +) func TestIdsStrToIdsIntGroup(t *testing.T) { group := IdsStrToIdsIntGroup("aaa") @@ -11,3 +15,12 @@ func TestGetRealAddressByIP(t *testing.T) { ip := GetRealAddressByIP("10.42.0.1") t.Log(ip) } + +func TestDeptPCIds(t *testing.T) { + ss := strings.Trim("/0/2/6/4", "/") + + split := strings.Split(ss, "/") + log.Println("split", split) + ids := DeptPCIds(split, 4, false) + t.Log(ids) +} diff --git a/initialize/router.go b/initialize/router.go index 148031f..a5efd68 100644 --- a/initialize/router.go +++ b/initialize/router.go @@ -4,6 +4,8 @@ import ( "fmt" ginSwagger "github.com/swaggo/gin-swagger" "github.com/swaggo/gin-swagger/swaggerFiles" + + jobRouter "pandax/apps/job/router" logRouter "pandax/apps/log/router" sysRouter "pandax/apps/system/router" @@ -61,10 +63,11 @@ func InitRouter() *gin.Engine { sysRouter.InitRoleRouter(sys) sysRouter.InitPostRouter(sys) sysRouter.InitUserRouter(sys) + sysRouter.InitNoticeRouter(sys) } - router.Group("job") + job := router.Group("job") { - + jobRouter.InitJobRouter(job) } //日志系统 log := router.Group("log") diff --git a/initialize/table.go b/initialize/table.go index bd7bcd2..3b9e181 100644 --- a/initialize/table.go +++ b/initialize/table.go @@ -3,10 +3,10 @@ package initialize import ( "pandax/apps/system/entity" + jobEntity "pandax/apps/job/entity" logEntity "pandax/apps/log/entity" "pandax/base/biz" - "pandax/base/casbin" "pandax/base/config" "pandax/base/global" ) @@ -17,7 +17,6 @@ func InitTable() { if m.IsInitTable { biz.ErrIsNil( global.Db.AutoMigrate( - casbin.CasbinRule{}, entity.SysDept{}, entity.SysApi{}, entity.SysConfig{}, @@ -25,12 +24,16 @@ func InitTable() { entity.SysDictData{}, logEntity.LogLogin{}, logEntity.LogOper{}, + logEntity.LogJob{}, entity.SysUser{}, entity.SysRole{}, entity.SysMenu{}, entity.SysPost{}, entity.SysRoleMenu{}, - entity.SysRoleDept{}), "初始化表失败") + entity.SysRoleDept{}, + entity.SysNotice{}, + jobEntity.SysJob{}), + "初始化表失败") } } diff --git a/main.go b/main.go index 6018c9d..ccefcdf 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "pandax/apps/job/jobs" "pandax/base/config" "pandax/base/ctx" "pandax/base/global" @@ -12,8 +13,16 @@ import ( func main() { global.Db = starter.GormInit(config.Conf.Server.DbType) initialize.InitTable() + // gin后置 函数 ctx.UseAfterHandlerInterceptor(middleware.OperationHandler) + // gin前置 函数 ctx.UseBeforeHandlerInterceptor(ctx.PermissionHandler) + // gin后置 函数 ctx.UseAfterHandlerInterceptor(ctx.LogHandler) + go func() { + // 启动系统调度任务 + jobs.InitJob() + jobs.Setup() + }() starter.RunWebServer(initialize.InitRouter()) }