mh_server/controller/mall.go
2022-01-16 16:56:33 +08:00

268 lines
5.7 KiB
Go

package controller
import (
"github.com/codinl/go-logger"
"github.com/gin-gonic/gin"
"mh-server/lib/auth"
"mh-server/lib/status"
"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.OrderUnpaidDeposit, 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,
}
err = order.Create(tx)
if err != nil {
logger.Error("err:", err)
tx.Rollback()
RespJson(c, status.InternalServerError, nil)
return
}
// TODO 减少库存
// TODO 确认下是在支付后减少,还是下单后?
tx.Commit()
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
}