Files
jx-callback/business/userstore/food_recipe.go
苏尹岚 0dd7235485 aa
2021-03-30 17:39:07 +08:00

368 lines
9.6 KiB
Go

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()
txDB , _ := dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db, txDB)
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, txDB)
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())
txDB , _ := dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db, txDB)
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, txDB)
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
txDB , _ := dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db, txDB)
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, txDB)
return err
}
func DeleteRecipes(ctx *jxcontext.Context, recipeIDs []int) (num int64, err error) {
db := dao.GetDB()
txDB , _ := dao.Begin(db)
defer func() {
if r := recover(); r != nil || err != nil {
dao.Rollback(db, txDB)
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, txDB)
return 0, err
}