package logic import ( "context" "encoding/json" "errors" "fmt" "fusenapi/constants" "fusenapi/model/gmodel" "fusenapi/server/inventory/internal/types" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/id_generator" "gorm.io/gorm" "time" "fusenapi/server/inventory/internal/svc" "github.com/zeromicro/go-zero/core/logx" ) type TakeLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewTakeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TakeLogic { return &TakeLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *TakeLogic) Take(req *types.TakeReq, userinfo *auth.UserInfo) (resp *basic.Response) { if userinfo.GetIdType() != auth.IDTYPE_User { return resp.SetStatusWithMessage(basic.CodeServiceErr, "please login first") } if len(req.Form) == 0 { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "param err :form can`t be empty array") } if req.AddressId <= 0 { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "param err :address_id is required") } //获取地址信息 addressInfo, err := l.svcCtx.AllModels.FsAddress.GetOne(l.ctx, req.AddressId, userinfo.UserId) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "your address is not exists") } logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get address info") } stockIds := make([]int64, 0, len(req.Form)) for _, v := range req.Form { stockIds = append(stockIds, v.Id) } //提货单总单 addressInfoBytes, _ := json.Marshal(addressInfo) addressInfoJson := string(addressInfoBytes) trackNum := id_generator.GenPickUpTrackNum() status := int64(constants.STATUS_ORDERD) now := time.Now().Unix() pickUpData := gmodel.FsCloudPickUp{ UserId: &userinfo.UserId, TrackNum: &trackNum, AddressId: &req.AddressId, AddressInfo: &addressInfoJson, Status: &status, Ctime: &now, } //箱数验证 boxes := int64(0) //需要更新的库存信息 stockUpdateList := make([]gmodel.FsUserStock, 0, len(req.Form)) //需要新增的提货详情单 pickUpDetailAddList := make([]gmodel.FsCloudPickUpDetail, 0, len(req.Form)) for k, val := range req.Form { formItem := val //验证提取数量 if formItem.Num <= 0 { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, fmt.Sprintf("row %d inventory data`s take num can`be less than 0", k+1)) } //获取库存信息(枷锁) stockInfo, err := l.svcCtx.AllModels.FsUserStock.FindOne(l.ctx, formItem.Id, userinfo.UserId, true) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, fmt.Sprintf("row %d inventory data is not availabled for you", k+1)) } logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, fmt.Sprintf("failed to get row %d`s stock info ", k+1)) } //校验取货数量 if *stockInfo.Stick < formItem.Num { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, fmt.Sprintf("row %d inventory data is shortage", k+1)) } if *stockInfo.EachBoxNum <= 0 { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, fmt.Sprintf("row %d inventory data each box num can`t be less than 0", k+1)) } boxes += (formItem.Num / *stockInfo.EachBoxNum) //库存变更 newStick := *stockInfo.Stick - formItem.Num newTransNum := *stockInfo.TransNum + formItem.Num stockUpdateList = append(stockUpdateList, gmodel.FsUserStock{ Id: stockInfo.Id, Stick: &newStick, TransNum: &newTransNum, }) //提货详情单 detailBoxes := formItem.Num / *stockInfo.EachBoxNum pickUpDetailAddList = append(pickUpDetailAddList, gmodel.FsCloudPickUpDetail{ PickId: nil, //到model里方法会给他赋值pick总单id StockId: &formItem.Id, Num: &formItem.Num, Boxes: &detailBoxes, Ctime: &now, }) } if boxes < 3 { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "Take out more than three boxes") } //事务处理数据 err = l.svcCtx.AllModels.FsCloudPickUp.SavePickUpWithTransaction(l.ctx, &pickUpData, stockUpdateList, pickUpDetailAddList) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to take your goods") } return resp.SetStatusWithMessage(basic.CodeOK, "success", []int64{}) }