package userstore import ( "fmt" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils/errlist" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/datares" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" ) type FoodRecipeItemParam struct { Name string `json:"name"` SkuIDs []int `json:"skuIDs"` } type FoodRecipeStepParam struct { Name string `orm:"size(48)" json:"name"` Description string `orm:"size(4096)" json:"description"` Img string `orm:"size(48)" json:"img"` } type FoodRecipeItem struct { model.FoodRecipeItem ItemChoiceList []*dao.FoodRecipeItemChoiceExt `json:"itemChoiceList"` } type FoodRecipeDetail struct { dao.FoodRecipeWithAction ItemList []*FoodRecipeItem `json:"itemList"` StepList []*model.FoodRecipeStep `json:"stepList"` } func updateFoodRecipeItemAndStep(ctx *jxcontext.Context, db *dao.DaoDB, recipeID int, itemList []*FoodRecipeItemParam, stepList []*FoodRecipeStepParam) (err error) { for k, v := range itemList { if len(v.SkuIDs) == 0 { return fmt.Errorf("SkuIDs必须要有值") } skuIDs, err2 := dao.GetSkus(db, v.SkuIDs, nil, nil, nil, nil) if err = err2; err != nil { return err } if len(v.SkuIDs) != len(skuIDs) { return fmt.Errorf("某些SkuID不存在") } item := &model.FoodRecipeItem{ RecipeID: recipeID, Index: int8(k + 1), Name: v.Name, } dao.WrapAddIDCULDEntity(item, ctx.GetUserName()) if err = dao.CreateEntity(db, item); err != nil { return err } for k2, v2 := range v.SkuIDs { choice := &model.FoodRecipeItemChoice{ RecipeID: recipeID, Index: item.Index, SkuID: v2, ChoiceIndex: int8(k2 + 1), } dao.WrapAddIDCULDEntity(choice, ctx.GetUserName()) if err = dao.CreateEntity(db, choice); err != nil { return err } } } for k, v := range stepList { step := &model.FoodRecipeStep{ RecipeID: recipeID, Index: int8(k + 1), Name: v.Name, Img: v.Img, Description: v.Description, } dao.WrapAddIDCULDEntity(step, ctx.GetUserName()) if err = dao.CreateEntity(db, step); err != nil { return err } } return err } func CreateFoodRecipe(ctx *jxcontext.Context, foodRecipe *model.FoodRecipe, itemList []*FoodRecipeItemParam, stepList []*FoodRecipeStepParam, authorID string) (err error) { if len(itemList) == 0 { return fmt.Errorf("必须要有配料") } if len(stepList) == 0 { return fmt.Errorf("必须要有操作步骤") } db := dao.GetDB() dao.Begin(db) defer func() { if r := recover(); r != nil || err != nil { dao.Rollback(db) if r != nil { panic(r) } } }() if authorID == "" { _, foodRecipe.AuthorID = ctx.GetMobileAndUserID() } else { foodRecipe.AuthorID = authorID } dao.WrapAddIDCULDEntity(foodRecipe, ctx.GetUserName()) if err = dao.CreateEntity(db, foodRecipe); err != nil { return err } if err = updateFoodRecipeItemAndStep(ctx, db, foodRecipe.ID, itemList, stepList); err != nil { return err } dao.Commit(db) tryRegisterDataRes4Recipe(ctx, foodRecipe.Name, foodRecipe.Img, stepList) return err } func UpdateFoodRecipe(ctx *jxcontext.Context, recipeID int, mapData map[string]interface{}, itemList []*FoodRecipeItemParam, stepList []*FoodRecipeStepParam) (err error) { db := dao.GetDB() localRecipe := &model.FoodRecipe{} localRecipe.ID = recipeID if err = dao.GetEntity(db, localRecipe); err != nil { return err } valid := dao.StrictMakeMapByStructObject(mapData, localRecipe, ctx.GetUserName()) dao.Begin(db) defer func() { if r := recover(); r != nil || err != nil { dao.Rollback(db) if r != nil { panic(r) } } }() if len(valid) > 0 { if _, err = dao.UpdateEntityLogically(db, localRecipe, valid, ctx.GetUserName(), nil); err != nil { return err } } if len(itemList) > 0 { choice := &model.FoodRecipeItemChoice{ RecipeID: recipeID, } if _, err = dao.DeleteEntity(db, choice, "RecipeID"); err != nil { return err } recipeItems := &model.FoodRecipeItem{ RecipeID: recipeID, } if _, err = dao.DeleteEntity(db, recipeItems, "RecipeID"); err != nil { return err } } if len(stepList) > 0 { recipeSteps := &model.FoodRecipeStep{ RecipeID: recipeID, } if _, err = dao.DeleteEntity(db, recipeSteps, "RecipeID"); err != nil { return err } } if err = updateFoodRecipeItemAndStep(ctx, db, recipeID, itemList, stepList); err != nil { return err } dao.Commit(db) tryRegisterDataRes4Recipe(ctx, localRecipe.Name, utils.Interface2String(valid["img"]), stepList) return err } func tryRegisterDataRes4Recipe(ctx *jxcontext.Context, name, mainImg string, stepList []*FoodRecipeStepParam) (err error) { imgList := []string{} if mainImg != "" { imgList = append(imgList, mainImg) } for _, v := range stepList { if v.Img != "" { imgList = append(imgList, v.Img) } } errList := errlist.New() for _, v := range imgList { _, err := datares.TryRegisterDataResource(ctx, name, v, model.ImgTypeLocal, true) errList.AddErr(err) } return errList.GetErrListAsOne() } func QueryFoodRecipes(ctx *jxcontext.Context, keyword, authorID string, skuIDs []int, offset, pageSize int) (recipeInfo *model.PagedInfo, err error) { _, userID := ctx.GetMobileAndUserID() recipeList, totalCount, err := dao.QueryFoodRecipes(dao.GetDB(), keyword, 0, authorID, userID, skuIDs, offset, pageSize) if err == nil { recipeInfo = &model.PagedInfo{ TotalCount: totalCount, Data: recipeList, } } return recipeInfo, err } func GetRecommendFoodRecipes(ctx *jxcontext.Context, keyword string, offset, pageSize int) (recipeInfo *model.PagedInfo, err error) { _, userID := ctx.GetMobileAndUserID() recipeList, totalCount, err := dao.GetRecommendFoodRecipes(dao.GetDB(), keyword, userID, offset, pageSize) if err == nil { recipeInfo = &model.PagedInfo{ TotalCount: totalCount, Data: recipeList, } } return recipeInfo, err } func GetRecipeDetail(ctx *jxcontext.Context, recipeID int) (recipeDetail *FoodRecipeDetail, err error) { _, userID := ctx.GetMobileAndUserID() db := dao.GetDB() recipeList, _, err := dao.QueryFoodRecipes(db, "", recipeID, "", userID, nil, 0, 0) if err != nil { return nil, err } if len(recipeList) == 0 { return nil, fmt.Errorf("找不到菜谱:%d", recipeID) } itemList, err := dao.QueryFoodRecipesItems(db, recipeID) if err != nil { return nil, err } itemChoiceList, err := dao.QueryFoodRecipesItemChoices(db, recipeID) if err != nil { return nil, err } choiceMap := make(map[int8][]*dao.FoodRecipeItemChoiceExt) for _, v := range itemChoiceList { v.SkuName = jxutils.ComposeSkuNameOriginal(v.Prefix, v.SkuNameName, v.Comment, v.Unit, v.SpecQuality, v.SpecUnit, 0) choiceMap[v.Index] = append(choiceMap[v.Index], v) } stepList, err := dao.QueryFoodRecipesSteps(db, recipeID) if err != nil { return nil, err } recipeDetail = &FoodRecipeDetail{ FoodRecipeWithAction: *recipeList[0], StepList: stepList, } for _, v := range itemList { recipeDetail.ItemList = append(recipeDetail.ItemList, &FoodRecipeItem{ FoodRecipeItem: *v, ItemChoiceList: choiceMap[v.Index], }) } return recipeDetail, err } func VoteFoodRecipe(ctx *jxcontext.Context, recipeID, voteType int) (err error) { _, userID := ctx.GetMobileAndUserID() if userID == "" { return fmt.Errorf("内部错误,找不到用户") } db := dao.GetDB() recipeList, _, err := dao.QueryFoodRecipes(db, "", recipeID, "", userID, nil, 0, 0) if err != nil { return err } if len(recipeList) == 0 { return fmt.Errorf("找不到菜谱:%d", recipeID) } recipe := &recipeList[0].FoodRecipe dao.Begin(db) defer func() { if r := recover(); r != nil || err != nil { dao.Rollback(db) if r != nil { panic(r) } } }() recipeUser := &model.FoodRecipeUser{ RecipeID: recipeID, UserID: userID, } if err = dao.GetEntity(db, recipeUser, "RecipeID", "UserID"); err != nil { if !dao.IsNoRowsError(err) { return err } } actionMask := int8(0) if voteType > 0 { recipe.UpvoteCount++ actionMask = model.RecipeActionUpvote } else if voteType < 0 { recipe.DownvoteCount++ actionMask = model.RecipeActionDownvote } if recipeUser.ActionType&model.RecipeActionUpvote != 0 { recipe.UpvoteCount-- } else if recipeUser.ActionType&model.RecipeActionDownvote != 0 { recipe.DownvoteCount-- } if recipeUser.ActionType&actionMask != 0 || (recipeUser.ActionType&(model.RecipeActionUpvote|model.RecipeActionDownvote) == 0 && voteType == 0) { return fmt.Errorf("已经做过此操作了") } recipeUser.ActionType = (recipeUser.ActionType & ^(model.RecipeActionUpvote | model.RecipeActionDownvote)) | actionMask if recipeUser.ID == 0 { dao.WrapAddIDCULDEntity(recipeUser, ctx.GetUserName()) err = dao.CreateEntity(db, recipeUser) } else { recipeUser.LastOperator = ctx.GetUserName() _, err = dao.UpdateEntity(db, recipeUser) } if err != nil { return err } _, err = dao.UpdateEntity(db, recipe, "UpvoteCount", "DownvoteCount") if err != nil { return err } dao.Commit(db) return err } func DeleteRecipes(ctx *jxcontext.Context, recipeIDs []int) (num int64, err error) { db := dao.GetDB() dao.Begin(db) defer func() { if r := recover(); r != nil || err != nil { dao.Rollback(db) if r != nil { panic(r) } } }() for _, recipeID := range recipeIDs { recipe := &model.FoodRecipe{} recipe.ID = recipeID num2, err2 := dao.DeleteEntityLogically(db, recipe, nil, ctx.GetUserName(), nil) if err = err2; err != nil { return 0, err } num += num2 } dao.Commit(db) return 0, err }