diff --git a/api/v1/plant/enter.go b/api/v1/plant/enter.go index 5c43209..3de3d2e 100644 --- a/api/v1/plant/enter.go +++ b/api/v1/plant/enter.go @@ -6,10 +6,14 @@ type ApiGroup struct { MyPlantApi TopicApi PostApi + WikiClassApi + WikiApi } var ( - plantService = service.GroupApp.PlantServiceGroup.MyPlantService - topicService = service.GroupApp.PlantServiceGroup.TopicService - postService = service.GroupApp.PlantServiceGroup.PostService + plantService = service.GroupApp.PlantServiceGroup.MyPlantService + topicService = service.GroupApp.PlantServiceGroup.TopicService + postService = service.GroupApp.PlantServiceGroup.PostService + wikiClassService = service.GroupApp.PlantServiceGroup.WikiClassService + wikiService = service.GroupApp.PlantServiceGroup.WikiService ) diff --git a/api/v1/plant/topic.go b/api/v1/plant/topic.go index 95893ca..a83169b 100644 --- a/api/v1/plant/topic.go +++ b/api/v1/plant/topic.go @@ -77,8 +77,8 @@ func (a *TopicApi) TopicPage(c *gin.Context) { } list, total, err := topicService.TopicPage(req) if err != nil { - global.Logger.Error("修改话题失败", zap.Error(err)) - response.FailWithMsg("修改话题失败", c) + global.Logger.Error("分页话题失败", zap.Error(err)) + response.FailWithMsg("分页话题失败", c) return } response.OkWithData(response.PageResult{ @@ -127,7 +127,7 @@ func (a *TopicApi) TopicDetail(c *gin.Context) { } -// DeleteTopic 删除植物 +// DeleteTopic 删除话题 // @Tags 帖子话题 // @Summary 删除任务 // @Security BearerAuth diff --git a/api/v1/plant/wiki.go b/api/v1/plant/wiki.go new file mode 100644 index 0000000..0c4b879 --- /dev/null +++ b/api/v1/plant/wiki.go @@ -0,0 +1,3 @@ +package plant + +type WikiApi struct{} diff --git a/api/v1/plant/wiki_class.go b/api/v1/plant/wiki_class.go new file mode 100644 index 0000000..0019dad --- /dev/null +++ b/api/v1/plant/wiki_class.go @@ -0,0 +1,151 @@ +package plant + +import ( + "sundynix-go/global" + "sundynix-go/model/commom/request" + "sundynix-go/model/commom/response" + plantReq "sundynix-go/model/plant/request" + + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + +type WikiClassApi struct{} + +// AddClass 发布分类 +// @Tags 百科分类 +// @Summary 添加分类 +// @Security BearerAuth +// @accept json +// @Produce application/json +// @Param data body plantReq.CreateWikiClass true "添加分类" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"发布成功"}" +// @Router /wiki-class/add [post] +func (a *WikiClassApi) AddClass(c *gin.Context) { + var req plantReq.CreateWikiClass + if err := c.ShouldBindJSON(&req); err != nil { + response.FailWithMsg("请求参数错误", c) + return + } + err := wikiClassService.AddClass(req) + if err != nil { + global.Logger.Error("添加百科分类失败", zap.Error(err)) + response.FailWithMsg("添加百科分类失败", c) + return + } + response.OkWithMsg("添加百科分类成功", c) +} + +// UpdateClass 修改分类 +// @Tags 百科分类 +// @Summary 修改分类(可直接传入ossId修改图片) +// @Security BearerAuth +// @accept json +// @Produce application/json +// @Param data body lantReq.UpdateWikiClass true "修改分类" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"发布成功"}" +// @Router /wiki-class/update [post] +func (a *WikiClassApi) UpdateClass(c *gin.Context) { + var req plantReq.UpdateWikiClass + if err := c.ShouldBindJSON(&req); err != nil { + response.FailWithMsg("请求参数错误", c) + return + } + err := wikiClassService.UpdateClass(req) + if err != nil { + global.Logger.Error("修改百科分类失败", zap.Error(err)) + response.FailWithMsg("修改百科失败", c) + return + } + response.OkWithMsg("修改百科分类成功", c) +} + +// ClassPage 百科分类列表 +// @Tags 百科分类 +// @Summary 分类分页 +// @Security BearerAuth +// @accept json +// @Produce application/json +// @Param data body request.PageInfo true "分页获取分类列表" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /wiki-class/page [post] +func (a *WikiClassApi) ClassPage(c *gin.Context) { + var req request.PageInfo + if err := c.ShouldBindQuery(&req); err != nil { + response.FailWithMsg("请求参数错误", c) + return + } + list, total, err := wikiClassService.ClassPage(req) + if err != nil { + global.Logger.Error("分页分类失败", zap.Error(err)) + response.FailWithMsg("分页分类失败", c) + return + } + response.OkWithData(response.PageResult{ + List: list, + Total: total, + Page: req.Current, + PageSize: req.PageSize, + }, c) +} + +// DeleteClass 删除分类 +// @Tags 百科分类 +// @Summary 删除分类 +// @Security BearerAuth +// @accept json +// @Produce application/json +// @Param data body request.IdsReq true "删除分类" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" +// @Router /wiki-class/delete [post] +func (a *WikiClassApi) DeleteClass(c *gin.Context) { + var req request.IdsReq + err := c.ShouldBindJSON(&req) + if err != nil { + response.FailWithMsg("请求参数错误", c) + return + } + err = wikiClassService.DeleteClass(req) + if err != nil { + global.Logger.Error("删除分类失败", zap.Error(err)) + response.FailWithMsg("删除分类失败", c) + } + response.OkWithMsg("删除分类成功", c) +} + +// ClassList 分类列表 +// @Tags 百科分类 +// @Summary 分类列表 +// @Security BearerAuth +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /wiki-class/list [get] +func (a *WikiClassApi) ClassList(c *gin.Context) { + list, err := wikiClassService.ClassList() + if err != nil { + global.Logger.Error("获取分类列表失败", zap.Error(err)) + response.FailWithMsg("获取分类列表失败", c) + return + } + response.OkWithData(response.ListResult{ + List: list, + }, c) +} + +// ClassDetail 话题详情 +// @Tags 百科分类 +// @Summary 分类详情 +// @Security BearerAuth +// @Produce application/json +// @Param id query string true "id" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /wiki-class/detail [get] +func (a *WikiClassApi) ClassDetail(c *gin.Context) { + id := c.Query("id") + topic, err := wikiClassService.Detail(id) + if err != nil { + response.FailWithMsg("获取失败", c) + return + } + response.OkWithData(topic, c) +} diff --git a/initialize/gorm.go b/initialize/gorm.go index 82ef181..76b14e0 100644 --- a/initialize/gorm.go +++ b/initialize/gorm.go @@ -47,6 +47,8 @@ func MigrateTable() { plant.Post{}, //帖子 plant.PostLike{}, //帖子点赞 plant.PostComment{}, //帖子评论 + plant.WikiClass{}, //百科分类 + plant.Wiki{}, //百科植物 ) if err != nil { diff --git a/initialize/router.go b/initialize/router.go index 2cfa1a7..4951584 100644 --- a/initialize/router.go +++ b/initialize/router.go @@ -49,9 +49,11 @@ func Routers() { { //需要鉴权的路由 - plantGroup.InitPlantRouter(NeedAuthGroup) // 植物相关 - plantGroup.InitTopicRouter(NeedAuthGroup) // 帖子话题 - plantGroup.InitPostRouter(NeedAuthGroup) // 帖子相关 + plantGroup.InitPlantRouter(NeedAuthGroup) // 植物相关 + plantGroup.InitTopicRouter(NeedAuthGroup) // 帖子话题 + plantGroup.InitPostRouter(NeedAuthGroup) // 帖子相关 + plantGroup.InitWikiClassRouter(NeedAuthGroup) //百科分类 + plantGroup.InitWikiRouter(NeedAuthGroup) //百科 } diff --git a/model/plant/request/wiki_class.go b/model/plant/request/wiki_class.go new file mode 100644 index 0000000..3391310 --- /dev/null +++ b/model/plant/request/wiki_class.go @@ -0,0 +1,14 @@ +package request + +// CreateWikiClass 创建分类 +type CreateWikiClass struct { + Name string `json:"name" binding:"required"` // 分类名称 + OssId string `json:"ossId"` // 图片id +} + +// UpdateWikiClass 修改分类 +type UpdateWikiClass struct { + Id string `json:"id" binding:"required"` + Name string `json:"name"` // 分类名称 + OssId string `json:"ossId"` // 图片id +} diff --git a/model/plant/wiki.go b/model/plant/wiki.go new file mode 100644 index 0000000..d62f497 --- /dev/null +++ b/model/plant/wiki.go @@ -0,0 +1,50 @@ +package plant + +import ( + "sundynix-go/global" + "sundynix-go/model/system" +) + +type Wiki struct { + global.BaseModel + IsHot int `json:"isHot" form:"isHot" gorm:"column:is_hot;comment:是否推荐植物"` + //基本信息 + Name string `json:"name" form:"name" gorm:"column:name;size:50;comment:名称"` + LatinName string `json:"latinName" form:"latinName" gorm:"size:100;column:latin_name;comment:拉丁名"` + Aliases string `json:"aliases" form:"aliases" gorm:"size:100;column:aliases;comment:别名(逗号分隔)"` + DistributionArea string `json:"distributionArea" form:"distributionArea" gorm:"size:100;column:distribution_area;comment:分布区域"` //分布区域 + //科学分类 + Genus string `json:"genus" form:"genus" gorm:"size:20;column:genus;comment:科属"` // 属 + Difficulty int `json:"difficulty" form:"difficulty" gorm:"column:difficulty;comment:种植难度"` //种植难度 1-5级 + //形态特征 + LifeCycle string `json:"lifeCycle" form:"lifeCycle" gorm:"size:20;column:life_cycle;comment:生命周期"` // 生命周期 一年生 二年生 多年生等 + GrowthHabit string `json:"growthHabit" form:"growthHabit" gorm:"size:200;column:growth_habit;comment:成长习性"` // 生长习性 + ReproductionMethod string `json:"reproductionMethod" form:"reproductionMethod" gorm:"size:200;column:reproduction_method;comment:繁殖方法"` //繁殖方法 + PestsDiseases string `json:"pestsDiseases" form:"pestsDiseases" gorm:"size:200;column:pests_diseases;comment:病虫害"` + //光照 + LightIntensity string `json:"lightIntensity" form:"lightIntensity" gorm:"size:50;column:light_intensity;comment:光照强度"` // 光照强度 弱光 强光 + LightType string `json:"lightType" form:"lightType" gorm:"size:50;column:light_type;comment:光照类型"` // 光照类型 直射光 散射光 半阴 全阴等 + //温度 + OptimalTempPeriod string `json:"optimalTempPeriod" form:"optimalTempPeriod" gorm:"column:optimal_temp_period;size:30;comment:最佳温度"` + //茎 + Stem string `json:"stem" form:"stem" gorm:"size:200;column:stem;comment:茎"` + //叶 + FoliageType string `json:"foliageType" form:"foliageType" gorm:"size:200;column:foliage_type;comment:叶型"` + FoliageColor string `json:"foliageColor" form:"foliageColor" gorm:"size:200;column:foliage_color;comment:叶色"` + FoliageShape string `json:"foliageShape" form:"foliageShape" gorm:"size:200;column:foliage_shape;comment:叶形"` + Height int `json:"height" form:"height" gorm:"size:10;column:height;comment:植株高度"` + //花 + FloweringPeriod string `json:"floweringPeriod" form:"floweringPeriod" gorm:"size:100;column:flowering_period;comment:开花期"` + FloweringColor string `json:"floweringColor" form:"floweringColor" gorm:"size:100;column:flowering_color;comment:开花颜色"` + FloweringShape string `json:"floweringShape" form:"floweringShape" gorm:"size:100;column:flowering_shape;comment:开花形状"` + FlowerDiameter int `json:"flowerDiameter" form:"flowerDiameter" gorm:"size:10;column:flower_diameter;comment:花直径"` + //果 + Fruit string `json:"fruit" form:"fruit" gorm:"size:200;column:fruit;comment:果实"` + + //相关推荐 + RelatedWiki []*Wiki `gorm:"many2many:wiki_related;" json:"relatedWiki"` + //图片 多对多 + ImgList []*system.Oss `gorm:"many2many:wiki_oss;" json:"imgList"` + // 分类 + Classes []*WikiClass `gorm:"many2many:wiki_class;" json:"classes"` +} diff --git a/model/plant/wiki_class.go b/model/plant/wiki_class.go new file mode 100644 index 0000000..4b2e495 --- /dev/null +++ b/model/plant/wiki_class.go @@ -0,0 +1,13 @@ +package plant + +import ( + "sundynix-go/global" + "sundynix-go/model/system" +) + +type WikiClass struct { + global.BaseModel + Name string `json:"name" form:"name" gorm:"column:name;comment:名称"` + OssId string `json:"ossId" form:"ossId" gorm:"column:oss_id;comment:图片id"` + Oss *system.Oss `gorm:"foreignKey:OssId" json:"oss"` +} diff --git a/router/plant/enter.go b/router/plant/enter.go index 5caefdd..d878ea4 100644 --- a/router/plant/enter.go +++ b/router/plant/enter.go @@ -6,11 +6,15 @@ type RouterGroup struct { MyPlantRouter TopicRouter PostRouter + WikiClassRouter + WikiRouter } // 初始化路由 var ( - myPlantApi = v1.ApiGroupApp.PlantApiGroup.MyPlantApi - topicApi = v1.ApiGroupApp.PlantApiGroup.TopicApi - postApi = v1.ApiGroupApp.PlantApiGroup.PostApi + myPlantApi = v1.ApiGroupApp.PlantApiGroup.MyPlantApi + topicApi = v1.ApiGroupApp.PlantApiGroup.TopicApi + postApi = v1.ApiGroupApp.PlantApiGroup.PostApi + wikiClassApi = v1.ApiGroupApp.PlantApiGroup.WikiClassApi + wikiApi = v1.ApiGroupApp.PlantApiGroup.WikiApi ) diff --git a/router/plant/wiki_class_router.go b/router/plant/wiki_class_router.go new file mode 100644 index 0000000..d958d0f --- /dev/null +++ b/router/plant/wiki_class_router.go @@ -0,0 +1,17 @@ +package plant + +import "github.com/gin-gonic/gin" + +type WikiClassRouter struct{} + +func (p *WikiClassRouter) InitWikiClassRouter(Router *gin.RouterGroup) { + wikiClassRouter := Router.Group("wiki-class") + { + wikiClassRouter.POST("/add", wikiClassApi.AddClass) + wikiClassRouter.POST("/update", wikiClassApi.UpdateClass) + wikiClassRouter.POST("/page", wikiClassApi.ClassPage) + wikiClassRouter.POST("/delete", wikiClassApi.DeleteClass) + wikiClassRouter.GET("/list", wikiClassApi.ClassList) + wikiClassRouter.GET("/detail", wikiClassApi.ClassDetail) + } +} diff --git a/router/plant/wiki_router.go b/router/plant/wiki_router.go new file mode 100644 index 0000000..466f3be --- /dev/null +++ b/router/plant/wiki_router.go @@ -0,0 +1,13 @@ +package plant + +import "github.com/gin-gonic/gin" + +type WikiRouter struct{} + +func (p *WikiRouter) InitWikiRouter(Router *gin.RouterGroup) { + wikiRouter := Router.Group("wiki") + { + wikiRouter.POST("/add", topicApi.AddTopic) + + } +} diff --git a/service/plant/enter.go b/service/plant/enter.go index b5f2768..b2e363d 100644 --- a/service/plant/enter.go +++ b/service/plant/enter.go @@ -4,4 +4,6 @@ type ServiceGroup struct { MyPlantService TopicService PostService + WikiClassService + WikiService } diff --git a/service/plant/topic.go b/service/plant/topic.go index 31d3700..2029e17 100644 --- a/service/plant/topic.go +++ b/service/plant/topic.go @@ -52,6 +52,9 @@ func (s *TopicService) TopicPage(req common.PageInfo) (list interface{}, total i db := global.DB.Model(&plant.Topic{}) var topics []*plant.Topic err = db.Count(&total).Error + if err != nil { + return + } err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&topics).Error return topics, total, err } diff --git a/service/plant/wiki.go b/service/plant/wiki.go new file mode 100644 index 0000000..5a9111a --- /dev/null +++ b/service/plant/wiki.go @@ -0,0 +1,5 @@ +package plant + +type WikiService struct{} + +var WikiServiceApp = new(WikiClassService) diff --git a/service/plant/wiki_class.go b/service/plant/wiki_class.go new file mode 100644 index 0000000..bd942b8 --- /dev/null +++ b/service/plant/wiki_class.go @@ -0,0 +1,84 @@ +package plant + +import ( + "errors" + "sundynix-go/global" + common "sundynix-go/model/commom/request" + "sundynix-go/model/plant" + plantReq "sundynix-go/model/plant/request" + "sundynix-go/model/system" + + "gorm.io/gorm" +) + +type WikiClassService struct{} + +var WikiClassServiceApp = new(WikiClassService) + +// AddClass 添加分类 +func (s *WikiClassService) AddClass(req plantReq.CreateWikiClass) error { + //1.查询name是否存在 2.查询oss是否存在 + if !errors.Is(global.DB.Where("name = ?", req.Name).First(&plant.WikiClass{}).Error, gorm.ErrRecordNotFound) { + return errors.New("存在重复分类名称,请修改名称") + } + if errors.Is(global.DB.Where("id = ?", req.OssId).First(&system.Oss{}).Error, gorm.ErrRecordNotFound) { + return errors.New("不存在此图片") + } + return global.DB.Create(&plant.WikiClass{ + Name: req.Name, + OssId: req.OssId, + }).Error +} + +// UpdateClass 修改分类 +func (s *WikiClassService) UpdateClass(req plantReq.UpdateWikiClass) error { + updateMap := map[string]interface{}{ + "name": req.Name, + "oss": req.OssId, + } + return global.DB.Model(&plant.WikiClass{}).Where("id = ?", req.Id).Updates(updateMap).Error +} + +func (s *WikiClassService) ClassPage(req common.PageInfo) (list interface{}, total int64, err error) { + limit := req.PageSize + offset := req.PageSize * (req.Current - 1) + db := global.DB.Model(&plant.WikiClass{}).Preload("Oss") + var classes []*plant.WikiClass + err = db.Count(&total).Error + if err != nil { + return + } + err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&classes).Error + return classes, total, err +} + +// DeleteClass 删除分类 +func (s *WikiClassService) DeleteClass(req common.IdsReq) error { + var classes []plant.WikiClass + if err := global.DB.Where("id in ?", req.Ids).Find(&classes).Error; err != nil { + return err + } + // todo 删除关联? + return global.DB.Unscoped().Delete(&classes).Error +} + +// ClassList 列表 +func (s *WikiClassService) ClassList() (list interface{}, err error) { + var classes []plant.WikiClass + err = global.DB.Order("created_at desc").Find(&classes).Error + if err != nil { + return + } + return classes, err +} + +// Detail 详情 +func (s *WikiClassService) Detail(id string) (c plant.WikiClass, err error) { + var class plant.WikiClass + err = global.DB.Where("id = ?", id).Preload("Oss").First(&class).Error + //不存在的时候不要返回错误,而是返回nil + if err != nil { + return class, err + } + return class, nil +}