424 lines
11 KiB
Go
424 lines
11 KiB
Go
package plant
|
|
|
|
import (
|
|
"sundynix-go/global"
|
|
common "sundynix-go/model/commom/request"
|
|
"sundynix-go/model/plant"
|
|
plantReq "sundynix-go/model/plant/request"
|
|
plantRes "sundynix-go/model/plant/response"
|
|
"sundynix-go/model/system"
|
|
"sundynix-go/utils/timer"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type MyPlantService struct{}
|
|
|
|
var MyPlantServiceApp = new(MyPlantService)
|
|
|
|
// AddPlant 添加植物
|
|
func (s *MyPlantService) AddPlant(req plantReq.CreateMyPlant, id string) error {
|
|
err := global.DB.Transaction(func(tx *gorm.DB) error {
|
|
//1. 验证oss是否存在
|
|
var ossList []*system.Oss
|
|
err := tx.Where("id in ?", req.OssIds).Find(&ossList).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
bgTime := timer.GetZeroTime()
|
|
//2. 处理养护计划
|
|
var carePlans []*plant.CarePlan
|
|
for _, v := range req.CarePlans {
|
|
carePlans = append(carePlans, &plant.CarePlan{
|
|
UserId: id,
|
|
Name: v.Name,
|
|
Icon: v.Icon,
|
|
Period: v.Period,
|
|
})
|
|
}
|
|
//3.保存数据
|
|
myPlant := plant.MyPlant{
|
|
UserId: id,
|
|
Name: req.Name,
|
|
PlantTime: bgTime,
|
|
Status: 1,
|
|
Placement: req.Placement,
|
|
PotMaterial: req.PotMaterial,
|
|
PotSize: req.PotSize,
|
|
Sunlight: req.Sunlight,
|
|
PlantingMaterial: req.PlantingMaterial,
|
|
CarePlans: carePlans,
|
|
}
|
|
err = tx.Create(&myPlant).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
//4.处理图片关系
|
|
if len(ossList) > 0 {
|
|
var relations []map[string]interface{}
|
|
for _, oss := range ossList {
|
|
relations = append(relations, map[string]interface{}{
|
|
"my_plant_id": myPlant.Id,
|
|
"oss_id": oss.Id,
|
|
})
|
|
}
|
|
err = tx.Table("sundynix_my_plant_oss").Create(relations).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
return err
|
|
|
|
}
|
|
|
|
// PlantPage 植物列表
|
|
func (s *MyPlantService) PlantPage(req common.PageInfo, userId string) (list interface{}, total int64, err error) {
|
|
limit := req.PageSize
|
|
offset := req.PageSize * (req.Current - 1)
|
|
db := global.DB.Model(&plant.MyPlant{}).Preload("ImgList", func(db *gorm.DB) *gorm.DB {
|
|
return db.Order("created_at desc")
|
|
})
|
|
var myPlants []*plant.MyPlant
|
|
db = db.Where("user_id = ?", userId)
|
|
err = db.Count(&total).Error
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&myPlants).Error
|
|
return myPlants, total, err
|
|
}
|
|
|
|
// PlantDetail 植物详情
|
|
func (s *MyPlantService) PlantDetail(id string) (p plant.MyPlant, err error) {
|
|
var res plant.MyPlant
|
|
err = global.DB.Where("id = ?", id).
|
|
Preload("ImgList", func(db *gorm.DB) *gorm.DB {
|
|
return db.Order("created_at desc")
|
|
}).
|
|
Preload("CarePlans").
|
|
Preload("CareRecords").
|
|
Preload("GrowthRecords", func(db *gorm.DB) *gorm.DB {
|
|
return db.Preload("ImgList", func(db *gorm.DB) *gorm.DB {
|
|
return db.Order("created_at desc")
|
|
})
|
|
}).
|
|
First(&res).Error
|
|
|
|
//不存在的时候不要返回错误,而是返回nil
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
func (s *MyPlantService) UpdatePlant(req plantReq.UpdateMyPlant) error {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var myPlant plant.MyPlant
|
|
err := tx.Where("id = ?", req.Id).First(&myPlant).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// 以map形式更新 先构建map
|
|
updateMap := map[string]interface{}{
|
|
"name": req.Name,
|
|
"placement": req.Placement,
|
|
"planting_material": req.PlantingMaterial,
|
|
"pot_material": req.PotMaterial,
|
|
"pot_size": req.PotSize,
|
|
"sunlight": req.Sunlight,
|
|
}
|
|
//1.修改基本信息
|
|
err = tx.Model(&plant.MyPlant{}).Where("id = ?", req.Id).Updates(updateMap).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//2.修改计划
|
|
if len(req.CarePlans) > 0 {
|
|
today := timer.GetZeroTime()
|
|
for _, plan := range req.CarePlans {
|
|
err = tx.Model(&plant.CarePlan{}).Where("id = ?", plan.Id).Updates(map[string]interface{}{
|
|
"icon": plan.Icon,
|
|
"name": plan.Name,
|
|
"period": plan.Period,
|
|
}).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//3.重新生成任务 CarePlans 结构体中使用钩子函数自动执行
|
|
//3.1 删除旧任务
|
|
err = tx.Where("plan_id = ?", plan.Id).Unscoped().Delete(&plant.CareTask{}).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//3.2 创建新任务
|
|
dueDate := today.AddDate(0, 0, plan.Period)
|
|
task := plant.CareTask{
|
|
UserId: myPlant.UserId,
|
|
PlantId: myPlant.Id,
|
|
PlanId: plan.Id,
|
|
Name: plan.Name,
|
|
Icon: plan.Icon,
|
|
DueDate: dueDate,
|
|
Status: 1,
|
|
}
|
|
err = tx.Create(&task).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// TodayTask 今日任务
|
|
func (s *MyPlantService) TodayTask(userId string) ([]plantRes.PlantTaskVO, error) {
|
|
today := timer.GetZeroTime()
|
|
endOfToday := today.Add(24 * time.Hour)
|
|
|
|
var tasks []*plant.CareTask
|
|
// 查询条件:1.未完成的任务(包含今天和以前逾期的) 2.今天已经完成的任务
|
|
err := global.DB.Where("user_id = ? AND ("+
|
|
"(status = 1 AND due_date < ?) OR "+
|
|
"(status = 2 AND completed_at >= ? AND completed_at < ?)"+
|
|
")", userId, endOfToday, today, endOfToday).
|
|
Order("due_date ASC").
|
|
Find(&tasks).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 2.内存处理:聚合数据
|
|
plantTaskMap := make(map[string][]*plant.CareTask)
|
|
expiredMap := make(map[string]bool)
|
|
var plantIds []string
|
|
for _, t := range tasks {
|
|
plantIds = append(plantIds, t.PlantId)
|
|
plantTaskMap[t.PlantId] = append(plantTaskMap[t.PlantId], t)
|
|
// 判定右上角红标:状态为待办 且 应做时间早于今天
|
|
if t.Status == 1 && t.DueDate.Before(today) {
|
|
expiredMap[t.PlantId] = true
|
|
}
|
|
}
|
|
//3.批量查询植物
|
|
var myPlants []*plant.MyPlant
|
|
err = global.DB.Where("id in ?", plantIds).Preload("ImgList", func(db *gorm.DB) *gorm.DB {
|
|
return db.Order("created_at desc")
|
|
}).Find(&myPlants).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
//4.组装结果
|
|
var res []plantRes.PlantTaskVO
|
|
for _, p := range myPlants {
|
|
plantTaskVO := plantRes.PlantTaskVO{
|
|
MyPlant: p,
|
|
HasExpired: expiredMap[p.Id],
|
|
Tasks: plantTaskMap[p.Id],
|
|
}
|
|
res = append(res, plantTaskVO)
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
// CompleteTask 完成任务
|
|
func (s *MyPlantService) CompleteTask(req plantReq.CompleteTask) error {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var task plant.CareTask
|
|
if err := tx.Where("id = ?", req.TaskId).First(&task).Error; err != nil {
|
|
return err
|
|
}
|
|
//1.更新当前任务为完成
|
|
updateData := map[string]interface{}{
|
|
"status": 2,
|
|
"completed_at": time.Now(),
|
|
}
|
|
if err := tx.Model(&task).Where("id = ?", req.TaskId).Updates(updateData).Error; err != nil {
|
|
return err
|
|
}
|
|
//2.获取计划模版
|
|
var plan plant.CarePlan
|
|
if err := tx.Where("id = ?", task.PlanId).First(&plan).Error; err != nil {
|
|
return err
|
|
}
|
|
//3.生成下个周期的任务
|
|
today := timer.GetZeroTime()
|
|
nextDueDate := today.AddDate(0, 0, plan.Period)
|
|
newTask := plant.CareTask{
|
|
UserId: plan.UserId,
|
|
PlantId: plan.PlantId,
|
|
PlanId: plan.Id,
|
|
Name: plan.Name,
|
|
Icon: plan.Icon,
|
|
DueDate: nextDueDate,
|
|
Status: 1,
|
|
}
|
|
if err := tx.Create(&newTask).Error; err != nil {
|
|
return err
|
|
}
|
|
//4.保存养护记录
|
|
record := plant.CareRecord{
|
|
UserId: plan.UserId,
|
|
PlantId: plan.PlantId,
|
|
PlanId: plan.Id,
|
|
Name: plan.Name,
|
|
Icon: plan.Icon,
|
|
Remark: req.Remark,
|
|
}
|
|
if err := tx.Create(&record).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// DeletePlants 删除植物
|
|
func (s *MyPlantService) DeletePlants(req common.IdsReq) error {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var plants []plant.MyPlant
|
|
if err := tx.Where("id in ?", req.Ids).Find(&plants).Error; err != nil {
|
|
return err
|
|
}
|
|
// 删除图片 养护计划 养护任务 养护记录 成长记录
|
|
err := tx.Select("ImgList", "CarePlans", "CareTasks", "CareRecords").Unscoped().Delete(&plants).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// DeletePlans 删除任务
|
|
func (s *MyPlantService) DeletePlans(req common.IdsReq) error {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var plans []plant.CarePlan
|
|
if err := tx.Where("id in ?", req.Ids).Find(&plans).Error; err != nil {
|
|
return err
|
|
}
|
|
var tasks []plant.CareTask
|
|
if err := tx.Where("plan_id in ?", req.Ids).Find(&tasks).Error; err != nil {
|
|
return err
|
|
}
|
|
//1.删除计划
|
|
err := tx.Unscoped().Delete(&plans).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//2.删除任务
|
|
err = tx.Unscoped().Delete(&tasks).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// AddCarePlan 添加CarePlan
|
|
func (s *MyPlantService) AddCarePlan(req plantReq.AddPlans) error {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
for _, plan := range req.CarePlan {
|
|
var myPlant plant.MyPlant
|
|
err := tx.Where("id = ?", plan.PlantId).First(&myPlant).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//1.新增计划
|
|
newPlan := plant.CarePlan{
|
|
UserId: myPlant.UserId,
|
|
PlantId: myPlant.Id,
|
|
Name: plan.Name,
|
|
Icon: plan.Icon,
|
|
Period: plan.Period,
|
|
}
|
|
err = tx.Create(&newPlan).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//2.新增任务
|
|
today := timer.GetZeroTime()
|
|
dueDate := today.AddDate(0, 0, plan.Period)
|
|
task := plant.CareTask{
|
|
UserId: myPlant.UserId,
|
|
PlantId: myPlant.Id,
|
|
PlanId: newPlan.Id,
|
|
Name: plan.Name,
|
|
Icon: plan.Icon,
|
|
DueDate: dueDate,
|
|
Status: 1,
|
|
}
|
|
err = tx.Create(&task).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// DeletePlan 删除CarePlan
|
|
func (s *MyPlantService) DeletePlan(id string) error {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
var plan plant.CarePlan
|
|
if err := tx.Where("id = ?", id).First(&plan).Error; err != nil {
|
|
return err
|
|
}
|
|
var tasks []plant.CareTask
|
|
if err := tx.Where("plan_id = ?", plan.Id).Find(&tasks).Error; err != nil {
|
|
return err
|
|
}
|
|
err := tx.Unscoped().Delete(&plan).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = tx.Unscoped().Delete(&tasks).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// AddGrowthRecord 添加成长记录
|
|
func (s *MyPlantService) AddGrowthRecord(req plantReq.CreateGrowthRecord, userId string) error {
|
|
return global.DB.Transaction(func(tx *gorm.DB) error {
|
|
//1.验证图片是否存在
|
|
var ossList []*system.Oss
|
|
err := tx.Where("id in ?", req.OssIds).Find(&ossList).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//2.保存记录
|
|
record := plant.GrowthRecord{
|
|
UserId: userId,
|
|
PlantId: req.PlantId,
|
|
Name: req.Name,
|
|
Content: req.Content,
|
|
Desc: req.Desc,
|
|
Tag: req.Tag,
|
|
}
|
|
err = tx.Create(&record).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//3.保存图片关系
|
|
if len(ossList) > 0 {
|
|
var relations []map[string]interface{}
|
|
for _, oss := range ossList {
|
|
relations = append(relations, map[string]interface{}{
|
|
"growth_record_id": record.Id,
|
|
"oss_id": oss.Id,
|
|
})
|
|
}
|
|
err = tx.Table("sundynix_growth_record_oss").Create(relations).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|