package controller import ( "errors" "github.com/codinl/go-logger" "github.com/gin-gonic/gin" "mh-server/lib/auth" "mh-server/lib/status" "mh-server/lib/wxpay" "mh-server/model" ) func MallGoodsList(c *gin.Context) { req := model.GoodsListReq{} if err := c.ShouldBindJSON(&req); err != nil { logger.Error(err) RespJson(c, status.BadRequest, nil) return } list, total, err := req.GoodsList() if err != nil { logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } ret := map[string]interface{}{ "list": list, "cur_page": req.PageIdx, "total_page": total, } RespOK(c, ret) return } func MallGoodsDetail(c *gin.Context) { req := model.GoodsDetailReq{} if err := c.ShouldBindJSON(&req); err != nil { logger.Error(err) RespJson(c, status.BadRequest, nil) return } detail, err := req.GoodsDetail() if err != nil { logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } RespOK(c, detail) return } func MallOrderCreate(c *gin.Context) { req := struct { GoodsId uint32 `json:"goods_id" binding:"required"` // 商品id Quantity uint32 `json:"quantity" binding:"required"` // 购买数量 PayType uint32 `json:"pay_type" binding:"required"` // 支付方式 AddressId uint32 `json:"address_id" binding:"required"` // 收货地址 DeliveryExtraInfo string `json:"delivery_extra_info"` // 收货备注 }{} if err := c.ShouldBindJSON(&req); err != nil { logger.Error(err) RespJson(c, status.BadRequest, nil) return } uc := auth.GetCurrentUser(c) if uc == nil { RespJson(c, status.Unauthorized, nil) return } // 商品是否存在 var goods model.Goods err := model.NewGoodsQuerySet(model.DB).GoodsIdEq(req.GoodsId).One(&goods) if err != nil { logger.Error("err:", err) RespJson(c, status.BadRequest, nil) return } // 商品在售状态 if goods.SaleStatus != model.SaleStatusYes { logger.Error("err:", err) RespJson(c, status.GoodsNotSale, nil) return } // 库存不足 if goods.Stock < req.Quantity { logger.Error("err:", err) RespJson(c, status.OrderStockOut, nil) return } // 检测收货地址是否正确 count, _ := model.NewUserAddressQuerySet(model.DB).UidEq(uc.Uid).IDEq(req.AddressId).Count() if count != 1 { logger.Error("err:", err) RespJson(c, status.BadRequest, "收货地址错误") return } // 计算总金额 amount := uint32(0) if req.PayType == model.PayTypeRm { amount = req.Quantity * goods.PriceRm } else if req.PayType == model.PayTypeVm { amount = req.Quantity * goods.PriceVm } // 开启事务 tx := model.TransactionBegin() // 订单创建逻辑 order := model.GoodsOrder{ OrderId: model.CreateGoodsOrderId(), SerialNo: model.CreateGoodsOrderSerialNo(), Uid: uc.Uid, GoodsId: req.GoodsId, Amount: amount, Quantity: req.Quantity, PayType: req.PayType, PayStatus: model.PayStatusInit, AddressId: req.AddressId, DeliveryExtraInfo: req.DeliveryExtraInfo, DeliveryFee: goods.DeliveryFee, DeliveryStatus: model.DeliveryStatusUnDeliver, } err = order.Create(tx) if err != nil { logger.Error("err:", err) tx.Rollback() RespJson(c, status.InternalServerError, nil) return } // TODO 减少库存 // TODO 确认下是在支付后减少,还是下单后? if req.PayType == model.PayTypeVm { var userVm model.UserVm err = model.NewUserVmQuerySet(model.DB).UidEq(uc.Uid).One(&userVm) if err != nil { tx.Rollback() logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } if userVm.Vm < amount { tx.Rollback() logger.Error("err:", err) RespJson(c, status.UserVmNotEnough, nil) return } err := model.OrderDeductionUserVm(uc.Uid, int(userVm.Vm), int(amount)*-1, tx) if err != nil { tx.Rollback() logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } } err = tx.Commit().Error if err != nil { tx.Rollback() logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } var user model.User err = model.NewUserQuerySet(model.DB).UidEq(uint32(order.Uid)).One(&user) if err != nil { logger.Error("Order err:", err) RespJson(c, status.InternalServerError, nil) return } webPay, err := wxpay.WebPay(order.SerialNo, goods.DeliveryFee, user.WxOpenID, "N", wxpay.WxPayExchangeGoods) if err != nil { logger.Error(errors.New("WebPay err")) RespJson(c, status.InternalServerError, nil) return } err = model.UserOpenMemberRecord{Uid: uc.Uid, OpenNo: order.SerialNo, OrderId: order.ID, OrderType: 3}.Insert() if err != nil { logger.Error(errors.New("WebPay err")) RespJson(c, status.InternalServerError, nil) return } ret := map[string]interface{}{ "web_pay": webPay, "order_id": order.ID, "order": order, } RespOK(c, ret) //RespOK(c, order) return } // 订单支付 // 暂时只支持积分支付, 以后再考虑人民币支付 func MallOrderPay(c *gin.Context) { req := struct { OrderId uint32 `json:"order_id" binding:"required"` }{} if err := c.ShouldBindJSON(&req); err != nil { logger.Error(err) RespJson(c, status.BadRequest, nil) return } uc := auth.GetCurrentUser(c) if uc == nil { RespJson(c, status.Unauthorized, nil) return } // 订单是否存在 var order model.GoodsOrder err := model.NewGoodsOrderQuerySet(model.DB). OrderIdEq(req.OrderId). UidEq(uc.Uid). One(&order) if err != nil { logger.Error("err:", err) RespJson(c, status.BadRequest, nil) return } // 订单状态不可以支付 if order.PayStatus != model.PayStatusInit { logger.Error("err:", err) RespJson(c, status.BadRequest, nil) return } tx := model.TransactionBegin() // TODO 减少库存 // TODO 确认下是在支付后减少,还是下单后? // TODO 减少用户积分 // 更新支付状态 err = model.NewGoodsOrderQuerySet(tx). OrderIdEq(req.OrderId). VersionIdEq(order.VersionId). GetUpdater(). SetPayStatus(model.PayStatusOK). SetVersionId(order.VersionId + 1). Update() if err != nil { logger.Error("err:", err) tx.Rollback() RespJson(c, status.BadRequest, nil) return } tx.Commit() RespOK(c, nil) return } func MallOrderList(c *gin.Context) { req := model.GoodsOrderListReq{} if err := c.ShouldBindJSON(&req); err != nil { logger.Error(err) RespJson(c, status.BadRequest, nil) return } uc := auth.GetCurrentUser(c) if uc == nil { RespJson(c, status.Unauthorized, nil) return } list, total, err := req.OrderList(uc.Uid) if err != nil { logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } ret := map[string]interface{}{ "list": list, "cur_page": req.PageIdx, "total_page": total, } RespOK(c, ret) return } func MallOrderDetail(c *gin.Context) { req := model.GoodsOrderDetailReq{} if err := c.ShouldBindJSON(&req); err != nil { logger.Error(err) RespJson(c, status.BadRequest, nil) return } uc := auth.GetCurrentUser(c) if uc == nil { RespJson(c, status.Unauthorized, nil) return } detail, err := req.OrderDetail(uc.Uid) if err != nil { logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } RespOK(c, detail) return } func MallUserVmRecord(c *gin.Context) { req := model.MallUserVmRecordReq{} if err := c.ShouldBindJSON(&req); err != nil { logger.Error(err) RespJson(c, status.BadRequest, nil) return } uc := auth.GetCurrentUser(c) if uc == nil { RespJson(c, status.Unauthorized, nil) return } list, total, err := req.UserVmRecordList(uc.Uid) if err != nil { logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } ret := map[string]interface{}{ "list": list, "cur_page": req.PageIdx, "total_page": total, } RespOK(c, ret) return } func MallGoodsOrderConfirmReceipt(c *gin.Context) { req := model.MallGoodsOrderConfirmReceiptReq{} if err := c.ShouldBindJSON(&req); err != nil { logger.Error(err) RespJson(c, status.BadRequest, nil) return } uc := auth.GetCurrentUser(c) if uc == nil { RespJson(c, status.Unauthorized, nil) return } err := req.MallGoodsOrderConfirmReceipt(uc.Uid) if err != nil { logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } RespOK(c, nil) return }