This commit is contained in:
li 2022-05-28 14:18:27 +08:00
parent a3058af533
commit f807a5ed89
10 changed files with 8936 additions and 491 deletions

View File

@ -78,7 +78,12 @@ func GameCardInfo(c *gin.Context) {
return
}
go model.HistoryBrowsingAdd(uint64(uc.Uid), req.GameId)
go func() {
err := model.HistoryBrowsingAdd(uint64(uc.Uid), req.GameId)
if err != nil {
log.Error().Msgf("history browsing add err:%#v", err)
}
}()
info, err := model.GetGameCardInfo(req.GameId)
if err != nil {
@ -218,12 +223,7 @@ type (
}
)
const (
PRIZE_WX_PAY_TYPE = "pwxpt"
FB_WX_PAY_TYPE = "fbwxpt"
)
// 0 元购 微信推送支付通知
// 微信推送支付通知
func PushWXPayNotice(c *gin.Context) {
fmt.Println("微信推送支付通知")
body, err := ioutil.ReadAll(c.Request.Body)
@ -232,7 +232,7 @@ func PushWXPayNotice(c *gin.Context) {
}
logger.Error("xml Request.Body1:", string(body))
var notify wxpay.WechatNotifyInfo
var notifyInfo wxpay.WechatNotifyInfo
//if err := c.ShouldBindXML(&notify); err != nil {
// logger.Error(err)
// RespBodyXML(c, map[string]string{
@ -241,29 +241,29 @@ func PushWXPayNotice(c *gin.Context) {
// return
//}
err = xml.Unmarshal(body, &notify)
err = xml.Unmarshal(body, &notifyInfo)
if err != nil {
logger.Error(err)
}
ret := WXPayNoticeResp{
ReturnCode: "FAIL",
}
correctSign, err := PayCallBackHandle(notify, config.AppConfig.WxMchSecret)
correctSign, err := PayCallBackHandle(notifyInfo, config.AppConfig.WxMchSecret)
if err != nil {
logger.Error("PushWXPayNotice sign create fail")
RespBodyXML(c, ret)
return
}
if notify.Sign != correctSign {
if notifyInfo.Sign != correctSign {
logger.Error("PushWXPayNotice sign verification fail")
RespBodyXML(c, ret)
return
}
fundRecord := new(model.FundRecord)
if notify.Attach == wxpay.WxPayRentCard {
if notifyInfo.Attach == wxpay.WxPayRentCard {
logger.Info("租借游戏卡 支付成功:")
var order model.Order
err := model.NewOrderQuerySet(model.DB).OrderSnEq(notify.OutTradeNo).
err := model.NewOrderQuerySet(model.DB).OrderSnEq(notifyInfo.OutTradeNo).
PayStatusEq(PayStatusUnPay).CardStatusNe(OrderCardStatusCancel).One(&order)
if err != nil {
logger.Error("err:", err)
@ -295,7 +295,7 @@ func PushWXPayNotice(c *gin.Context) {
// 库存不足取消订单
orderSn := model.GetOrderSn()
memberRecord := &model.UserOpenMemberRecord{OpenNo: orderSn, OrderType: 2, Order: &order}
err = memberRecord.OrderRefund(notify.OutTradeNo)
err = memberRecord.OrderRefund(notifyInfo.OutTradeNo)
if err != nil {
logger.Error("err:", err)
return
@ -355,25 +355,17 @@ func PushWXPayNotice(c *gin.Context) {
fundRecord.Uid = uint32(order.Uid)
fundRecord.FundType = model.FundTypeExpressFee
fundRecord.Remark = "借卡邮费"
//count, err := model.NewOrderQuerySet(model.DB).UidEq(order.Uid).IDEq(order.ID).Count()
//if err != nil {
// logger.Error("err:", err)
// return
//}
//go model.OrderCardUserRentCard(uint32(order.Uid), uint32(count), nil)
} else if notify.Attach == wxpay.WxPayMember {
} else if notifyInfo.Attach == wxpay.WxPayMember {
logger.Info("开通会员 支付成功:")
logger.Info("用户uid:", notify.OutTradeNo)
logger.Info("用户uid:", notifyInfo.OutTradeNo)
//uid, err := strconv.Atoi(notify.OutTradeNo)
//if err != nil {
// logger.Error("err:", err)
// return
//}
record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo}
record := &model.UserOpenMemberRecord{OpenNo: notifyInfo.OutTradeNo}
err := record.GetByOpenNo()
if err != nil {
logger.Error("err:", err)
@ -506,14 +498,13 @@ func PushWXPayNotice(c *gin.Context) {
}
model.CreateUserRentCardByMemberLevel(record.Uid, record.MemberLevel, memberConfig.CardMax)
}
fmt.Println("notify.TotalFee:", notify.TotalFee)
fmt.Println("notify.OutTradeNo:", notify.OutTradeNo)
fmt.Println("notify.TotalFee:", notifyInfo.TotalFee)
fmt.Println("notify.OutTradeNo:", notifyInfo.OutTradeNo)
} else if notify.Attach == wxpay.WxPayDeposit {
record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo}
} else if notifyInfo.Attach == wxpay.WxPayDeposit {
record := &model.UserOpenMemberRecord{OpenNo: notifyInfo.OutTradeNo}
err := record.GetByOpenNo()
if err != nil {
logger.Error("err:", err)
@ -556,34 +547,36 @@ func PushWXPayNotice(c *gin.Context) {
if num == 0 {
logger.Error("update deposit num is 0")
}
} else if notify.Attach == wxpay.WxPayExchangeGoods {
_, err := model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notify.OutTradeNo).GetUpdater().
} else if notifyInfo.Attach == wxpay.WxPayBuyGoods {
_, err := model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notifyInfo.OutTradeNo).GetUpdater().
SetPayTime(time.Now()).
SetPayStatus(model.PayStatusOK).UpdateNum()
SetPayStatus(model.PayStatusOK).
SetState(model.GoodsOrderStateOnDeliver).UpdateNum()
if err != nil {
logger.Error("err:", err)
}
var goodsOrder model.GoodsOrder
err = model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notify.OutTradeNo).One(&goodsOrder)
err = model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notifyInfo.OutTradeNo).One(&goodsOrder)
if err != nil {
logger.Error("err:", err)
}
err = model.OrderUpdateGoodsStock(goodsOrder.GoodsId, goodsOrder.Quantity, model.DB)
err = model.OrderUpdateGoodsStock(goodsOrder.GoodsAttributeId, goodsOrder.Quantity, model.DB)
if err != nil {
logger.Error("err:", err)
}
err = model.UserVmUpdate(goodsOrder.Uid, int(goodsOrder.Amount)*-1, model.VmEventExchangeGoods, "兑换奖品")
err = model.UserVmUpdate(goodsOrder.Uid, int(goodsOrder.Vm)*-1, model.VmEventBuyGoods, "购买商品积分抵扣")
if err != nil {
logger.Error("err:", err)
}
fundRecord.Uid = uint32(goodsOrder.Uid)
fundRecord.FundType = model.FundTypeExpressFee
fundRecord.FundType = model.FundTypeBuyGoods
fundRecord.Remark = "积分兑换快递费"
} else if notify.Attach == wxpay.WxPayUpgradeMember {
record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo}
} else if notifyInfo.Attach == wxpay.WxPayUpgradeMember {
record := &model.UserOpenMemberRecord{OpenNo: notifyInfo.OutTradeNo}
err := record.GetByOpenNo()
if err != nil {
logger.Error("err:", err)
@ -628,8 +621,8 @@ func PushWXPayNotice(c *gin.Context) {
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypeUpgradeMember
fundRecord.Remark = "升级会员"
} else if notify.Attach == wxpay.WxPayMemberExpireDelay {
record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo}
} else if notifyInfo.Attach == wxpay.WxPayMemberExpireDelay {
record := &model.UserOpenMemberRecord{OpenNo: notifyInfo.OutTradeNo}
err := record.GetByOpenNo()
if err != nil {
logger.Error("err:", err)
@ -651,8 +644,8 @@ func PushWXPayNotice(c *gin.Context) {
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypeMemberExpireDelay
fundRecord.Remark = "会员过期滞纳金"
} else if notify.Attach == wxpay.WxPayShareCardRetrieve {
record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo}
} else if notifyInfo.Attach == wxpay.WxPayShareCardRetrieve {
record := &model.UserOpenMemberRecord{OpenNo: notifyInfo.OutTradeNo}
err := record.GetByOpenNo()
if err != nil {
logger.Error("err:", err)
@ -680,9 +673,9 @@ func PushWXPayNotice(c *gin.Context) {
fundRecord.Remark = "共享卡收回卡快递费"
}
fundRecord.Amount = int64(notify.TotalFee)
fundRecord.TransactionId = notify.TransactionId
fundRecord.OutTradeNo = notify.OutTradeNo
fundRecord.Amount = int64(notifyInfo.TotalFee)
fundRecord.TransactionId = notifyInfo.TransactionId
fundRecord.OutTradeNo = notifyInfo.OutTradeNo
fundRecord.Status = 2
err = model.DB.Create(&fundRecord).Error
if err != nil {

View File

@ -4,8 +4,10 @@ import (
"errors"
"github.com/codinl/go-logger"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
"mh-server/lib/auth"
"mh-server/lib/status"
"mh-server/lib/utils"
"mh-server/lib/wxpay"
"mh-server/model"
"time"
@ -57,9 +59,11 @@ func MallGoodsDetail(c *gin.Context) {
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"` // 支付方式
GoodsId uint32 `json:"goods_id" binding:"required"` // 商品id
GoodsAttributeId uint32 `json:"goods_attribute_id" binding:"required"` // 规格id
GoodsAttributeComboId uint32 `json:"goods_attribute_combo_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"` // 收货备注
}{}
@ -74,10 +78,16 @@ func MallOrderCreate(c *gin.Context) {
RespJson(c, status.Unauthorized, nil)
return
}
user := model.GetUserByUid(uc.Uid)
err := user.SetVm()
if err != nil {
log.Error().Msgf("set vm err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
// 商品是否存在
var goods model.Goods
err := model.NewGoodsQuerySet(model.DB).GoodsIdEq(req.GoodsId).One(&goods)
err = model.NewGoodsQuerySet(model.DB).GoodsIdEq(req.GoodsId).One(&goods)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.BadRequest, nil)
@ -91,8 +101,16 @@ func MallOrderCreate(c *gin.Context) {
return
}
var attribute model.GoodsAttribute
err = model.NewGoodsAttributeQuerySet(model.DB).IDEq(req.GoodsAttributeId).One(&attribute)
if err != nil {
log.Error().Msgf("attribute err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
// 库存不足
if goods.Stock < req.Quantity {
//if goods.Stock < req.Quantity {
if attribute.Stock < req.Quantity {
logger.Error("err:", err)
RespJson(c, status.OrderStockOut, nil)
return
@ -106,73 +124,89 @@ func MallOrderCreate(c *gin.Context) {
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
//// 计算总金额
//amount := uint32(0)
//if req.PayType == model.PayTypeRm {
// amount = req.Quantity * goods.PriceRm
//} else if req.PayType == model.PayTypeVm {
// amount = req.Quantity * goods.PriceVm
//}
discount, err := goods.GetUserDiscount(user)
if err != nil {
log.Error().Msgf("combo err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
var combo model.GoodsAttributeCombo
err = model.NewGoodsAttributeComboQuerySet(model.DB).IDEq(req.GoodsAttributeComboId).One(&combo)
if err != nil {
log.Error().Msgf("combo err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
totalVm := combo.PriceVm * req.Quantity
totalRm := (combo.PriceRm*req.Quantity*discount + 5) / model.Rmb
if combo.PriceVm > 0 && user.UserVm.Vm < totalVm {
log.Error().Msgf("vm not enough")
RespJson(c, status.UserVmNotEnough, nil)
return
}
// 开启事务
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,
OrderId: model.CreateGoodsOrderId(),
SerialNo: model.CreateGoodsOrderSerialNo(),
Uid: uc.Uid,
GoodsId: req.GoodsId,
Rm: totalRm,
Vm: totalVm,
Quantity: req.Quantity,
//PayType: req.PayType,
PayStatus: model.PayStatusInit,
AddressId: req.AddressId,
DeliveryExtraInfo: req.DeliveryExtraInfo,
DeliveryFee: goods.DeliveryFee,
DeliveryStatus: model.DeliveryStatusUnDeliver,
GoodsAttributeId: req.GoodsAttributeId,
GoodsAttributeComboId: req.GoodsAttributeComboId,
Discount: discount,
State: model.GoodsOrderStateUnPay,
}
// 减少库存
// 确认下是在支付后减少,还是下单后
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 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 {
//if goods.DeliveryFee == 0 {
if combo.PriceRm == 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)
//}
order.State = model.GoodsOrderStateOnDeliver
err = order.Create(tx)
if err != nil {
logger.Error("err:", err)
@ -181,7 +215,7 @@ func MallOrderCreate(c *gin.Context) {
return
}
err = model.OrderUpdateGoodsStock(order.GoodsId, order.Quantity, tx)
err = model.OrderUpdateGoodsStock(req.GoodsAttributeId, order.Quantity, tx)
if err != nil {
tx.Rollback()
logger.Error("err:", err)
@ -189,7 +223,7 @@ func MallOrderCreate(c *gin.Context) {
return
}
err = model.UserVmUpdate(order.Uid, int(order.Amount)*-1, model.VmEventExchangeGoods, "兑换奖品")
err = model.UserVmUpdate(order.Uid, int(order.Vm)*-1, model.VmEventBuyGoods, "购买商品积分抵扣")
if err != nil {
tx.Rollback()
logger.Error("err:", err)
@ -230,27 +264,28 @@ func MallOrderCreate(c *gin.Context) {
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
}
//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)
webPay, err := wxpay.WebPay(order.SerialNo, order.Rm, user.WxOpenID, "N",
wxpay.WxPayBuyGoods, 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()
err = model.UserOpenMemberRecord{Uid: uc.Uid, OpenNo: order.SerialNo, OrderId: order.OrderId, OrderType: 6}.Insert()
if err != nil {
logger.Error(errors.New("WebPay err"))
RespJson(c, status.InternalServerError, nil)
@ -388,6 +423,211 @@ func MallOrderDetail(c *gin.Context) {
return
}
func MallOrderRefund(c *gin.Context) {
req := struct {
GoodsOrderId uint32 `json:"goods_order_id"`
RefundReason string `json:"refund_reason"`
}{}
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
}
//model.GoodsOrder{}
var goodsOrder model.GoodsOrder
err := model.NewGoodsOrderQuerySet(model.DB).OrderIdEq(req.GoodsOrderId).One(&goodsOrder)
if err != nil {
log.Error().Msgf("goods order err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
if goodsOrder.CreatedAt.AddDate(0, 0, 15).Before(utils.Now()) ||
(!goodsOrder.ReceivedTime.IsZero() && goodsOrder.ReceivedTime.AddDate(0, 0, 7).Before(utils.Now())) {
log.Error().Msg("goods order refund exceed the time limit")
RespJson(c, status.InternalServerError, nil)
return
}
if goodsOrder.State != model.GoodsOrderStateDelivered &&
goodsOrder.State != model.GoodsOrderStateReceived &&
goodsOrder.State != model.GoodsOrderStateRefundedCancel {
log.Error().Msg("goods order state err")
RespJson(c, status.OrderDelivered, nil)
return
}
store, err := model.GetStore(goodsOrder.DeliverStoreId)
if err != nil {
log.Error().Msgf("get store err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
goodsOrder.DeliverStore = store
err = model.NewGoodsOrderQuerySet(model.DB).OrderIdEq(req.GoodsOrderId).GetUpdater().
SetRefundReason(req.RefundReason).SetState(model.GoodsOrderStateOnRefund).Update()
if err != nil {
log.Error().Msgf("update goods order err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
RespOK(c, goodsOrder)
return
}
func MallOrderRefundCancel(c *gin.Context) {
req := struct {
GoodsOrderId uint32 `json:"goods_order_id"`
}{}
if err := c.ShouldBindJSON(&req); err != nil {
logger.Error(err)
RespJson(c, status.BadRequest, nil)
return
}
var goodsOrder model.GoodsOrder
err := model.NewGoodsOrderQuerySet(model.DB).OrderIdEq(req.GoodsOrderId).One(&goodsOrder)
if err != nil {
log.Error().Msgf("goods order err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
if goodsOrder.State != model.GoodsOrderStateOnRefund {
log.Error().Msgf("state err")
RespJson(c, status.StateNotCancel, nil)
return
}
err = model.NewGoodsOrderQuerySet(model.DB).OrderIdEq(req.GoodsOrderId).GetUpdater().
SetState(model.GoodsOrderStateRefundedCancel).Update()
if err != nil {
log.Error().Msgf("update goods order err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
RespOK(c, nil)
return
}
func MallOrderRefundSend(c *gin.Context) {
req := struct {
GoodsOrderId uint32 `json:"goods_order_id"`
RefundExpressCompany string `json:"refund_express_company"` // 退货物流公司
RefundExpressCompanyNo string `json:"refund_express_company_no"` // 退货物流公司编号
RefundExpressNo string `json:"refund_express_no"` // 退货物流单号
}{}
if err := c.ShouldBindJSON(&req); err != nil {
logger.Error(err)
RespJson(c, status.BadRequest, nil)
return
}
var goodsOrder model.GoodsOrder
err := model.NewGoodsOrderQuerySet(model.DB).OrderIdEq(req.GoodsOrderId).One(&goodsOrder)
if err != nil {
log.Error().Msgf("goods order err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
if goodsOrder.State != model.GoodsOrderStateOnRefund {
log.Error().Msgf("state err")
RespJson(c, status.StateNotCancel, nil)
return
}
err = model.NewGoodsOrderQuerySet(model.DB).OrderIdEq(req.GoodsOrderId).GetUpdater().
SetRefundExpressNo(req.RefundExpressNo).
SetRefundExpressCompany(req.RefundExpressCompany).
SetRefundExpressCompanyNo(req.RefundExpressCompanyNo).Update()
if err != nil {
log.Error().Msgf("update goods order err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
RespOK(c, nil)
return
}
func MallOrderCancel(c *gin.Context) {
req := struct {
GoodsOrderId uint32 `json:"goods_order_id"`
}{}
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 goodsOrder model.GoodsOrder
err := model.NewGoodsOrderQuerySet(model.DB).OrderIdEq(req.GoodsOrderId).One(&goodsOrder)
if err != nil {
log.Error().Msgf("goods order err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
if goodsOrder.State != model.GoodsOrderStateOnDeliver {
log.Error().Msg("goods order state err")
RespJson(c, status.OrderDelivered, nil)
return
}
if goodsOrder.PayStatus != 2 {
log.Error().Msg("not pay")
RespJson(c, status.InternalServerError, nil)
return
}
if goodsOrder.Rm != 0 {
outTradeNo, err := model.GetWxPayExpressFeeRefundRecord(goodsOrder.OrderId)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
//m.OpenNo = model.GetOrderSn()
memberRecord := &model.UserOpenMemberRecord{OpenNo: model.GetOrderSn(), OrderType: 7, GoodsOrder: &goodsOrder}
err = memberRecord.MallGoodsOrderRefund(outTradeNo)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
}
//tx := model.DB.Begin()
err = model.NewGoodsOrderQuerySet(model.DB).OrderIdEq(req.GoodsOrderId).GetUpdater().
SetState(model.GoodsOrderStateCancel).Update()
if err != nil {
//tx.Rollback()
log.Error().Msgf("update goods order err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
//err = tx.Commit().Error
//if err != nil {
// tx.Rollback()
// log.Error().Msgf("commit err:%#v", err)
// RespJson(c, status.InternalServerError, nil)
// return
//}
if goodsOrder.Vm != 0 {
err = model.UserVmUpdate(goodsOrder.Uid, int(goodsOrder.Vm)*-1, model.VmEventBuyGoods, "购买商品积分抵扣取消")
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
}
RespOK(c, "")
return
}
func MallUserVmRecord(c *gin.Context) {
req := model.MallUserVmRecordReq{}
if err := c.ShouldBindJSON(&req); err != nil {
@ -443,3 +683,63 @@ func MallGoodsOrderConfirmReceipt(c *gin.Context) {
RespOK(c, nil)
return
}
func MallGoodsSpec(c *gin.Context) {
req := model.MallGoodsSpecReq{}
if err := c.ShouldBindJSON(&req); err != nil {
logger.Error(err)
RespJson(c, status.BadRequest, nil)
return
}
err := req.Spec()
if err != nil {
logger.Error("err:", err)
if err.Error() == "not_found" {
RespJson(c, status.OrderStockOut, nil)
return
}
RespJson(c, status.InternalServerError, nil)
return
}
RespOK(c, req.GoodsAttribute)
return
}
func MallGoodsCatList(c *gin.Context) {
var goodsCats []model.GoodsCat
err := model.DB.Table("goods_cat").Where("level=?", 1).Where("state=2").
Order("sort DESC").Find(&goodsCats).Error
if err != nil {
logger.Error("goods cat list err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
pids := make([]uint32, 0)
for i, _ := range goodsCats {
pids = append(pids, goodsCats[i].ID)
}
var subCat []model.GoodsCat
err = model.DB.Table("goods_cat").Where("pid in (?)", pids).Where("state=2").
Order("sort DESC").Find(&subCat).Error
if err != nil {
logger.Errorf("pCat err:%#v", err)
RespJson(c, status.InternalServerError, nil)
return
}
pCatMap := make(map[uint32][]model.GoodsCat, 0)
for i, _ := range subCat {
pCatMap[subCat[i].Pid] = append(pCatMap[subCat[i].Pid], subCat[i])
}
for i, _ := range goodsCats {
v, ok := pCatMap[goodsCats[i].ID]
if ok {
goodsCats[i].SubCats = v
}
}
RespOK(c, goodsCats)
return
}

View File

@ -101,6 +101,7 @@ const (
TodayAttendance = 500517 // 已签到
NoAuth = 500519 // 没有权限
GoodsNotSale = 500508 // 商品已下架
StateNotCancel = 500521 // 状态不能取消
ToastErr = 600 // 报错
)
@ -167,7 +168,8 @@ var statusDesc = map[int]string{
AwardOffShelves: "奖品已下架",
AwardExchangeOut: "奖品已兑完",
GoodsNotSale: "商品已下架",
GoodsNotSale: "商品已下架",
StateNotCancel: "状态不能取消",
NotMember: "非会员",
HadReceiveReward: "已经领取过了",
@ -235,6 +237,7 @@ var statusMsg = map[int]string{
PayStateIng: "支付中",
PayStateFail: "支付失败",
MoneySufficient: "余额不足",
UserVmNotEnough: "积分余额不足",
AwardOffShelves: "奖品已下架",
AwardExchangeOut: "奖品已兑完",

View File

@ -37,11 +37,12 @@ const (
WxPayMember = "member_pay" // 会员
WxPayRentCard = "rent_card_pay" // 租卡
WxPayDeposit = "deposit_pay" // 押金
WxPayExchangeGoods = "exchange_goods" // 兑换商品
WxPayBuyGoods = "buy_goods" // 购买商品
WxPayUpgradeMember = "upgrade_member" // 多级会员
WxPayMemberExpireDelay = "member_expire_delay" // 会员过期滞纳金
WxPayShareCardRetrieve = "share_card_retrieve" //
//WxPayExchangeGoods = "exchange_goods" // 兑换商品
//NotifyUrl = "https://switch.deovo.com:8001/api/v1/wxpay/notice" // 数据库配置 生产
//NotifyUrl = "https://dev.switch.deovo.com:8004/api/v1/wxpay/notice" // 测试
@ -251,6 +252,15 @@ type (
//CouponFee0 string `json:"coupon_fee_0"`
//CouponId0 string `json:"coupon_id_0"`
//<coupon_count><![CDATA[3]]></coupon_count>
//<coupon_fee>6000</coupon_fee>
//<coupon_fee_0><![CDATA[2000]]></coupon_fee_0>
//<coupon_fee_1><![CDATA[2000]]></coupon_fee_1>
//<coupon_fee_2><![CDATA[2000]]></coupon_fee_2>
//<coupon_id_0><![CDATA[34002152204]]></coupon_id_0>
//<coupon_id_1><![CDATA[34003509554]]></coupon_id_1>
//<coupon_id_2><![CDATA[34002433276]]></coupon_id_2>
CouponFee1 uint `xml:"coupon_fee_1,CDATA" json:"coupon_fee_1"`
CouponId1 string `xml:"coupon_id_1,CDATA" json:"coupon_id_1"`
CouponFee2 uint `xml:"coupon_fee_2,CDATA" json:"coupon_fee_2"`

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,16 @@
package model
import (
"encoding/json"
"errors"
"fmt"
"github.com/codinl/go-logger"
"github.com/jinzhu/gorm"
"github.com/rs/zerolog/log"
"mh-server/lib/utils"
"sort"
"strconv"
"strings"
"time"
)
@ -32,6 +38,9 @@ const (
DeliveryStatusDelivered // 2-已发货
DeliveryStatusHarvestGoods // 3-已收货
)
const (
Rmb = 100
)
// 商品
//go:generate goqueryset -in mall.go
@ -41,31 +50,126 @@ type Goods struct {
GoodsId uint32 `json:"goods_id" gorm:"unique_index"`
SerialNo string `json:"serial_no" gorm:"unique_index"` // 序列号
CatId uint32 `json:"cat_id"` // 分类
CatId uint32 `json:"cat_id" gorm:"index"` // 分类
Name string `json:"name"` // 名称
Title string `json:"title"` // 标题
MainImage string `json:"main_image"` // 主图
Images string `json:"images"` // 图片列表,用,隔开
Stock uint32 `json:"stock"` // 库存
Detail string `json:"detail" gorm:"type:text;"` // 详情, 富文本
//Stock uint32 `json:"stock"` // 库存
Detail string `json:"detail" gorm:"type:text;"` // 详情, 富文本
SoldCount uint32 `json:"sold_count"` // 已销售数量
SaleStatus uint32 `json:"sale_status"` // 在售状态 1-在售 2-下架
CatSort uint32 `json:"cat_sort"`
Sort uint32 `json:"sort"`
PriceVm uint32 `json:"price_vm"` // 积分价格
PriceRm uint32 `json:"price_rm"` // 人民币价格
SpecList string `json:"spec_list" gorm:"type:text;"` // 属性json数据
DiscountList string `json:"discount_list" gorm:"type:text;"` // 折扣
SpecIndex string `json:"spec_index" gorm:"index"` // 1_3
//PriceVm uint32 `json:"price_vm"` // 积分价格
//PriceRm uint32 `json:"price_rm"` // 人民币价格
PriceOriginal uint32 `json:"price_original"` // 市场价
DeliveryFee uint32 `json:"delivery_fee"` // 邮费
DealType uint32 `json:"deal_type"` // 1-积分兑换 2-购买 3-抵扣
VersionId uint64 `json:"version_id"` // 乐观锁
GoodsCat *GoodsCat `json:"goods_cat" gorm:"-"`
GoodsDiscount *GoodsDiscount `json:"goods_discount" gorm:"-"`
Attributes []GoodsAttribute `json:"attributes" gorm:"-"`
}
//// gen:qs
//type GoodsCat struct {
// gen:qs
type GoodsCat struct {
Model
Name string `json:"name"` // 名称
Priority string `json:"priority"` // 分类
State uint32 `json:"state"` // 1-未使用 2-使用
Level uint32 `json:"level"` // 分类层级
Pid uint32 `json:"pid" gorm:"index"`
Sort uint32 `json:"sort"`
SubCats []GoodsCat `json:"sub_cats" gorm:"-"` // 子列表
}
type GoodsDiscount struct {
Gold uint32 `json:"gold"` // 黄金折扣
Platinum uint32 `json:"platinum"` // 白金折扣
BlackGold uint32 `json:"black_gold"` // 黑金折扣
}
// gen:qs
type GoodsAttribute struct {
Model
GoodsId uint32 `json:"goods_id" gorm:"index"`
SerialNo string `json:"serial_no" gorm:"index"` // 序列号
CatId uint32 `json:"cat_id" gorm:"index"` // 分类
Name string `json:"name"` // 名称
Title string `json:"title"` // 标题
MainImage string `json:"main_image"` // 主图
Stock uint32 `json:"stock"` // 库存
SoldCount uint32 `json:"sold_count"` // 已销售数量
PriceRm uint32 `json:"price_rm"` // 人民币价格
PriceOriginal uint32 `json:"price_original"` // 市场价
SpecValueList string `json:"spec_value_list" gorm:"type:text;"` // 属性json数据
SpecValueIndex string `json:"spec_value_index" gorm:"index"` // 1_3_5
DealType uint32 `json:"deal_type"` // 1-积分兑换 2-购买 3-抵扣
SpecValues []*SpecValue `json:"spec_values" gorm:"-"`
Goods *Goods `json:"goods" gorm:"-"`
Combos []GoodsAttributeCombo `json:"combos" gorm:"-"`
Combo *GoodsAttributeCombo `json:"combo" gorm:"-"`
// goods_attribute
}
// gen:qs
type GoodsAttributeCombo struct {
Model
GoodsAttributeId uint32 `json:"goods_attribute_id" gorm:"index"`
GoodsId uint32 `json:"goods_id" gorm:"index"`
SerialNo string `json:"serial_no" gorm:"index"` // 序列号
CatId uint32 `json:"cat_id" gorm:"index"` // 分类
Name string `json:"name"` // 名称
Title string `json:"title"` // 标题
MainImage string `json:"main_image"` // 主图
ComboName string `json:"combo_name"` // 名称
PriceVm uint32 `json:"price_vm"` // 积分价格
PriceRm uint32 `json:"price_rm"` // 人民币价格
}
//type GoodsSpec struct {
// Model
// Color string `json:"color"`
//}
// gen:qs
type Spec struct {
Model
DisplayName string `json:"display_name" gorm:"unique_index"`
Name string `json:"name"`
State uint32 `json:"state"` // 1-未使用 2-使用
Sort uint32 `json:"sort"`
Values []SpecValue `json:"values" gorm:"-"`
}
// gen:qs
type SpecValue struct {
Model
SpecId uint32 `json:"spec_id" gorm:"index"`
SpecDisplayName string `json:"spec_display_name"`
SpecName string `json:"spec_name"`
DisplayValue string `json:"display_value" gorm:"unique_index"`
State uint32 `json:"state"` // 1-未使用 2-使用
Value string `json:"value"`
SpecSort uint32 `json:"spec_sort"`
Sort uint32 `json:"sort"`
}
func CreateGoodsSerialNo() string {
for {
serialNo := utils.GenSerialNo()
@ -87,8 +191,9 @@ func CreateGoodsId() uint32 {
}
type GoodsListReq struct {
PageIdx int `json:"page_idx"`
PageSize int `json:"page_size"`
CatId uint32 `json:"cat_id"`
PageIdx int `json:"page_idx"`
PageSize int `json:"page_size"`
}
func (m *GoodsListReq) GoodsList() ([]Goods, int, error) {
@ -99,8 +204,29 @@ func (m *GoodsListReq) GoodsList() ([]Goods, int, error) {
if m.PageSize == 0 {
m.PageSize = 10
}
fmt.Println("CatId:", m.CatId)
var goodsList []Goods
qs := NewGoodsQuerySet(DB).SaleStatusEq(1)
if m.CatId != 0 {
//cat, err := GetGoodsCat(m.CatId)
//if err != nil {
// log.Error().Msgf("cat err:%#v", err)
// return nil, 0, err
//}
var goodsCats []GoodsCat
err := NewGoodsCatQuerySet(DB).PidEq(m.CatId).All(&goodsCats)
if err != nil {
log.Error().Msgf("goods cat err:%#v", err)
return nil, 0, err
}
ids := []uint32{m.CatId}
if len(goodsCats) > 0 {
for i, _ := range goodsCats {
ids = append(ids, goodsCats[i].ID)
}
}
qs = qs.CatIdIn(ids...)
}
count, err := qs.Count()
if err != nil {
@ -109,7 +235,7 @@ func (m *GoodsListReq) GoodsList() ([]Goods, int, error) {
}
totalPage := count/m.PageSize + 1
err = qs.Offset(page * m.PageSize).Limit(m.PageSize).All(&goodsList)
err = qs.OrderDescByCatSort().OrderDescBySort().Offset(page * m.PageSize).Limit(m.PageSize).All(&goodsList)
if err != nil {
logger.Error("err:", err)
return nil, 0, err
@ -129,6 +255,31 @@ func (m *GoodsDetailReq) GoodsDetail() (*Goods, error) {
logger.Error("err:", err)
return nil, err
}
var goodsAttributes []GoodsAttribute
err = DB.Table("goods_attribute").Where("goods_id=?", m.GoodsId).
Find(&goodsAttributes).Error
if err != nil {
log.Error().Msgf("goods attribute err:%#v", err)
return &goods, err
}
if goods.DiscountList != "" {
discount := new(GoodsDiscount)
err = json.Unmarshal([]byte(goods.DiscountList), discount)
if err != nil {
log.Error().Msgf("goods discount err:%#v", err)
return &goods, err
}
goods.GoodsDiscount = discount
}
cat, err := GetGoodsCat(goods.CatId)
if err != nil {
log.Error().Msgf("goods cat err:%#v", err)
}
goods.GoodsCat = cat
GoodsAttributeListSetSpecValues(goodsAttributes)
GoodsAttributeListSetCombos(goodsAttributes)
goods.Attributes = goodsAttributes
return &goods, nil
}
@ -145,6 +296,17 @@ type GoodsCategory struct {
State uint32 `json:"state"`
}
const (
GoodsOrderStateUnPay = "un_pay" // 待付款
GoodsOrderStateOnDeliver = "on_deliver" // 待发货
GoodsOrderStateDelivered = "delivered" // 已发货
GoodsOrderStateReceived = "received" // 已收货
GoodsOrderStateCancel = "cancel" // 已取消
GoodsOrderStateOnRefund = "on_refund" // 退货中
GoodsOrderStateRefunded = "refunded" // 已退货
GoodsOrderStateRefundedCancel = "refunded_cancel" // 退货取消
)
// 商品订单
// gen:qs
type GoodsOrder struct {
@ -158,21 +320,37 @@ type GoodsOrder struct {
Amount uint32 `json:"amount"` // 订单金额
Quantity uint32 `json:"quantity"` // 购买商品的数量
PayType uint32 `json:"pay_type"` // 支付方式 1-rm 2-vm
PayTime time.Time `json:"pay_time"` // 支付时间
PayStatus uint32 `json:"pay_status"` // 支付状态 1-待支付 2-已支付 3-失败
PayType uint32 `json:"pay_type"` // 支付方式 1-rm 2-vm
PayTime time.Time `json:"pay_time"` // 支付时间
PayStatus uint32 `json:"pay_status"` // 支付状态 1-待支付 2-已支付 3-失败
State string `json:"state"` //
AddressId uint32 `json:"address_id"` // 收货地址
DeliveryExtraInfo string `json:"delivery_extra_info"` // 物流备注
DeliveryFee uint32 `json:"delivery_fee"` // 物流费用
DeliveryTrackingNo string `json:"delivery_tracking_no"` // 物流单号
DeliveryCompany string `json:"delivery_company"` // 物流公司
DeliveryCompanyNo string `json:"delivery_company_no"` // 物流公司编号
DeliveryStatus uint32 `json:"delivery_status"` // 物流状态 1-待发货 2-已发货 3-已收货
Rm uint32 `json:"rm"` //
Vm uint32 `json:"vm"` // 积分
Discount uint32 `json:"discount"` // 折扣
GoodsAttributeId uint32 `json:"goods_attribute_id"` //
GoodsAttributeComboId uint32 `json:"goods_attribute_combo_id"` //
AddressId uint32 `json:"address_id"` // 收货地址
DeliveryExtraInfo string `json:"delivery_extra_info"` // 物流备注
DeliveryFee uint32 `json:"delivery_fee"` // 物流费用
DeliveryTrackingNo string `json:"delivery_tracking_no"` // 物流单号
DeliveryCompany string `json:"delivery_company"` // 物流公司
DeliveryStatus uint32 `json:"delivery_status"` // 物流状态 1-待发货 2-已发货 3-已收货
DeliverStoreId uint32 `json:"deliver_store_id"` // 发货门店
DeliverTime time.Time `json:"deliver_time"` // 发货时间
RefundExpressCompany string `json:"refund_express_company"` // 退货物流公司
RefundExpressCompanyNo string `json:"refund_express_company_no"` // 退货物流公司编号
RefundExpressNo string `json:"refund_express_no"` // 退货物流单号
RefundReason string `json:"refund_reason" gorm:"type:text;"`
ReceivedTime time.Time `json:"received_time"` // 签收时间
VersionId uint64 `json:"version_id"` // 乐观锁
Goods *Goods `json:"goods" gorm:"-"`
UserAddress *UserAddress `json:"user_address" gorm:"-"`
Goods *Goods `json:"goods" gorm:"-"`
UserAddress *UserAddress `json:"user_address" gorm:"-"`
DeliverStore *Store `json:"deliver_store" gorm:"-"`
GoodsAttribute *GoodsAttribute `json:"goods_attribute" gorm:"-"`
}
func CreateGoodsOrderSerialNo() string {
@ -196,9 +374,10 @@ func CreateGoodsOrderId() uint32 {
}
type GoodsOrderListReq struct {
PageIdx int `json:"page_idx"`
PageSize int `json:"page_size"`
DeliveryStatus uint32 `json:"delivery_status"` // 物流状态 1-待发货 2-已发货 3-已收货
PageIdx int `json:"page_idx"`
PageSize int `json:"page_size"`
State string `json:"state"`
//DeliveryStatus uint32 `json:"delivery_status"` // 物流状态 1-待发货 2-已发货 3-已收货
}
func (m *GoodsOrderListReq) OrderList(uid uint32) ([]GoodsOrder, int, error) {
@ -211,13 +390,16 @@ func (m *GoodsOrderListReq) OrderList(uid uint32) ([]GoodsOrder, int, error) {
}
var list []GoodsOrder
qs := NewGoodsOrderQuerySet(DB).PayStatusEq(PayStatusOK)
qs := NewGoodsOrderQuerySet(DB).PayStatusEq(PayStatusOK).UidEq(uid)
if uid != 0 {
qs = qs.UidEq(uid)
}
if m.DeliveryStatus != 0 {
qs = qs.DeliveryStatusEq(m.DeliveryStatus)
//if uid != 0 {
// qs = qs.UidEq(uid)
//}
//if m.DeliveryStatus != 0 {
// qs = qs.DeliveryStatusEq(m.DeliveryStatus)
//}
if m.State != "" {
qs = qs.StateEq(m.State)
}
count, err := qs.Count()
if err != nil {
@ -232,7 +414,8 @@ func (m *GoodsOrderListReq) OrderList(uid uint32) ([]GoodsOrder, int, error) {
return nil, 0, err
}
list = GoodsOrderListSetGoods(list)
GoodsOrderListSetGoods(list)
GoodsOrderListSetAttribute(list)
return list, totalPage, nil
}
@ -243,21 +426,64 @@ type GoodsOrderDetailReq struct {
func (m *GoodsOrderDetailReq) OrderDetail(uid uint32) (*GoodsOrder, error) {
var order GoodsOrder
qs := NewGoodsOrderQuerySet(DB).OrderIdEq(m.OrderId)
qs := NewGoodsOrderQuerySet(DB).OrderIdEq(m.OrderId).UidEq(uid)
if uid != 0 {
qs = qs.UidEq(uid)
}
//if uid != 0 {
// qs = qs.UidEq(uid)
//}
err := qs.One(&order)
if err != nil && err != RecordNotFound {
logger.Error("err:", err)
return nil, err
}
orders := GoodsOrderListSetGoods([]GoodsOrder{order})
if len(orders) > 0 {
order.Goods = orders[0].Goods
//orders := []GoodsOrder{order}
//GoodsOrderListSetGoods(orders)
//if len(orders) > 0 {
// order.Goods = orders[0].Goods
//}
var goods Goods
err = NewGoodsQuerySet(DB).GoodsIdEq(order.GoodsId).One(&goods)
if err != nil {
logger.Error("err:", err)
return nil, err
}
var goodsAttribute GoodsAttribute
err = DB.Table("goods_attribute").Where("id=?", order.GoodsAttributeId).
Find(&goodsAttribute).Error
if err != nil {
log.Error().Msgf("goods attribute err:%#v", err)
return nil, err
}
if goods.DiscountList != "" {
discount := new(GoodsDiscount)
err = json.Unmarshal([]byte(goods.DiscountList), discount)
if err != nil {
log.Error().Msgf("goods discount err:%#v", err)
return nil, err
}
goods.GoodsDiscount = discount
}
//cat, err := GetGoodsCat(goods.CatId)
//if err != nil {
// log.Error().Msgf("goods cat err:%#v", err)
//}
//goods.GoodsCat = cat
attributes := []GoodsAttribute{goodsAttribute}
GoodsAttributeListSetSpecValues(attributes)
combo, err := GetCombo(order.GoodsAttributeComboId)
if err != nil {
log.Error().Msgf("goods attribute err:%#v", err)
return nil, err
}
if len(attributes) > 0 {
attributes[0].Combo = combo
}
//GoodsAttributeListSetCombos(attributes)
goods.Attributes = attributes
order.Goods = &goods
var userAddress UserAddress
err = NewUserAddressQuerySet(DB.Unscoped()).IDEq(order.AddressId).One(&userAddress)
if err != nil && err != RecordNotFound {
@ -293,8 +519,10 @@ func OrderDeductionUserVm(uid uint32, userVmAmount, vm int, gdb *gorm.DB) error
return nil
}
func OrderUpdateGoodsStock(goodsId, count uint32, gdb *gorm.DB) error {
sql := fmt.Sprintf("UPDATE goods SET stock=stock-%d,sold_count=sold_count+%d WHERE goods_id = %d", count, count, goodsId)
func OrderUpdateGoodsStock(attributeId, count uint32, gdb *gorm.DB) error {
sql := fmt.Sprintf("UPDATE goods_attribute SET stock=stock-%d,sold_count=sold_count+%d WHERE id=%d ",
count, count, attributeId)
err := gdb.Exec(sql).Error
if err != nil {
logger.Error("err:", err)
@ -321,9 +549,9 @@ func GetGoodsMapByIds(ids []uint32) map[uint32]Goods {
return goodsMap
}
func GoodsOrderListSetGoods(orders []GoodsOrder) []GoodsOrder {
func GoodsOrderListSetGoods(orders []GoodsOrder) {
if len(orders) == 0 {
return orders
return
}
ids := make([]uint32, 0, len(orders))
for i, _ := range orders {
@ -336,7 +564,47 @@ func GoodsOrderListSetGoods(orders []GoodsOrder) []GoodsOrder {
orders[i].Goods = &v
}
}
return orders
}
func GoodsOrderListSetAttribute(orders []GoodsOrder) {
if len(orders) == 0 {
return
}
ids := make([]uint32, 0, len(orders))
for i, _ := range orders {
ids = append(ids, orders[i].GoodsAttributeId)
}
attributeMap, err := GetGoodsAttributeMap(ids)
if err != nil {
log.Error().Msgf("attribute map err:%#v", err)
return
}
for i, _ := range orders {
v, ok := attributeMap[orders[i].GoodsAttributeId]
if ok {
orders[i].GoodsAttribute = &v
}
}
}
func GetGoodsAttributeMap(ids []uint32) (map[uint32]GoodsAttribute, error) {
attributeMap := make(map[uint32]GoodsAttribute, 0)
if len(ids) == 0 {
return attributeMap, nil
}
var attributes []GoodsAttribute
err := NewGoodsAttributeQuerySet(DB).IDIn(ids...).All(&attributes)
if err != nil {
log.Error().Msgf("goods attribute err:%#v", err)
return attributeMap, err
}
for i, _ := range attributes {
attributeMap[attributes[i].ID] = attributes[i]
}
return attributeMap, nil
}
type MallUserVmRecordReq struct {
@ -383,10 +651,192 @@ type MallGoodsOrderConfirmReceiptReq struct {
func (m *MallGoodsOrderConfirmReceiptReq) MallGoodsOrderConfirmReceipt(uid uint32) error {
_, err := NewGoodsOrderQuerySet(DB).OrderIdEq(m.OrderId).UidEq(uid).GetUpdater().
SetDeliveryStatus(DeliveryStatusHarvestGoods).UpdateNum()
SetState(GoodsOrderStateReceived).UpdateNum()
if err != nil {
logger.Error("err:", err)
return err
}
return nil
}
type MallGoodsSpecReq struct {
GoodsId uint32 `json:"goods_id"` // 商品id
SpecValueIndex string `json:"spec_value_index"` // 1,3,5
GoodsAttribute *GoodsAttribute
}
func (r *MallGoodsSpecReq) Spec() error {
//GoodsAttribute{}
indexSort, err := IndexSortString(r.SpecValueIndex)
if err != nil {
log.Error().Msgf("index sort:%#v", err)
return err
}
r.SpecValueIndex = indexSort
err = NewGoodsAttributeQuerySet(DB).GoodsIdEq(r.GoodsId).SpecValueIndexEq(r.SpecValueIndex).One(r.GoodsAttribute)
if err != nil && err != RecordNotFound {
log.Error().Msgf("goods attribute err:%#v", err)
return err
}
if err == RecordNotFound {
log.Error().Msg("goods attribute not found")
return errors.New("not_found")
}
var combos []GoodsAttributeCombo
err = NewGoodsAttributeComboQuerySet(DB).GoodsAttributeIdEq(r.GoodsAttribute.ID).All(&combos)
if err != nil {
log.Error().Msgf("goods attribute combo err:%#v", err)
return err
}
return nil
}
func IndexSortString(n string) (string, error) {
numStrings := strings.Split(n, ",")
nums := make([]int, 0, len(numStrings))
for i, _ := range numStrings {
num, err := strconv.Atoi(numStrings[i])
if err != nil {
logger.Error("num err:", err)
return "", err
}
nums = append(nums, num)
}
ns := ""
sort.Ints(nums)
for i, _ := range nums {
ns += fmt.Sprintf("%d,", nums[i])
}
return ns[:len(ns)-1], nil
}
func GetGoods(id uint32) (Goods, error) {
var goods Goods
err := NewGoodsQuerySet(DB).GoodsIdEq(id).One(&goods)
if err != nil {
log.Error().Msgf("get goods err:%#v", err)
return goods, err
}
return goods, err
}
func GetGoodsCat(id uint32) (*GoodsCat, error) {
var cat GoodsCat
err := DB.Table("goods_cat").Where("id=?", id).Find(&cat).Error
if err != nil {
log.Error().Msgf("goods cat err:%#v", err)
return &cat, err
}
if cat.Pid != 0 {
var pCat GoodsCat
err := DB.Table("goods_cat").Where("id=?", cat.Pid).Find(&pCat).Error
if err != nil {
log.Error().Msgf("goods cat err:%#v", err)
return &cat, err
}
pCat.SubCats = []GoodsCat{cat}
return &pCat, nil
}
return &cat, nil
}
func (g *Goods) SetDiscount() error {
discount := new(GoodsDiscount)
err := json.Unmarshal([]byte(g.DiscountList), discount)
if err != nil {
log.Error().Msgf("set goods discount:%#v", err)
return err
}
return nil
}
func (g *Goods) GetUserDiscount(u *User) (uint32, error) {
if g.GoodsDiscount == nil {
err := g.SetDiscount()
if err != nil {
log.Error().Msgf("set discount err:%#v", err)
return 100, err
}
}
switch u.MemberLevel {
case MemberLevelGold:
return g.GoodsDiscount.Gold, nil
case MemberLevelPlatinum:
return g.GoodsDiscount.Gold, nil
case MemberLevelBlackGold:
return g.GoodsDiscount.Gold, nil
}
//return 100, errors.New("member level err")
return 100, nil
}
func GoodsAttributeListSetSpecValues(attributes []GoodsAttribute) {
for i, _ := range attributes {
err := json.Unmarshal([]byte(attributes[i].SpecValueList), &attributes[i].SpecValues)
if err != nil {
log.Error().Msgf("spec value err:%#v", err)
continue
}
}
}
func GoodsAttributeListSetCombos(attributes []GoodsAttribute) {
ids := make([]uint32, 0)
for i, _ := range attributes {
ids = append(ids, attributes[i].ID)
}
comboMap := GetGoodsAttributeComboMap(ids)
for i, _ := range attributes {
v, ok := comboMap[attributes[i].ID]
if ok {
attributes[i].Combos = v
}
}
}
func GetGoodsAttributeComboMap(attributeIds []uint32) map[uint32][]GoodsAttributeCombo {
attributeMap := make(map[uint32][]GoodsAttributeCombo, 0)
if len(attributeIds) == 0 {
return attributeMap
}
var combos []GoodsAttributeCombo
err := DB.Table("goods_attribute_combo").Where("goods_attribute_id in (?)", attributeIds).
Find(&combos).Error
if err != nil {
log.Error().Msgf("goods attribute combo err:%#v", err)
return attributeMap
}
for i, _ := range combos {
attributeMap[combos[i].GoodsAttributeId] =
append(attributeMap[combos[i].GoodsAttributeId], combos[i])
}
return attributeMap
}
func GetCombo(id uint32) (*GoodsAttributeCombo, error) {
var combo GoodsAttributeCombo
err := NewGoodsAttributeComboQuerySet(DB).IDEq(id).One(&combo)
if err != nil {
log.Error().Msgf("goods attribute combo err:%#v", err)
return &combo, err
}
return &combo, nil
}
func GetStore(id uint32) (*Store, error) {
var store Store
err := NewStoreQuerySet(DB).IDEq(id).One(&store)
if err != nil {
log.Error().Msgf("store err:%#v", err)
return nil, err
}
return &store, nil
}

View File

@ -6,6 +6,8 @@ import (
"fmt"
"mh-server/lib/auth"
"mh-server/lib/utils"
"sort"
"strconv"
//"github.com/andreburgaud/crypt2go/ecb"
//"github.com/andreburgaud/crypt2go/padding"
@ -75,17 +77,6 @@ func InitTestDB() {
db.SingularTable(true)
db.AutoMigrate(
Article{},
ArticleCollect{},
ArticleTitlePanel{},
CannibalizeGameCardGoods{},
CannibalizeStockTask{},
CardIssueFeedback{},
Collection{},
CommonProblem{},
Config{},
CooperativeBusiness{},
//&GameCard{},
//&FundRecord{},
//&User{},
@ -114,6 +105,14 @@ func InitTestDB() {
//&CooperativeDeductSettle{},
//&XcxRole{},
&Goods{},
&GoodsCat{},
&GoodsAttribute{},
&GoodsAttributeCombo{},
&Spec{},
&SpecValue{},
&GoodsOrder{},
&OperationLog{},
)
fmt.Println("DB init success")
@ -125,7 +124,7 @@ func TestInitTestDBModel(t *testing.T) {
InitTestDB()
}
func TestMemberExprireTime(t *testing.T) {
func TestMemberExpireTime(t *testing.T) {
InitTestDB()
}
@ -149,52 +148,52 @@ func InitDBProd() {
DBProd.LogMode(false)
DBProd.SingularTable(true)
DBProd.AutoMigrate(
//&RedeemCode{},
//&UserRedeemCode{},
//&GameCardGoods{},
//
//&UserShareCardBill{},
//&ShareCardBillGame{},
//&UserShareCard{},
//&ShareCardVmRecord{},
//&UserShareCardVm{},
//&ShareCardDateVm{},
//&ShareCardGameVm{},
//&ShareCardRetrieve{},
//&ShareCardRetrieveCard{},
//&GameCardLabel{},
//&CardIssueFeedback{},
//&RedeemCode{},
//&UserRedeemCode{},
//&GameCardGoods{},
//
//&UserShareCardBill{},
//&ShareCardBillGame{},
//&UserShareCard{},
//&ShareCardVmRecord{},
//&UserShareCardVm{},
//&ShareCardDateVm{},
//&ShareCardGameVm{},
//&ShareCardRetrieve{},
//&ShareCardRetrieveCard{},
//&GameCardLabel{},
//&CardIssueFeedback{},
//&GameCard{},
//&FundRecord{},
//&User{},
//&GameCard{},
//&FundRecord{},
//&User{},
//&GameCard{},
//&FundRecord{},
//&User{},
//&UserAttendance{},
//&UserAttendanceRecord{},
//&GameCard{},
//&FundRecord{},
//&User{},
//&UserAttendance{},
//&UserAttendanceRecord{},
&Store{},
&GameCard{},
&GameCardGoods{},
&GameCardGoodsStock{},
&User{},
&Order{},
&OrderCard{},
&OperationLog{},
&CooperativeBusiness{},
&CooperativeMemberDeduct{},
&CooperativeAssistantMemberDeduct{},
&CooperativeMemberPromotion{},
&CooperativeMemberPromotionStore{},
&CooperativeMemberPromotionDay{},
&CooperativeMemberPromotionStoreDay{},
&InviteMemberReport{},
&CooperativeDeductSettle{},
&XcxRole{},
//&Store{},
//&GameCard{},
//&GameCardGoods{},
//&GameCardGoodsStock{},
//&User{},
//&Order{},
//&OrderCard{},
//
//&OperationLog{},
//&CooperativeBusiness{},
//&CooperativeMemberDeduct{},
//&CooperativeAssistantMemberDeduct{},
//
//&CooperativeMemberPromotion{},
//&CooperativeMemberPromotionStore{},
//&CooperativeMemberPromotionDay{},
//&CooperativeMemberPromotionStoreDay{},
//&InviteMemberReport{},
//&CooperativeDeductSettle{},
//&XcxRole{},
)
if err := DBProd.DB().Ping(); err != nil {
@ -631,19 +630,19 @@ func GoodsAdd() {
InitTestDB()
for i := 0; i < 5; i++ {
goods := Goods{
GoodsId: 1 + uint32(i) + 1,
SerialNo: "sdhfjskdhjk" + fmt.Sprintf("%d", i+1),
CatId: 1,
Name: "宝可梦剑" + fmt.Sprintf("%d", i+1),
Title: "宝可梦剑",
MainImage: "https://minghui-oss.oss-cn-shenzhen.aliyuncs.com/eceec8e0-da21-11eb-8936-197fd3ba503d.jpg",
Images: "https://minghui-oss.oss-cn-shenzhen.aliyuncs.com/eceec8e0-da21-11eb-8936-197fd3ba503d.jpg",
Stock: 10,
Detail: "宝可梦剑 详情" + fmt.Sprintf("%d", i+1),
SoldCount: 0,
SaleStatus: 1,
PriceVm: 10 + uint32(i),
PriceRm: 29900,
GoodsId: 1 + uint32(i) + 1,
SerialNo: "sdhfjskdhjk" + fmt.Sprintf("%d", i+1),
CatId: 1,
Name: "宝可梦剑" + fmt.Sprintf("%d", i+1),
Title: "宝可梦剑",
MainImage: "https://minghui-oss.oss-cn-shenzhen.aliyuncs.com/eceec8e0-da21-11eb-8936-197fd3ba503d.jpg",
Images: "https://minghui-oss.oss-cn-shenzhen.aliyuncs.com/eceec8e0-da21-11eb-8936-197fd3ba503d.jpg",
//Stock: 10,
Detail: "宝可梦剑 详情" + fmt.Sprintf("%d", i+1),
SoldCount: 0,
SaleStatus: 1,
//PriceVm: 10 + uint32(i),
//PriceRm: 29900,
PriceOriginal: 29900,
DeliveryFee: 1000,
VersionId: 0,
@ -1310,3 +1309,37 @@ func TestUpdateUid(t *testing.T) {
}
}
func TestStringSort(t *testing.T) {
idx := "1,20,14,7"
////list := strings.Split(idx, ",")
////sort.Strings(list)
////fmt.Println("list:", list)
stringSort, err := NumStringSort(idx)
if err != nil {
fmt.Println("err:", err)
}
fmt.Println("stringSort:", stringSort)
}
func NumStringSort(n string) (string, error) {
numStrings := strings.Split(n, ",")
nums := make([]int, 0, len(numStrings))
for i, _ := range numStrings {
num, err := strconv.Atoi(numStrings[i])
if err != nil {
logger.Error("num err:", err)
return "", err
}
nums = append(nums, num)
}
ns := ""
sort.Ints(nums)
for i, _ := range nums {
ns += fmt.Sprintf("%d,", nums[i])
}
return ns[:len(ns)-1], nil
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"github.com/codinl/go-logger"
"github.com/jinzhu/gorm"
"github.com/rs/zerolog/log"
"mh-server/lib/utils"
"mh-server/lib/wxpay"
"sync"
@ -128,6 +129,8 @@ const (
FundTypeMemberExpireDelay = "member_expire_delay" // 滞纳金
FundTypeDepositRefund = "deposit_refund" // 退押金
FundTypeExpressFeeRefund = "express_fee_refund" // 退邮费
FundTypeBuyGoods = "buy_goods" // 购买商品
)
// gen:qs
@ -236,6 +239,8 @@ func UserUpdate(user *User) error {
return nil
}
//OrderType: 1-物流支付 2-取消物流租卡 3-滞纳金 4-收回卡 5-退物流费 6-商城购物 7-购买商品取消订单
// gen:qs
type UserOpenMemberRecord struct {
Model
@ -243,12 +248,14 @@ type UserOpenMemberRecord struct {
Uid uint32 `json:"uid" gorm:"index"`
OpenNo string `json:"open_no" gorm:"index"`
OrderId uint32 `json:"order_id" gorm:"index"`
OrderType uint32 `json:"order_type"` // 1-物流支付 2-取消物流租卡 3-滞纳金 4-收回卡 5-退物流费
OrderType uint32 `json:"order_type"`
MemberLevel uint32 `json:"member_level"`
MemberExpire time.Time `json:"member_expire"` // 会员到期时间
//Attach string `json:"attach"`
Order *Order `json:"order" gorm:"-"`
ShareCardRetrieve *ShareCardRetrieve `json:"share_card_retrieve" gorm:"-"`
GoodsOrder *GoodsOrder `json:"goods_order" gorm:"-"`
//Attach string `json:"attach"`
}
func (o *UserOpenMemberRecord) TableName() string {
@ -277,7 +284,8 @@ const (
// gen:qs
type OperationLog struct {
Model
Uid uint32 `json:"uid" gorm:"index"` // 店员id
Uid uint32 `json:"uid" gorm:"index"` // 店员id
SysUid uint32 `json:"sys_uid" gorm:"index"`
Description string `json:"description"` // 描述
OperationType string `json:"operation_type" gorm:"index"` // 操作类型
CorrelationId uint32 `json:"correlation_id" gorm:"index"` // 关联id
@ -310,6 +318,25 @@ func (m *UserOpenMemberRecord) OrderRefund(outTradeNo string) error {
return nil
}
func (m *UserOpenMemberRecord) MallGoodsOrderRefund(outTradeNo string) error {
if m.GoodsOrder == nil {
return errors.New("goods order is nil")
}
if m.OpenNo == "" {
m.OpenNo = GetOrderSn()
}
m.Uid = uint32(m.GoodsOrder.Uid)
m.OrderId = m.GoodsOrder.ID
err := m.Refund(outTradeNo, m.GoodsOrder.Rm)
if err != nil {
logger.Error("refund err:", err)
return err
}
return nil
}
// gen:qs
type InviteMemberReport struct {
Model
@ -639,8 +666,10 @@ func (m *User) Edit() {
func GetWxPayExpressFeeRefundRecord(orderId uint32) (string, error) {
var openMemberRecord UserOpenMemberRecord
//err := NewUserOpenMemberRecordQuerySet(DB).OrderIdEq(orderId).OrderTypeEq(1).OrderDescByID().Limit(1).One(&openMemberRecord)
err := NewUserOpenMemberRecordQuerySet(DB).OrderIdEq(orderId).OrderDescByID().Limit(1).One(&openMemberRecord)
//err := NewUserOpenMemberRecordQuerySet(DB).OrderIdEq(orderId).OrderTypeEq(1).
//OrderDescByID().Limit(1).One(&openMemberRecord)
err := NewUserOpenMemberRecordQuerySet(DB).OrderIdEq(orderId).OrderDescByID().
Limit(1).One(&openMemberRecord)
if err != nil {
logger.Error("err:", err)
return "", err
@ -936,3 +965,14 @@ func GetUserMap(ids []uint32) (map[uint32]*User, error) {
}
return userMap, nil
}
func (u *User) SetVm() error {
var userVm UserVm
err := NewUserVmQuerySet(DB).UidEq(u.Uid).One(&userVm)
if err != nil {
log.Error().Msgf("UserVm err:%#v", err)
return err
}
u.UserVm = &userVm
return nil
}

View File

@ -7,7 +7,8 @@ import (
)
const (
VmEventExchangeGoods = "exchange_goods"
//VmEventExchangeGoods = "exchange_goods"
VmEventBuyGoods = "buy_goods"
VmEventOpenMember = "open_member"
VmEventInvite1Member = "invite_1_member"
VmEventInvite2Member = "invite_2_member"

View File

@ -170,6 +170,8 @@ func ConfigAppRouter(r gin.IRouter) {
{
mall.POST("goods/list", controller.MallGoodsList) // 商品-列表
mall.POST("goods/detail", controller.MallGoodsDetail) // 商品-详情
mall.POST("goods/spec", controller.MallGoodsSpec) // 商品-规格
mall.POST("cat/list", controller.MallGoodsCatList) // 商品-分类列表
mall.Use(auth.UserAccessAuth)
mall.POST("order/create", controller.MallOrderCreate) // 订单-创建(下单)
@ -178,6 +180,11 @@ func ConfigAppRouter(r gin.IRouter) {
mall.POST("order/detail", controller.MallOrderDetail) // 订单-详情
mall.POST("user/vm_record", controller.MallUserVmRecord) // 用户-积分记录
mall.POST("order/confirm_receipt", controller.MallGoodsOrderConfirmReceipt) // 用户-确认收货
mall.POST("order/cancel", controller.MallOrderCancel) // 订单-取消
mall.POST("order/refund", controller.MallOrderRefund) // 订单-退货
mall.POST("order/refund_cancel", controller.MallOrderRefundCancel) // 订单-退货-取消
mall.POST("order/refund_send", controller.MallOrderRefundSend) // 订单-退货-填物流
}
shoppingCart := api.Group("shopping_cart")
{