mh_server/controller/mall.go
2022-04-25 13:59:56 +08:00

446 lines
9.8 KiB
Go

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"
"time"
)
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,
}
// 减少库存
// 确认下是在支付后减少,还是下单后
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
//}
}
if goods.DeliveryFee == 0 {
order.PayTime = time.Now()
order.PayStatus = model.PayStatusOK
//_, err := model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notify.OutTradeNo).GetUpdater().
// SetPayTime(time.Now()).
// SetPayStatus(model.PayStatusOK).UpdateNum()
//if err != nil {
// logger.Error("err:", err)
//}
//var goodsOrder model.GoodsOrder
//err = model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notify.OutTradeNo).One(&goodsOrder)
//if err != nil {
// logger.Error("err:", err)
//}
err = order.Create(tx)
if err != nil {
logger.Error("err:", err)
tx.Rollback()
RespJson(c, status.InternalServerError, nil)
return
}
err = model.OrderUpdateGoodsStock(order.GoodsId, order.Quantity, tx)
if err != nil {
tx.Rollback()
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
err = model.UserVmUpdate(order.Uid, int(order.Amount)*-1, model.VmEventExchangeGoods, "兑换奖品")
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
}
ret := map[string]interface{}{
"order_id": order.ID,
"order": order,
}
RespOK(c, ret)
return
}
err = order.Create(tx)
if err != nil {
logger.Error("err:", err)
tx.Rollback()
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
}
configInfo, err := model.PayConfigInfo()
if err != nil {
logger.Error(err)
RespJson(c, status.InternalServerError, nil)
return
}
webPay, err := wxpay.WebPay(order.SerialNo, goods.DeliveryFee, user.WxOpenID, "N", wxpay.WxPayExchangeGoods, configInfo.NotifyUrl)
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()
// 减少库存
// 确认下是在支付后减少,还是下单后?
// 减少用户积分
// 更新支付状态
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
}