315 lines
8.9 KiB
Go
315 lines
8.9 KiB
Go
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 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, userId string) (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")
|
|
}).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.wiki_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
|
|
|
|
// 优化 N+1 查询
|
|
var wikiIds []string
|
|
for _, v := range wikis {
|
|
wikiIds = append(wikiIds, v.Id)
|
|
}
|
|
//批量查询当前用户的收藏
|
|
var stars []*plant.UserStar
|
|
err = global.DB.Where("user_id = ? and wiki_id in ?", userId, wikiIds).Find(&stars).Error
|
|
if err != nil {
|
|
return
|
|
}
|
|
starsMap := make(map[string]bool)
|
|
for _, v := range stars {
|
|
starsMap[v.WikiId] = true
|
|
}
|
|
// 是否收藏
|
|
for i := range wikis {
|
|
if starsMap[wikis[i].Id] {
|
|
wikis[i].HasStar = 1
|
|
} else {
|
|
wikis[i].HasStar = 0
|
|
}
|
|
}
|
|
return wikis, total, err
|
|
}
|
|
|
|
// Detail 详情
|
|
func (s *WikiService) Detail(id, userId 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
|
|
}
|
|
var stars []plant.UserStar
|
|
err = global.DB.Where("user_id = ? and wiki_id = ?", userId, id).Find(&stars).Error
|
|
if err != nil {
|
|
return
|
|
}
|
|
if len(stars) > 0 {
|
|
wiki.HasStar = 1
|
|
}
|
|
return wiki, nil
|
|
}
|
|
|
|
// StarWiki 收藏
|
|
func (s *WikiService) StarWiki(userId, wikiId, class string) error {
|
|
if class == "1" {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var wiki plant.Wiki
|
|
err := tx.Where("id = ?", wikiId).First(&wiki).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//2.添加到我的收藏
|
|
star := plant.UserStar{
|
|
UserId: userId,
|
|
Type: 1,
|
|
WikiId: wikiId,
|
|
}
|
|
return tx.Create(&star).Error
|
|
})
|
|
} else if class == "2" {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var star plant.UserStar
|
|
err := tx.Where("wiki_id = ? and user_id = ?", wikiId, userId).First(&star).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//2.删除收藏
|
|
return tx.Unscoped().Delete(&star).Error
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// UploadImg 上传图片
|
|
func (s *WikiService) UploadImg(req common.UploadOss) error {
|
|
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var wiki plant.Wiki
|
|
err := tx.Where("id = ?", req.Id).First(&wiki).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var ossList []system.Oss
|
|
err = tx.Where("id in ?", req.OssIds).Find(&ossList).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var relations []map[string]interface{}
|
|
for _, oss := range ossList {
|
|
relations = append(relations, map[string]interface{}{
|
|
"wiki_id": wiki.Id,
|
|
"oss_id": oss.Id,
|
|
})
|
|
}
|
|
//3.添加关联关系(添加引用)
|
|
return global.DB.Table("sundynix_wiki_oss").Create(relations).Error
|
|
})
|
|
}
|
|
|
|
// DeleteWiki 删除百科
|
|
func (s *WikiService) DeleteWiki(req common.IdsReq) error {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var imgIds []string
|
|
tx.Table("sundynix_wiki_oss").Where("wiki_id IN ?", req.Ids).Pluck("oss_id", &imgIds)
|
|
// 3. 物理删除图片记录本身
|
|
if len(imgIds) > 0 {
|
|
if err := tx.Unscoped().Where("id IN ?", imgIds).Delete(&system.Oss{}).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
// 2. 清理中间表记录 (解开多对多关系)
|
|
// 使用 Exec 直接操作中间表比循环 Clear 快得多
|
|
if err := tx.Exec("DELETE FROM sundynix_wiki_oss WHERE wiki_id IN ?", req.Ids).Error; err != nil {
|
|
return err
|
|
}
|
|
if err := tx.Exec("DELETE FROM sundynix_wiki_class WHERE wiki_id IN ?", req.Ids).Error; err != nil {
|
|
return err
|
|
}
|
|
if err := tx.Exec("DELETE FROM sundynix_wiki_related WHERE wiki_id IN ? or related_wiki_id in ?", req.Ids, req.Ids).Error; err != nil {
|
|
return err
|
|
}
|
|
//删除百科本身
|
|
return tx.Unscoped().Where("id IN ?", req.Ids).Delete(&plant.Wiki{}).Error
|
|
})
|
|
}
|