268 lines
5.7 KiB
Go
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
|
||
|
}
|