feat: 迁移plant
This commit is contained in:
@@ -21,10 +21,35 @@ func NewCreatePlantLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Creat
|
||||
|
||||
func (l *CreatePlantLogic) CreatePlant(req *types.CreatePlantReq) error {
|
||||
userId := fmt.Sprintf("%v", l.ctx.Value("userId"))
|
||||
_, err := l.svcCtx.PlantRpc.CreatePlant(l.ctx, &plant.CreatePlantReq{
|
||||
imgIds := req.ImgIds
|
||||
if len(imgIds) == 0 {
|
||||
imgIds = req.OssIds
|
||||
}
|
||||
resp, err := l.svcCtx.PlantRpc.CreatePlant(l.ctx, &plant.CreatePlantReq{
|
||||
UserId: userId, Name: req.Name, PlantTime: req.PlantTime, Placement: req.Placement,
|
||||
PotMaterial: req.PotMaterial, PotSize: req.PotSize, Sunlight: req.Sunlight,
|
||||
PlantingMaterial: req.PlantingMaterial, ImgIds: req.ImgIds,
|
||||
PlantingMaterial: req.PlantingMaterial, ImgIds: imgIds,
|
||||
})
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp == nil || resp.Msg == "" || resp.Msg == "ok" {
|
||||
return nil
|
||||
}
|
||||
for _, planReq := range req.CarePlans {
|
||||
if planReq.Name == "" || planReq.Period <= 0 {
|
||||
continue
|
||||
}
|
||||
if _, err = l.svcCtx.PlantRpc.AddCarePlan(l.ctx, &plant.AddCarePlanReq{
|
||||
UserId: userId,
|
||||
PlantId: resp.Msg,
|
||||
Name: planReq.Name,
|
||||
Icon: planReq.Icon,
|
||||
TargetAction: planReq.TargetAction,
|
||||
Period: int32(planReq.Period),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package myPlant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/plant/api/internal/svc"
|
||||
"sundynix-micro-go/app/plant/api/internal/types"
|
||||
plantPb "sundynix-micro-go/app/plant/rpc/plant"
|
||||
)
|
||||
|
||||
type DeleteCarePlanLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewDeleteCarePlanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteCarePlanLogic {
|
||||
return &DeleteCarePlanLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
|
||||
}
|
||||
|
||||
func (l *DeleteCarePlanLogic) DeleteCarePlan(req *types.IdsReq) error {
|
||||
_, err := l.svcCtx.PlantRpc.DeleteCarePlan(l.ctx, &plantPb.IdsReq{Ids: req.Ids})
|
||||
return err
|
||||
}
|
||||
@@ -3,10 +3,12 @@ package myPlant
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"sundynix-micro-go/app/plant/api/internal/svc"
|
||||
"sundynix-micro-go/app/plant/api/internal/types"
|
||||
"sundynix-micro-go/app/plant/rpc/plant"
|
||||
plantModel "sundynix-micro-go/app/plant/model"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetMyPlantListLogic struct {
|
||||
@@ -19,13 +21,130 @@ func NewGetMyPlantListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge
|
||||
return &GetMyPlantListLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
|
||||
}
|
||||
|
||||
type plantListResp struct {
|
||||
List interface{} `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
|
||||
type PlantItem struct {
|
||||
ID string `json:"id"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
CreatedAtStr string `json:"createdAtStr"`
|
||||
UserID string `json:"userId"`
|
||||
Name string `json:"name"`
|
||||
PlantTime string `json:"plantTime"`
|
||||
Status int `json:"status"`
|
||||
Placement string `json:"placement"`
|
||||
PotMaterial string `json:"potMaterial"`
|
||||
PotSize string `json:"potSize"`
|
||||
Sunlight string `json:"sunlight"`
|
||||
PlantingMaterial string `json:"plantingMaterial"`
|
||||
ImgList []ImageInfo `json:"imgList"`
|
||||
CarePlans interface{} `json:"carePlans"`
|
||||
CareTasks interface{} `json:"careTasks"`
|
||||
CareRecords interface{} `json:"careRecords"`
|
||||
GrowthRecords interface{} `json:"growthRecords"`
|
||||
}
|
||||
|
||||
func (l *GetMyPlantListLogic) GetMyPlantList(req *types.PlantListReq) (resp interface{}, err error) {
|
||||
userId := fmt.Sprintf("%v", l.ctx.Value("userId"))
|
||||
result, err := l.svcCtx.PlantRpc.GetPlantList(l.ctx, &plant.PlantListReq{
|
||||
UserId: userId, Current: int32(req.Current), PageSize: int32(req.PageSize), Name: req.Name,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
db := l.svcCtx.DB.Model(&plantModel.MyPlant{}).Where("user_id = ?", userId)
|
||||
if req.Name != "" {
|
||||
db = db.Where("name like ?", "%"+req.Name+"%")
|
||||
}
|
||||
|
||||
var total int64
|
||||
db.Count(&total)
|
||||
|
||||
pageSize := req.PageSize
|
||||
if pageSize <= 0 {
|
||||
pageSize = 20
|
||||
}
|
||||
page := req.Current
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
offset := (page - 1) * pageSize
|
||||
|
||||
var plants []plantModel.MyPlant
|
||||
if err := db.Limit(pageSize).Offset(offset).Order("created_at desc").Find(&plants).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return map[string]interface{}{"list": result.List, "total": result.Total}, nil
|
||||
|
||||
// 查本地关联表获取图片 ID,再通过 FileRpc 获取完整信息
|
||||
imgMap := resolvePlantImages(l.ctx, l.svcCtx, plants)
|
||||
|
||||
var list []PlantItem
|
||||
for _, p := range plants {
|
||||
list = append(list, PlantItem{
|
||||
ID: p.ID,
|
||||
CreatedAt: FormatTime(p.CreatedAt),
|
||||
UpdatedAt: FormatTime(p.UpdatedAt),
|
||||
CreatedAtStr: FormatTimeShort(p.CreatedAt),
|
||||
UserID: p.UserID,
|
||||
Name: p.Name,
|
||||
PlantTime: FormatTime(p.PlantTime),
|
||||
Status: p.Status,
|
||||
Placement: p.Placement,
|
||||
PotMaterial: p.PotMaterial,
|
||||
PotSize: p.PotSize,
|
||||
Sunlight: p.Sunlight,
|
||||
PlantingMaterial: p.PlantingMaterial,
|
||||
ImgList: imgMap[p.ID],
|
||||
CarePlans: nil,
|
||||
CareTasks: nil,
|
||||
CareRecords: nil,
|
||||
GrowthRecords: nil,
|
||||
})
|
||||
}
|
||||
|
||||
return &plantListResp{List: list, Total: total, Page: page, PageSize: pageSize}, nil
|
||||
}
|
||||
|
||||
// resolvePlantImages 批量查询植物图片
|
||||
func resolvePlantImages(ctx context.Context, svcCtx *svc.ServiceContext, plants []plantModel.MyPlant) map[string][]ImageInfo {
|
||||
var plantIds []string
|
||||
for _, p := range plants {
|
||||
plantIds = append(plantIds, p.ID)
|
||||
}
|
||||
if len(plantIds) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
type rel struct {
|
||||
MyPlantID string `gorm:"column:sundynix_my_plant_id"`
|
||||
OssID string `gorm:"column:sundynix_oss_id"`
|
||||
}
|
||||
var rels []rel
|
||||
svcCtx.DB.Table("sundynix_plant_my_plant_oss").
|
||||
Where("sundynix_my_plant_id IN ?", plantIds).
|
||||
Order("sundynix_oss_id asc").
|
||||
Find(&rels)
|
||||
|
||||
var allOssIds []string
|
||||
pidMap := make(map[string][]string)
|
||||
for _, r := range rels {
|
||||
pidMap[r.MyPlantID] = append(pidMap[r.MyPlantID], r.OssID)
|
||||
allOssIds = append(allOssIds, r.OssID)
|
||||
}
|
||||
|
||||
fileInfos := FetchFilesByIds(ctx, svcCtx, allOssIds)
|
||||
result := make(map[string][]ImageInfo)
|
||||
for pid, ids := range pidMap {
|
||||
var imgs []ImageInfo
|
||||
for _, oid := range ids {
|
||||
if f, ok := fileInfos[oid]; ok {
|
||||
imgs = append(imgs, f)
|
||||
}
|
||||
}
|
||||
if imgs == nil {
|
||||
imgs = []ImageInfo{}
|
||||
}
|
||||
result[pid] = imgs
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ package myPlant
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gorm"
|
||||
"sundynix-micro-go/app/plant/api/internal/svc"
|
||||
"sundynix-micro-go/app/plant/api/internal/types"
|
||||
"sundynix-micro-go/app/plant/rpc/plant"
|
||||
plantModel "sundynix-micro-go/app/plant/model"
|
||||
)
|
||||
|
||||
type GetPlantDetailLogic struct {
|
||||
@@ -18,10 +20,226 @@ func NewGetPlantDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge
|
||||
return &GetPlantDetailLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
|
||||
}
|
||||
|
||||
// PlantDetailItem 植物详情 DTO
|
||||
type PlantDetailItem struct {
|
||||
ID string `json:"id"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
CreatedAtStr string `json:"createdAtStr"`
|
||||
UserID string `json:"userId"`
|
||||
Name string `json:"name"`
|
||||
PlantTime string `json:"plantTime"`
|
||||
Status int `json:"status"`
|
||||
Placement string `json:"placement"`
|
||||
PotMaterial string `json:"potMaterial"`
|
||||
PotSize string `json:"potSize"`
|
||||
Sunlight string `json:"sunlight"`
|
||||
PlantingMaterial string `json:"plantingMaterial"`
|
||||
ImgList []ImageInfo `json:"imgList"`
|
||||
CarePlans []CarePlanItem `json:"carePlans"`
|
||||
CareTasks interface{} `json:"careTasks"`
|
||||
CareRecords []CareRecordItem `json:"careRecords"`
|
||||
GrowthRecords []GrowthRecordItem `json:"growthRecords"`
|
||||
}
|
||||
|
||||
type CarePlanItem struct {
|
||||
ID string `json:"id"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
CreatedAtStr string `json:"createdAtStr"`
|
||||
UserID string `json:"userId"`
|
||||
PlantID string `json:"plantId"`
|
||||
Icon string `json:"icon"`
|
||||
Name string `json:"name"`
|
||||
Period int `json:"period"`
|
||||
TargetAction string `json:"targetAction"`
|
||||
}
|
||||
|
||||
type CareRecordItem struct {
|
||||
ID string `json:"id"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
CreatedAtStr string `json:"createdAtStr"`
|
||||
UserID string `json:"userId"`
|
||||
PlantID string `json:"plantId"`
|
||||
PlanID string `json:"planId"`
|
||||
Name string `json:"name"`
|
||||
Remark string `json:"remark"`
|
||||
Icon string `json:"icon"`
|
||||
}
|
||||
|
||||
type GrowthRecordItem struct {
|
||||
ID string `json:"id"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
CreatedAtStr string `json:"createdAtStr"`
|
||||
PlantID string `json:"plantId"`
|
||||
UserID string `json:"userId"`
|
||||
Name string `json:"name"`
|
||||
Tag string `json:"tag"`
|
||||
Desc string `json:"desc"`
|
||||
Content string `json:"content"`
|
||||
ImgList []ImageInfo `json:"imgList"`
|
||||
}
|
||||
|
||||
func (l *GetPlantDetailLogic) GetPlantDetail(req *types.IdPathReq) (resp interface{}, err error) {
|
||||
result, err := l.svcCtx.PlantRpc.GetPlantDetail(l.ctx, &plant.IdReq{Id: req.Id})
|
||||
var myPlant plantModel.MyPlant
|
||||
err = l.svcCtx.DB.
|
||||
Preload("CarePlans").
|
||||
Preload("CareRecords", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("created_at desc")
|
||||
}).
|
||||
Preload("GrowthRecords", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("created_at desc")
|
||||
}).
|
||||
Where("id = ?", req.Id).First(&myPlant).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
|
||||
// 查图片(本地关联表 + FileRpc)
|
||||
imgList := queryPlantImages(l.ctx, l.svcCtx, req.Id)
|
||||
|
||||
// 成长记录图片
|
||||
growthImgMap := resolveGrowthRecordImages(l.ctx, l.svcCtx, myPlant.GrowthRecords)
|
||||
|
||||
return &PlantDetailItem{
|
||||
ID: myPlant.ID,
|
||||
CreatedAt: FormatTime(myPlant.CreatedAt),
|
||||
UpdatedAt: FormatTime(myPlant.UpdatedAt),
|
||||
CreatedAtStr: FormatTimeShort(myPlant.CreatedAt),
|
||||
UserID: myPlant.UserID,
|
||||
Name: myPlant.Name,
|
||||
PlantTime: FormatTime(myPlant.PlantTime),
|
||||
Status: myPlant.Status,
|
||||
Placement: myPlant.Placement,
|
||||
PotMaterial: myPlant.PotMaterial,
|
||||
PotSize: myPlant.PotSize,
|
||||
Sunlight: myPlant.Sunlight,
|
||||
PlantingMaterial: myPlant.PlantingMaterial,
|
||||
ImgList: imgList,
|
||||
CarePlans: toCarePlanItems(myPlant.CarePlans),
|
||||
CareTasks: nil,
|
||||
CareRecords: toCareRecordItems(myPlant.CareRecords),
|
||||
GrowthRecords: toGrowthRecordItems(myPlant.GrowthRecords, growthImgMap),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func queryPlantImages(ctx context.Context, svcCtx *svc.ServiceContext, plantID string) []ImageInfo {
|
||||
type rel struct {
|
||||
OssID string `gorm:"column:sundynix_oss_id"`
|
||||
}
|
||||
var rels []rel
|
||||
svcCtx.DB.Table("sundynix_plant_my_plant_oss").
|
||||
Where("sundynix_my_plant_id = ?", plantID).
|
||||
Order("sundynix_oss_id asc").
|
||||
Find(&rels)
|
||||
|
||||
var ids []string
|
||||
for _, r := range rels {
|
||||
ids = append(ids, r.OssID)
|
||||
}
|
||||
infos := FetchFilesByIds(ctx, svcCtx, ids)
|
||||
var result []ImageInfo
|
||||
for _, id := range ids {
|
||||
if f, ok := infos[id]; ok {
|
||||
result = append(result, f)
|
||||
}
|
||||
}
|
||||
if result == nil {
|
||||
result = []ImageInfo{}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func resolveGrowthRecordImages(ctx context.Context, svcCtx *svc.ServiceContext, records []*plantModel.GrowthRecord) map[string][]ImageInfo {
|
||||
var ids []string
|
||||
for _, gr := range records {
|
||||
ids = append(ids, gr.ID)
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
type rel struct {
|
||||
GrowthRecordID string `gorm:"column:growth_record_id"`
|
||||
OssID string `gorm:"column:oss_id"`
|
||||
}
|
||||
var rels []rel
|
||||
svcCtx.DB.Table("sundynix_plant_growth_record_oss").
|
||||
Where("growth_record_id IN ?", ids).
|
||||
Find(&rels)
|
||||
|
||||
var allOssIds []string
|
||||
gidMap := make(map[string][]string)
|
||||
for _, r := range rels {
|
||||
gidMap[r.GrowthRecordID] = append(gidMap[r.GrowthRecordID], r.OssID)
|
||||
allOssIds = append(allOssIds, r.OssID)
|
||||
}
|
||||
|
||||
infos := FetchFilesByIds(ctx, svcCtx, allOssIds)
|
||||
result := make(map[string][]ImageInfo)
|
||||
for gid, ossIds := range gidMap {
|
||||
var imgs []ImageInfo
|
||||
for _, oid := range ossIds {
|
||||
if f, ok := infos[oid]; ok {
|
||||
imgs = append(imgs, f)
|
||||
}
|
||||
}
|
||||
result[gid] = imgs
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func toCarePlanItems(plans []*plantModel.CarePlan) []CarePlanItem {
|
||||
var items []CarePlanItem
|
||||
for _, p := range plans {
|
||||
items = append(items, CarePlanItem{
|
||||
ID: p.ID, CreatedAt: FormatTime(p.CreatedAt),
|
||||
UpdatedAt: FormatTime(p.UpdatedAt), CreatedAtStr: FormatTimeShort(p.CreatedAt),
|
||||
UserID: p.UserID, PlantID: p.PlantID, Icon: p.Icon, Name: p.Name,
|
||||
Period: p.Period, TargetAction: p.TargetAction,
|
||||
})
|
||||
}
|
||||
if items == nil {
|
||||
items = []CarePlanItem{}
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func toCareRecordItems(records []*plantModel.CareRecord) []CareRecordItem {
|
||||
var items []CareRecordItem
|
||||
for _, r := range records {
|
||||
items = append(items, CareRecordItem{
|
||||
ID: r.ID, CreatedAt: FormatTime(r.CreatedAt),
|
||||
UpdatedAt: FormatTime(r.UpdatedAt), CreatedAtStr: FormatTimeShort(r.CreatedAt),
|
||||
UserID: r.UserID, PlantID: r.PlantID, PlanID: r.PlanID,
|
||||
Name: r.Name, Remark: r.Remark, Icon: r.Icon,
|
||||
})
|
||||
}
|
||||
if items == nil {
|
||||
items = []CareRecordItem{}
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func toGrowthRecordItems(records []*plantModel.GrowthRecord, imgMap map[string][]ImageInfo) []GrowthRecordItem {
|
||||
var items []GrowthRecordItem
|
||||
for _, gr := range records {
|
||||
item := GrowthRecordItem{
|
||||
ID: gr.ID, CreatedAt: FormatTime(gr.CreatedAt),
|
||||
UpdatedAt: FormatTime(gr.UpdatedAt), CreatedAtStr: FormatTimeShort(gr.CreatedAt),
|
||||
PlantID: gr.PlantID, UserID: gr.UserID, Name: gr.Name,
|
||||
Tag: gr.Tag, Desc: gr.Desc, Content: gr.Content,
|
||||
ImgList: imgMap[gr.ID],
|
||||
}
|
||||
if item.ImgList == nil {
|
||||
item.ImgList = []ImageInfo{}
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
if items == nil {
|
||||
items = []GrowthRecordItem{}
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package myPlant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"sundynix-micro-go/app/plant/api/internal/svc"
|
||||
plantPb "sundynix-micro-go/app/plant/rpc/plant"
|
||||
)
|
||||
|
||||
type GetTodayTaskListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetTodayTaskListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetTodayTaskListLogic {
|
||||
return &GetTodayTaskListLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
|
||||
}
|
||||
|
||||
func (l *GetTodayTaskListLogic) GetTodayTaskList() (*plantPb.CareTaskListResp, error) {
|
||||
userId := fmt.Sprintf("%v", l.ctx.Value("userId"))
|
||||
return l.svcCtx.PlantRpc.GetTodayTaskList(l.ctx, &plantPb.GetProfileReq{UserId: userId})
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package myPlant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
filePb "sundynix-micro-go/app/file/rpc/file"
|
||||
"sundynix-micro-go/app/plant/api/internal/svc"
|
||||
)
|
||||
|
||||
// ========== 图片 DTO ==========
|
||||
|
||||
// ImageInfo 图片信息 DTO,匹配旧单体 Oss 结构
|
||||
type ImageInfo struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Url string `json:"url"`
|
||||
Tag string `json:"tag"`
|
||||
Key string `json:"key"`
|
||||
Suffix string `json:"suffix"`
|
||||
MD5 string `json:"md5"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
CreatedAtStr string `json:"createdAtStr"`
|
||||
}
|
||||
|
||||
// ========== 时间格式化 ==========
|
||||
|
||||
func FormatTime(t time.Time) string {
|
||||
if t.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return t.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
func FormatTimeShort(t time.Time) string {
|
||||
if t.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return t.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func UnixToTimeStr(ts int64) string {
|
||||
if ts == 0 {
|
||||
return ""
|
||||
}
|
||||
return time.Unix(ts, 0).Format(time.RFC3339)
|
||||
}
|
||||
|
||||
func UnixToTimeStrShort(ts int64) string {
|
||||
if ts == 0 {
|
||||
return ""
|
||||
}
|
||||
return time.Unix(ts, 0).Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
// ========== 文件服务 RPC 封装 ==========
|
||||
|
||||
// FetchFilesByIds 通过 FileRpc 批量获取文件信息,返回 id->ImageInfo 映射
|
||||
func FetchFilesByIds(ctx context.Context, svcCtx *svc.ServiceContext, ids []string) map[string]ImageInfo {
|
||||
result := make(map[string]ImageInfo)
|
||||
if len(ids) == 0 {
|
||||
return result
|
||||
}
|
||||
resp, err := svcCtx.FileRpc.GetFilesByIds(ctx, &filePb.GetFilesByIdsReq{Ids: ids})
|
||||
if err != nil || resp == nil {
|
||||
return result
|
||||
}
|
||||
for _, f := range resp.Files {
|
||||
result[f.Id] = ImageInfo{
|
||||
ID: f.Id,
|
||||
Name: f.Name,
|
||||
Url: f.Url,
|
||||
Tag: f.Tag,
|
||||
Key: f.Key,
|
||||
Suffix: f.Suffix,
|
||||
MD5: f.Md5,
|
||||
CreatedAt: UnixToTimeStr(f.CreatedAt),
|
||||
UpdatedAt: UnixToTimeStr(f.CreatedAt),
|
||||
CreatedAtStr: UnixToTimeStrShort(f.CreatedAt),
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package myPlant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"sundynix-micro-go/app/plant/api/internal/svc"
|
||||
"sundynix-micro-go/app/plant/api/internal/types"
|
||||
plantModel "sundynix-micro-go/app/plant/model"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type QuickCareLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewQuickCareLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QuickCareLogic {
|
||||
return &QuickCareLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
|
||||
}
|
||||
|
||||
func (l *QuickCareLogic) QuickCare(req *types.QuickCareReq) error {
|
||||
userId := fmt.Sprintf("%v", l.ctx.Value("userId"))
|
||||
|
||||
return l.svcCtx.DB.Transaction(func(tx *gorm.DB) error {
|
||||
// 1. Validate plant exists and belongs to user
|
||||
var myPlant plantModel.MyPlant
|
||||
if err := tx.Where("id = ? AND user_id = ?", req.PlantId, userId).First(&myPlant).Error; err != nil {
|
||||
return errors.New("植物不存在")
|
||||
}
|
||||
|
||||
// 2. Create care record
|
||||
record := plantModel.CareRecord{
|
||||
UserID: userId,
|
||||
PlantID: req.PlantId,
|
||||
Name: req.Name,
|
||||
Icon: req.Icon,
|
||||
Remark: req.Remark,
|
||||
}
|
||||
if err := tx.Create(&record).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. Update user profile counter
|
||||
column := "care_count"
|
||||
if req.Icon != "" || req.Name != "" {
|
||||
nameMap := map[string]string{
|
||||
"浇水": "water_count",
|
||||
"施肥": "fertilize_count",
|
||||
"修剪": "prune_count",
|
||||
"换盆": "repot_count",
|
||||
}
|
||||
if col, ok := nameMap[req.Name]; ok {
|
||||
column = col
|
||||
} else if req.Icon != "" {
|
||||
actionMap := map[string]string{
|
||||
"water": "water_count", "fertilize": "fertilize_count",
|
||||
"prune": "prune_count", "repot": "repot_count",
|
||||
}
|
||||
for key, col := range actionMap {
|
||||
if strings.Contains(req.Icon, key) {
|
||||
column = col
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tx.Model(&plantModel.UserProfile{}).Where("user_id = ?", userId).
|
||||
Update(column, gorm.Expr(column+" + 1")).Error
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user