From e612234c91d74e9344b93a99ea1dad4618319e8a Mon Sep 17 00:00:00 2001 From: Blizzard Date: Sat, 7 Feb 2026 18:01:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=99=BE=E7=A7=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v1/plant/wiki.go | 105 ++++++++++++++++++++ initialize/gorm.go | 2 +- model/plant/request/wiki.go | 73 ++++++++++++++ model/plant/wiki.go | 2 +- model/plant/wiki_class.go | 2 +- router/plant/wiki_router.go | 5 +- service/plant/wiki.go | 192 ++++++++++++++++++++++++++++++++++++ service/plant/wiki_class.go | 20 ++-- 8 files changed, 387 insertions(+), 14 deletions(-) create mode 100644 model/plant/request/wiki.go diff --git a/api/v1/plant/wiki.go b/api/v1/plant/wiki.go index 0c4b879..370525b 100644 --- a/api/v1/plant/wiki.go +++ b/api/v1/plant/wiki.go @@ -1,3 +1,108 @@ package plant +import ( + "sundynix-go/global" + "sundynix-go/model/commom/response" + plantReq "sundynix-go/model/plant/request" + + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) + type WikiApi struct{} + +// CreateWiki 发布百科 +// @Tags 百科 +// @Summary 添加百科 +// @Security BearerAuth +// @accept application/json +// @Produce application/json +// @Param data body plantReq.CreateWiki true "添加百科" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"发布成功"}" +// @Router /wiki/add [post] +func (a *WikiApi) CreateWiki(c *gin.Context) { + var req plantReq.CreateWiki + if err := c.ShouldBind(&req); err != nil { + response.FailWithMsg("请求参数错误", c) + return + } + err := wikiService.CreateWiki(req) + if err != nil { + global.Logger.Error("添加百科失败", zap.Error(err)) + response.FailWithMsg("添加百科失败", c) + return + } + response.OkWithMsg("添加百科成功", c) +} + +// UpdateWiki 发布百科 +// @Tags 百科 +// @Summary 修改百科 +// @Security BearerAuth +// @accept application/json +// @Produce application/json +// @Param data body plantReq.UpdateWiki true "修改百科" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"发布成功"}" +// @Router /wiki/update [post] +func (a *WikiApi) UpdateWiki(c *gin.Context) { + var req plantReq.UpdateWiki + if err := c.ShouldBind(&req); err != nil { + response.FailWithMsg("请求参数错误", c) + return + } + err := wikiService.UpdateWiki(req) + if err != nil { + global.Logger.Error("修改百科失败", zap.Error(err)) + response.FailWithMsg("修改百科失败", c) + return + } + response.OkWithMsg("修改百科成功", c) + +} + +// WikiPage 百科分页 +// @Tags 百科 +// @Summary 分页 +// @Security BearerAuth +// @accept application/json +// @Produce application/json +// @Param data body plantReq.WikiPage true "百科分页" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"发布成功"}" +// @Router /wiki/page [post] +func (a *WikiApi) WikiPage(c *gin.Context) { + var req plantReq.WikiPage + if err := c.ShouldBind(&req); err != nil { + response.FailWithMsg("请求参数错误", c) + return + } + list, total, err := wikiService.WikiPage(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) +} + +// WikiDetail 百科详情 +// @Tags 百科 +// @Summary 百科详情 +// @Security BearerAuth +// @Produce application/json +// @Param id query string true "id" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /wiki/detail [get] +func (a *WikiApi) WikiDetail(c *gin.Context) { + id := c.Query("id") + topic, err := wikiService.Detail(id) + if err != nil { + response.FailWithMsg("获取失败", c) + return + } + response.OkWithData(topic, c) +} diff --git a/initialize/gorm.go b/initialize/gorm.go index 76b14e0..0be1d39 100644 --- a/initialize/gorm.go +++ b/initialize/gorm.go @@ -47,7 +47,7 @@ func MigrateTable() { plant.Post{}, //帖子 plant.PostLike{}, //帖子点赞 plant.PostComment{}, //帖子评论 - plant.WikiClass{}, //百科分类 + plant.Class{}, //百科分类 plant.Wiki{}, //百科植物 ) diff --git a/model/plant/request/wiki.go b/model/plant/request/wiki.go new file mode 100644 index 0000000..7042d0e --- /dev/null +++ b/model/plant/request/wiki.go @@ -0,0 +1,73 @@ +package request + +import common "sundynix-go/model/commom/request" + +// CreateWiki 创建百科植物库 +type CreateWiki struct { + IsHot int `json:"isHot"` // 是否热门 + Name string `json:"name" binding:"required"` // 名称 + LatinName string `json:"latinName"` // 拉丁名 + Aliases string `json:"aliases"` // 别名 + DistributionArea string `json:"distributionArea"` // 分布区域 + Genus string `json:"genus"` // 属 + Difficulty int `json:"difficulty"` // 种植难度 1-5级 + LifeCycle string `json:"lifeCycle"` // 生命周期 + GrowthHabit string `json:"growthHabit"` // 生长习性 + ReproductionMethod string `json:"reproductionMethod"` // 繁殖方法 + PestsDiseases string `json:"pestsDiseases"` // 常见病虫害 + LightIntensity string `json:"lightIntensity"` // 光照强度 + LightType string `json:"lightType"` // 光照类型(直射,散射等) + OptimalTempPeriod string `json:"optimalTempPeriod"` //最佳温度区间 + Stem string `json:"stem"` //茎 + Fruit string `json:"fruit"` //果 + FoliageType string `json:"foliageType"` // 叶型 + FoliageColor string `json:"foliageColor"` // 叶色 + FoliageShape string `json:"foliageShape"` // 叶形 + Height int `json:"height"` // 高度(cm) + FloweringPeriod string `json:"floweringPeriod"` // 开花期 + FloweringColor string `json:"floweringColor"` // 花色 + FloweringShape string `json:"floweringShape"` // 花形 + FlowerDiameter int `json:"flowerDiameter"` // 花直径(cm) + RelatedWikiIds []string `json:"relatedWikiIds"` //相关推荐 + OssIds []string `json:"ossIds"` // 图片 + ClassIds []string `json:"classIds"` //分类id +} + +type UpdateWiki struct { + Id string `json:"id" binding:"required"` + Name string `json:"name"` // 名称 + LatinName string `json:"latinName"` // 拉丁名 + Aliases string `json:"aliases"` // 别名 + DistributionArea string `json:"distributionArea"` // 分布区域 + Genus string `json:"genus"` // 属 + Difficulty int `json:"difficulty"` // 种植难度 1-5级 + LifeCycle string `json:"lifeCycle"` // 生命周期 + GrowthHabit string `json:"growthHabit"` // 生长习性 + PestsDiseases string `json:"pestsDiseases"` // 常见病虫害 + LightIntensity string `json:"lightIntensity"` // 光照强度 + LightType string `json:"lightType"` // 光照类型(直射,散射等) + OptimalTempPeriod string `json:"optimalTempPeriod"` //最佳温度区间 + Stem string `json:"stem"` //茎 + Fruit string `json:"fruit"` //果 + FoliageType string `json:"foliageType"` // 叶型 + FoliageColor string `json:"foliageColor"` // 叶色 + FoliageShape string `json:"foliageShape"` // 叶形 + Height int `json:"height"` // 高度(cm) + FloweringPeriod string `json:"floweringPeriod"` // 开花期 + FloweringColor string `json:"floweringColor"` // 花色 + FloweringShape string `json:"floweringShape"` // 花形 + FlowerDiameter int `json:"flowerDiameter"` // 花直径(cm) +} + +// WikiPage 列表 +type WikiPage struct { + common.PageInfo + Name string `json:"name"` // 植物名称 + IsHot *int `json:"isHot"` // 是否热门 0否 1是 + ClassIdIs []string `json:"classId"` // 分类id +} + +type AlterHot struct { + common.IdsReq + IsHot int `json:"isHot"` // 是否热门 1是 2否 +} diff --git a/model/plant/wiki.go b/model/plant/wiki.go index d62f497..69ce3dd 100644 --- a/model/plant/wiki.go +++ b/model/plant/wiki.go @@ -46,5 +46,5 @@ type Wiki struct { //图片 多对多 ImgList []*system.Oss `gorm:"many2many:wiki_oss;" json:"imgList"` // 分类 - Classes []*WikiClass `gorm:"many2many:wiki_class;" json:"classes"` + Classes []*Class `gorm:"many2many:wiki_class;" json:"classes"` } diff --git a/model/plant/wiki_class.go b/model/plant/wiki_class.go index 4b2e495..9a9e939 100644 --- a/model/plant/wiki_class.go +++ b/model/plant/wiki_class.go @@ -5,7 +5,7 @@ import ( "sundynix-go/model/system" ) -type WikiClass struct { +type Class 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"` diff --git a/router/plant/wiki_router.go b/router/plant/wiki_router.go index 466f3be..66f87fb 100644 --- a/router/plant/wiki_router.go +++ b/router/plant/wiki_router.go @@ -7,7 +7,10 @@ type WikiRouter struct{} func (p *WikiRouter) InitWikiRouter(Router *gin.RouterGroup) { wikiRouter := Router.Group("wiki") { - wikiRouter.POST("/add", topicApi.AddTopic) + wikiRouter.POST("/add", wikiApi.CreateWiki) + wikiRouter.POST("/update", wikiApi.UpdateWiki) + wikiRouter.POST("/page", wikiApi.WikiPage) + wikiRouter.GET("/detail", wikiApi.WikiDetail) } } diff --git a/service/plant/wiki.go b/service/plant/wiki.go index 5a9111a..18738b0 100644 --- a/service/plant/wiki.go +++ b/service/plant/wiki.go @@ -1,5 +1,197 @@ package plant +import ( + "errors" + "sundynix-go/global" + "sundynix-go/model/plant" + plantReq "sundynix-go/model/plant/request" + "sundynix-go/model/system" + + "gorm.io/gorm" +) + type WikiService struct{} var WikiServiceApp = new(WikiClassService) + +// CreateWiki 创建百科 +func (s *WikiService) CreateWiki(req plantReq.CreateWiki) error { + return global.DB.Transaction(func(tx *gorm.DB) error { + //1.先模糊查询name是否存在 如果存在 则返回错误 + if !errors.Is(tx.Where("name like ?", "%"+req.Name+"%").First(&plant.Wiki{}).Error, gorm.ErrRecordNotFound) { + return errors.New("植物已经存在") + } + + //2.图片 + var ossList []*system.Oss + err := tx.Where("id in ?", req.OssIds).Find(&ossList).Error + if err != nil { + return err + } + //3. 分类 + var classes []*plant.Class + err = tx.Where("id in ?", req.ClassIds).Find(&classes).Error + if err != nil { + return err + } + //4. 相关的植物 + var relatedWiki []*plant.Wiki + err = tx.Where("id in ?", req.RelatedWikiIds).Find(&relatedWiki).Error + if err != nil { + return err + } + //6.保存数据 + wiki := plant.Wiki{ + IsHot: req.IsHot, + Name: req.Name, + LatinName: req.LatinName, + Aliases: req.Aliases, + Difficulty: req.Difficulty, + DistributionArea: req.DistributionArea, + Stem: req.Stem, + Fruit: req.Fruit, + Genus: req.Genus, + LifeCycle: req.LifeCycle, + GrowthHabit: req.GrowthHabit, + ReproductionMethod: req.ReproductionMethod, + PestsDiseases: req.PestsDiseases, + LightIntensity: req.LightIntensity, + LightType: req.LightType, + OptimalTempPeriod: req.OptimalTempPeriod, + FoliageType: req.FoliageType, + FoliageColor: req.FoliageColor, + FoliageShape: req.FoliageShape, + Height: req.Height, + FloweringPeriod: req.FloweringPeriod, + FloweringColor: req.FloweringColor, + FloweringShape: req.FloweringShape, + FlowerDiameter: req.FlowerDiameter, + } + err = tx.Create(&wiki).Error + if err != nil { + return err + } + //7.处理图片关系 + if len(ossList) > 0 { + var relations []map[string]interface{} + for _, oss := range ossList { + relations = append(relations, map[string]interface{}{ + "wiki_id": wiki.Id, + "oss_id": oss.Id, + }) + } + err = tx.Table("sundynix_wiki_oss").Create(relations).Error + if err != nil { + return err + } + } + //8.处理分类关系 + if len(classes) > 0 { + var classRelations []map[string]interface{} + for _, class := range classes { + classRelations = append(classRelations, map[string]interface{}{ + "wiki_id": wiki.Id, + "class_id": class.Id, + }) + } + err = tx.Table("sundynix_wiki_class").Create(classRelations).Error + if err != nil { + return err + } + } + //9.处理相关植物关系 + if len(relatedWiki) > 0 { + var relatedWikiRelations []map[string]interface{} + for _, item := range relatedWiki { + relatedWikiRelations = append(relatedWikiRelations, map[string]interface{}{ + "wiki_id": wiki.Id, + "related_wiki_id": item.Id, + }) + } + err = tx.Table("sundynix_wiki_related").Create(relatedWikiRelations).Error + if err != nil { + return err + } + } + + return nil + }) +} + +// UpdateWiki 修改百科 +func (s *WikiService) UpdateWiki(req plantReq.UpdateWiki) error { + updateData := map[string]interface{}{ + "name": req.Name, + "latin_name": req.LatinName, + "aliases": req.Aliases, + "difficulty": req.Difficulty, + "genus": req.Genus, + "distribution_area": req.DistributionArea, + "life_cycle": req.LifeCycle, + "growth_habit": req.GrowthHabit, + "pests_diseases": req.PestsDiseases, + "light_intensity": req.LightIntensity, + "light_type": req.LightType, + "optimal_temp_period": req.OptimalTempPeriod, + "stem": req.Stem, + "fruit": req.Fruit, + "foliage_type": req.FoliageType, + "foliage_color": req.FoliageColor, + "foliage_shape": req.FoliageShape, + "height": req.Height, + "flowering_period": req.FloweringPeriod, + "flowering_color": req.FloweringColor, + "flowering_shape": req.FloweringShape, + "flower_diameter": req.FlowerDiameter, + } + err := global.DB.Model(&plant.Wiki{}).Where("id = ?", req.Id).Updates(updateData).Error + return err +} + +// WikiPage 分页 +func (s *WikiService) WikiPage(req plantReq.WikiPage) (list interface{}, total int64, err error) { + limit := req.PageSize + offset := req.PageSize * (req.Current - 1) + db := global.DB.Model(&plant.Wiki{}).Preload("ImgList", func(db *gorm.DB) *gorm.DB { + return db.Order("created_at desc").Limit(1) + }).Preload("Classes", func(db *gorm.DB) *gorm.DB { + return db.Order("created_at desc") + }) + var wikis []plant.Wiki + if req.Name != "" { + db = db.Where("name like ?", "%"+req.Name+"%") + } + if req.IsHot != nil { + db = db.Where("is_hot = ?", *req.IsHot) + } + if len(req.ClassIdIs) > 0 { + db = db.Joins("inner join sundynix_wiki_class on sundynix_wiki_class.class.id = sundynix_wiki.id"). + Where("sundynix_wiki_class.class_id IN (?)", req.ClassIdIs) + } + err = db.Count(&total).Error + if err != nil { + return + } + err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&wikis).Error + return wikis, total, err +} + +// Detail 详情 +func (s *WikiService) Detail(id string) (w plant.Wiki, err error) { + var wiki plant.Wiki + err = global.DB.Where("id = ?", id). + Preload("Classes", func(db *gorm.DB) *gorm.DB { + return db.Order("created_at desc") + }). + Preload("ImgList", func(db *gorm.DB) *gorm.DB { + return db.Order("created_at desc") + }). + Preload("RelatedWiki", func(db *gorm.DB) *gorm.DB { + return db.Order("created_at desc") + }). + First(&wiki).Error + if err != nil { + return + } + return wiki, nil +} diff --git a/service/plant/wiki_class.go b/service/plant/wiki_class.go index bd942b8..1389f94 100644 --- a/service/plant/wiki_class.go +++ b/service/plant/wiki_class.go @@ -18,13 +18,13 @@ 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) { + if !errors.Is(global.DB.Where("name = ?", req.Name).First(&plant.Class{}).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{ + return global.DB.Create(&plant.Class{ Name: req.Name, OssId: req.OssId, }).Error @@ -36,14 +36,14 @@ func (s *WikiClassService) UpdateClass(req plantReq.UpdateWikiClass) error { "name": req.Name, "oss": req.OssId, } - return global.DB.Model(&plant.WikiClass{}).Where("id = ?", req.Id).Updates(updateMap).Error + return global.DB.Model(&plant.Class{}).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 + db := global.DB.Model(&plant.Class{}).Preload("Oss") + var classes []*plant.Class err = db.Count(&total).Error if err != nil { return @@ -54,7 +54,7 @@ func (s *WikiClassService) ClassPage(req common.PageInfo) (list interface{}, tot // DeleteClass 删除分类 func (s *WikiClassService) DeleteClass(req common.IdsReq) error { - var classes []plant.WikiClass + var classes []plant.Class if err := global.DB.Where("id in ?", req.Ids).Find(&classes).Error; err != nil { return err } @@ -64,7 +64,7 @@ func (s *WikiClassService) DeleteClass(req common.IdsReq) error { // ClassList 列表 func (s *WikiClassService) ClassList() (list interface{}, err error) { - var classes []plant.WikiClass + var classes []plant.Class err = global.DB.Order("created_at desc").Find(&classes).Error if err != nil { return @@ -73,12 +73,12 @@ func (s *WikiClassService) ClassList() (list interface{}, err error) { } // Detail 详情 -func (s *WikiClassService) Detail(id string) (c plant.WikiClass, err error) { - var class plant.WikiClass +func (s *WikiClassService) Detail(id string) (c plant.Class, err error) { + var class plant.Class err = global.DB.Where("id = ?", id).Preload("Oss").First(&class).Error //不存在的时候不要返回错误,而是返回nil if err != nil { - return class, err + return } return class, nil }