diff --git a/api/v1/enter.go b/api/v1/enter.go index 7120c18..647326f 100644 --- a/api/v1/enter.go +++ b/api/v1/enter.go @@ -5,6 +5,7 @@ import ( "git.echol.cn/loser/lckt/api/v1/bot" "git.echol.cn/loser/lckt/api/v1/category" "git.echol.cn/loser/lckt/api/v1/example" + "git.echol.cn/loser/lckt/api/v1/notice" "git.echol.cn/loser/lckt/api/v1/system" "git.echol.cn/loser/lckt/api/v1/user" "git.echol.cn/loser/lckt/api/v1/vip" @@ -20,4 +21,5 @@ type ApiGroup struct { ArticleApiGroup article.ApiGroup UserApiGroup user.APPUserApi VipApiGroup vip.ApiGroup + NoticeApiGroup notice.ApiGroup } diff --git a/api/v1/notice/enter.go b/api/v1/notice/enter.go new file mode 100644 index 0000000..3ba8adb --- /dev/null +++ b/api/v1/notice/enter.go @@ -0,0 +1,12 @@ +package notice + +import ( + "git.echol.cn/loser/lckt/service" +) + +type ApiGroup struct{ NoticeApi } + +var ( + noticeService = service.ServiceGroupApp.NoticeServiceGroup.NoticeService + notService = service.ServiceGroupApp.NoticeServiceGroup.NoticeService +) diff --git a/api/v1/notice/notice.go b/api/v1/notice/notice.go new file mode 100644 index 0000000..d0c8ddf --- /dev/null +++ b/api/v1/notice/notice.go @@ -0,0 +1,188 @@ +package notice + +import ( + "git.echol.cn/loser/lckt/global" + "git.echol.cn/loser/lckt/model/common/response" + "git.echol.cn/loser/lckt/model/notice" + noticeReq "git.echol.cn/loser/lckt/model/notice/request" + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +type NoticeApi struct{} + +// CreateNotice 创建通知 +// @Tags Notice +// @Summary 创建通知 +// @Security ApiKeyAuth +// @Accept application/json +// @Produce application/json +// @Param data body notice.Notice true "创建通知" +// @Success 200 {object} response.Response{msg=string} "创建成功" +// @Router /not/createNotice [post] +func (notApi *NoticeApi) CreateNotice(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + + var not notice.Notice + err := c.ShouldBindJSON(¬) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = notService.CreateNotice(ctx, ¬) + if err != nil { + global.GVA_LOG.Error("创建失败!", zap.Error(err)) + response.FailWithMessage("创建失败:"+err.Error(), c) + return + } + response.OkWithMessage("创建成功", c) +} + +// DeleteNotice 删除通知 +// @Tags Notice +// @Summary 删除通知 +// @Security ApiKeyAuth +// @Accept application/json +// @Produce application/json +// @Param data body notice.Notice true "删除通知" +// @Success 200 {object} response.Response{msg=string} "删除成功" +// @Router /not/deleteNotice [delete] +func (notApi *NoticeApi) DeleteNotice(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + + ID := c.Query("ID") + err := notService.DeleteNotice(ctx, ID) + if err != nil { + global.GVA_LOG.Error("删除失败!", zap.Error(err)) + response.FailWithMessage("删除失败:"+err.Error(), c) + return + } + response.OkWithMessage("删除成功", c) +} + +// DeleteNoticeByIds 批量删除通知 +// @Tags Notice +// @Summary 批量删除通知 +// @Security ApiKeyAuth +// @Accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{msg=string} "批量删除成功" +// @Router /not/deleteNoticeByIds [delete] +func (notApi *NoticeApi) DeleteNoticeByIds(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + + IDs := c.QueryArray("IDs[]") + err := notService.DeleteNoticeByIds(ctx, IDs) + if err != nil { + global.GVA_LOG.Error("批量删除失败!", zap.Error(err)) + response.FailWithMessage("批量删除失败:"+err.Error(), c) + return + } + response.OkWithMessage("批量删除成功", c) +} + +// UpdateNotice 更新通知 +// @Tags Notice +// @Summary 更新通知 +// @Security ApiKeyAuth +// @Accept application/json +// @Produce application/json +// @Param data body notice.Notice true "更新通知" +// @Success 200 {object} response.Response{msg=string} "更新成功" +// @Router /not/updateNotice [put] +func (notApi *NoticeApi) UpdateNotice(c *gin.Context) { + // 从ctx获取标准context进行业务行为 + ctx := c.Request.Context() + + var not notice.Notice + err := c.ShouldBindJSON(¬) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + err = notService.UpdateNotice(ctx, not) + if err != nil { + global.GVA_LOG.Error("更新失败!", zap.Error(err)) + response.FailWithMessage("更新失败:"+err.Error(), c) + return + } + response.OkWithMessage("更新成功", c) +} + +// FindNotice 用id查询通知 +// @Tags Notice +// @Summary 用id查询通知 +// @Security ApiKeyAuth +// @Accept application/json +// @Produce application/json +// @Param ID query uint true "用id查询通知" +// @Success 200 {object} response.Response{data=notice.Notice,msg=string} "查询成功" +// @Router /not/findNotice [get] +func (notApi *NoticeApi) FindNotice(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + + ID := c.Query("ID") + renot, err := notService.GetNotice(ctx, ID) + if err != nil { + global.GVA_LOG.Error("查询失败!", zap.Error(err)) + response.FailWithMessage("查询失败:"+err.Error(), c) + return + } + response.OkWithData(renot, c) +} + +// GetNoticeList 分页获取通知列表 +// @Tags Notice +// @Summary 分页获取通知列表 +// @Security ApiKeyAuth +// @Accept application/json +// @Produce application/json +// @Param data query noticeReq.NoticeSearch true "分页获取通知列表" +// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功" +// @Router /not/getNoticeList [get] +func (notApi *NoticeApi) GetNoticeList(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + + var pageInfo noticeReq.NoticeSearch + err := c.ShouldBindQuery(&pageInfo) + if err != nil { + response.FailWithMessage(err.Error(), c) + return + } + list, total, err := notService.GetNoticeInfoList(ctx, pageInfo) + if err != nil { + global.GVA_LOG.Error("获取失败!", zap.Error(err)) + response.FailWithMessage("获取失败:"+err.Error(), c) + return + } + response.OkWithDetailed(response.PageResult{ + List: list, + Total: total, + Page: pageInfo.Page, + PageSize: pageInfo.PageSize, + }, "获取成功", c) +} + +// GetNoticePublic 不需要鉴权的通知接口 +// @Tags Notice +// @Summary 不需要鉴权的通知接口 +// @Accept application/json +// @Produce application/json +// @Success 200 {object} response.Response{data=object,msg=string} "获取成功" +// @Router /not/getNoticePublic [get] +func (notApi *NoticeApi) GetNoticePublic(c *gin.Context) { + // 创建业务用Context + ctx := c.Request.Context() + + // 此接口不需要鉴权 + // 示例为返回了一个固定的消息接口,一般本接口用于C端服务,需要自己实现业务逻辑 + notService.GetNoticePublic(ctx) + response.OkWithDetailed(gin.H{ + "info": "不需要鉴权的通知接口信息", + }, "获取成功", c) +} diff --git a/config.yaml b/config.yaml index b7e69b0..4d54f86 100644 --- a/config.yaml +++ b/config.yaml @@ -7,8 +7,8 @@ aliyun-oss: base-path: yourBasePath autocode: web: web/src - root: C:\Users\Administrator\Desktop\lckt - server: server + root: C:\Users\Administrator\GolandProjects\zb + server: lckt-server module: git.echol.cn/loser/lckt ai-path: "https://ai.gin-vue-admin.com/{FUNC}/loser7659/c178e970-6a59-497d-96ed-86fee6b3285a" aws-s3: diff --git a/go.mod b/go.mod index 7a2aae1..1e2c190 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,11 @@ go 1.23 toolchain go1.23.2 require ( + github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7 github.com/ArtisanCloud/PowerWeChat/v3 v3.4.6 github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7 github.com/alibabacloud-go/dysmsapi-20170525/v4 v4.1.2 + github.com/alibabacloud-go/tea v1.3.8 github.com/alibabacloud-go/tea-utils/v2 v2.0.7 github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible github.com/aws/aws-sdk-go v1.55.6 @@ -60,7 +62,6 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/ArtisanCloud/PowerLibs/v3 v3.3.2 // indirect - github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7 // indirect github.com/BurntSushi/toml v1.4.0 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/STARRY-S/zip v0.1.0 // indirect @@ -69,7 +70,6 @@ require ( github.com/alibabacloud-go/debug v1.0.1 // indirect github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect github.com/alibabacloud-go/openapi-util v0.1.1 // indirect - github.com/alibabacloud-go/tea v1.3.8 // indirect github.com/aliyun/credentials-go v1.4.5 // indirect github.com/andybalholm/brotli v1.1.1 // indirect github.com/bmatcuk/doublestar/v4 v4.8.0 // indirect diff --git a/initialize/gorm_biz.go b/initialize/gorm_biz.go index e88a681..7e3cadb 100644 --- a/initialize/gorm_biz.go +++ b/initialize/gorm_biz.go @@ -5,19 +5,14 @@ import ( "git.echol.cn/loser/lckt/model/article" "git.echol.cn/loser/lckt/model/bot" "git.echol.cn/loser/lckt/model/category" + "git.echol.cn/loser/lckt/model/notice" "git.echol.cn/loser/lckt/model/user" "git.echol.cn/loser/lckt/model/vip" ) func bizModel() error { db := global.GVA_DB - err := db.AutoMigrate( - category.Category{}, - bot.Bot{}, - article.Article{}, - user.User{}, - vip.Vip{}, - ) + err := db.AutoMigrate(category.Category{}, bot.Bot{}, article.Article{}, user.User{}, vip.Vip{}, notice.Notice{}, notice.Notice{}) if err != nil { return err } diff --git a/initialize/router_biz.go b/initialize/router_biz.go index ffda167..8cae4bf 100644 --- a/initialize/router_biz.go +++ b/initialize/router_biz.go @@ -16,7 +16,7 @@ func initBizRouter(routers ...*gin.RouterGroup) { { categoryRouter := router.RouterGroupApp.Category categoryRouter.InitCategoryRouter(privateGroup, publicGroup) - } // 占位方法,保证文件可以正确加载,避免go空变量检测报错,请勿删除。 + } { botRouter := router.RouterGroupApp.Bot botRouter.InitBotRouter(privateGroup, publicGroup) @@ -34,4 +34,8 @@ func initBizRouter(routers ...*gin.RouterGroup) { vipRouter := router.RouterGroupApp.Vip vipRouter.InitVipRouter(privateGroup, publicGroup) } + { + noticeRouter := router.RouterGroupApp.Notice + noticeRouter.InitNoticeRouter(privateGroup, publicGroup) // 占位方法,保证文件可以正确加载,避免go空变量检测报错,请勿删除。 + } } diff --git a/model/notice/notice.go b/model/notice/notice.go new file mode 100644 index 0000000..9e5d1b6 --- /dev/null +++ b/model/notice/notice.go @@ -0,0 +1,19 @@ +// 自动生成模板Notice +package notice + +import ( + "git.echol.cn/loser/lckt/global" +) + +// 通知 结构体 Notice +type Notice struct { + global.GVA_MODEL + Title *string `json:"title" form:"title" gorm:"column:title;comment:;" binding:"required"` //标题 + Content *string `json:"content" form:"content" gorm:"column:content;comment:;type:text;" binding:"required"` //内容 + Status *int `json:"status" form:"status" gorm:"column:status;comment:状态;"` //状态 +} + +// TableName 通知 Notice自定义表名 notice +func (Notice) TableName() string { + return "notice" +} diff --git a/model/notice/request/notice.go b/model/notice/request/notice.go new file mode 100644 index 0000000..52c7494 --- /dev/null +++ b/model/notice/request/notice.go @@ -0,0 +1,14 @@ +package request + +import ( + "git.echol.cn/loser/lckt/model/common/request" + "time" +) + +type NoticeSearch struct { + StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"` + EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"` + request.PageInfo + Sort string `json:"sort" form:"sort"` + Order string `json:"order" form:"order"` +} diff --git a/router/enter.go b/router/enter.go index 391caf6..f2e3067 100644 --- a/router/enter.go +++ b/router/enter.go @@ -5,6 +5,7 @@ import ( "git.echol.cn/loser/lckt/router/bot" "git.echol.cn/loser/lckt/router/category" "git.echol.cn/loser/lckt/router/example" + "git.echol.cn/loser/lckt/router/notice" "git.echol.cn/loser/lckt/router/system" "git.echol.cn/loser/lckt/router/user" "git.echol.cn/loser/lckt/router/vip" @@ -20,4 +21,5 @@ type RouterGroup struct { Article article.RouterGroup User user.UserRouter Vip vip.VipRouter + Notice notice.NoticeRouter } diff --git a/router/notice/enter.go b/router/notice/enter.go new file mode 100644 index 0000000..366a858 --- /dev/null +++ b/router/notice/enter.go @@ -0,0 +1,9 @@ +package notice + +import api "git.echol.cn/loser/lckt/api/v1" + +type RouterGroup struct{ NoticeRouter } + +var ( + notApi = api.ApiGroupApp.NoticeApiGroup.NoticeApi +) diff --git a/router/notice/notice.go b/router/notice/notice.go new file mode 100644 index 0000000..3995fc1 --- /dev/null +++ b/router/notice/notice.go @@ -0,0 +1,28 @@ +package notice + +import ( + "git.echol.cn/loser/lckt/middleware" + "github.com/gin-gonic/gin" +) + +type NoticeRouter struct{} + +// InitNoticeRouter 初始化 通知 路由信息 +func (s *NoticeRouter) InitNoticeRouter(Router *gin.RouterGroup, PublicRouter *gin.RouterGroup) { + notRouter := Router.Group("not").Use(middleware.OperationRecord()) + notRouterWithoutRecord := Router.Group("not") + notRouterWithoutAuth := PublicRouter.Group("not") + { + notRouter.POST("createNotice", notApi.CreateNotice) // 新建通知 + notRouter.DELETE("deleteNotice", notApi.DeleteNotice) // 删除通知 + notRouter.DELETE("deleteNoticeByIds", notApi.DeleteNoticeByIds) // 批量删除通知 + notRouter.PUT("updateNotice", notApi.UpdateNotice) // 更新通知 + } + { + notRouterWithoutRecord.GET("findNotice", notApi.FindNotice) // 根据ID获取通知 + notRouterWithoutRecord.GET("getNoticeList", notApi.GetNoticeList) // 获取通知列表 + } + { + notRouterWithoutAuth.GET("getNoticePublic", notApi.GetNoticePublic) // 通知开放接口 + } +} diff --git a/service/enter.go b/service/enter.go index 1a94396..a3f513a 100644 --- a/service/enter.go +++ b/service/enter.go @@ -5,6 +5,7 @@ import ( "git.echol.cn/loser/lckt/service/bot" "git.echol.cn/loser/lckt/service/category" "git.echol.cn/loser/lckt/service/example" + "git.echol.cn/loser/lckt/service/notice" "git.echol.cn/loser/lckt/service/system" "git.echol.cn/loser/lckt/service/user" "git.echol.cn/loser/lckt/service/vip" @@ -20,4 +21,5 @@ type ServiceGroup struct { ArticleGroup article.ServiceGroup UserServiceGroup user.ServiceGroup VipServiceGroup vip.ServiceGroup + NoticeServiceGroup notice.ServiceGroup } diff --git a/service/notice/enter.go b/service/notice/enter.go new file mode 100644 index 0000000..a786c03 --- /dev/null +++ b/service/notice/enter.go @@ -0,0 +1,3 @@ +package notice + +type ServiceGroup struct{ NoticeService } diff --git a/service/notice/notice.go b/service/notice/notice.go new file mode 100644 index 0000000..7c2aa54 --- /dev/null +++ b/service/notice/notice.go @@ -0,0 +1,84 @@ +package notice + +import ( + "context" + "git.echol.cn/loser/lckt/global" + "git.echol.cn/loser/lckt/model/notice" + noticeReq "git.echol.cn/loser/lckt/model/notice/request" +) + +type NoticeService struct{} + +// CreateNotice 创建通知记录 +// Author [yourname](https://github.com/yourname) +func (notService *NoticeService) CreateNotice(ctx context.Context, not *notice.Notice) (err error) { + err = global.GVA_DB.Create(not).Error + return err +} + +// DeleteNotice 删除通知记录 +// Author [yourname](https://github.com/yourname) +func (notService *NoticeService) DeleteNotice(ctx context.Context, ID string) (err error) { + err = global.GVA_DB.Delete(¬ice.Notice{}, "id = ?", ID).Error + return err +} + +// DeleteNoticeByIds 批量删除通知记录 +// Author [yourname](https://github.com/yourname) +func (notService *NoticeService) DeleteNoticeByIds(ctx context.Context, IDs []string) (err error) { + err = global.GVA_DB.Delete(&[]notice.Notice{}, "id in ?", IDs).Error + return err +} + +// UpdateNotice 更新通知记录 +// Author [yourname](https://github.com/yourname) +func (notService *NoticeService) UpdateNotice(ctx context.Context, not notice.Notice) (err error) { + err = global.GVA_DB.Model(¬ice.Notice{}).Where("id = ?", not.ID).Updates(¬).Error + return err +} + +// GetNotice 根据ID获取通知记录 +// Author [yourname](https://github.com/yourname) +func (notService *NoticeService) GetNotice(ctx context.Context, ID string) (not notice.Notice, err error) { + err = global.GVA_DB.Where("id = ?", ID).First(¬).Error + return +} + +// GetNoticeInfoList 分页获取通知记录 +// Author [yourname](https://github.com/yourname) +func (notService *NoticeService) GetNoticeInfoList(ctx context.Context, info noticeReq.NoticeSearch) (list []notice.Notice, total int64, err error) { + limit := info.PageSize + offset := info.PageSize * (info.Page - 1) + // 创建db + db := global.GVA_DB.Model(¬ice.Notice{}) + var nots []notice.Notice + // 如果有条件搜索 下方会自动创建搜索语句 + if info.StartCreatedAt != nil && info.EndCreatedAt != nil { + db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt) + } + err = db.Count(&total).Error + if err != nil { + return + } + var OrderStr string + orderMap := make(map[string]bool) + orderMap["title"] = true + if orderMap[info.Sort] { + OrderStr = info.Sort + if info.Order == "descending" { + OrderStr = OrderStr + " desc" + } + db = db.Order(OrderStr) + } + + if limit != 0 { + db = db.Limit(limit).Offset(offset) + } + + err = db.Find(¬s).Error + return nots, total, err +} +func (notService *NoticeService) GetNoticePublic(ctx context.Context) { + // 此方法为获取数据源定义的数据 + // 请自行实现 +}