2022-01-16 08:56:33 +00:00
|
|
|
|
package controller
|
|
|
|
|
|
|
|
|
|
import (
|
2024-09-14 09:37:22 +00:00
|
|
|
|
"fmt"
|
2022-01-16 08:56:33 +00:00
|
|
|
|
"github.com/codinl/go-logger"
|
|
|
|
|
"github.com/gin-gonic/gin"
|
2025-09-11 10:06:20 +00:00
|
|
|
|
"github.com/pkg/errors"
|
2022-05-28 06:18:27 +00:00
|
|
|
|
"github.com/rs/zerolog/log"
|
2022-01-16 08:56:33 +00:00
|
|
|
|
"mh-server/lib/auth"
|
|
|
|
|
"mh-server/lib/status"
|
2022-05-28 06:18:27 +00:00
|
|
|
|
"mh-server/lib/utils"
|
2022-03-07 06:14:05 +00:00
|
|
|
|
"mh-server/lib/wxpay"
|
2022-01-16 08:56:33 +00:00
|
|
|
|
"mh-server/model"
|
2024-09-14 09:37:22 +00:00
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
2022-01-16 08:56:33 +00:00
|
|
|
|
)
|
|
|
|
|
|
2025-09-02 06:30:21 +00:00
|
|
|
|
// MallGoodsList 商品列表
|
|
|
|
|
// @Summary 商品列表
|
|
|
|
|
// @Tags 商城, V1.4.5
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Param request body model.GoodsListReq true "新建商品列表模型"
|
|
|
|
|
// @Success 200 {object} model.GoodsListResp
|
|
|
|
|
// @Router /api/v1/mall/goods/list [post]
|
2022-01-16 08:56:33 +00:00
|
|
|
|
func MallGoodsList(c *gin.Context) {
|
|
|
|
|
req := model.GoodsListReq{}
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
logger.Error(err)
|
|
|
|
|
RespJson(c, status.BadRequest, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
if req.NearestStoreId != 0 {
|
|
|
|
|
if store, err := model.GetStore(req.NearestStoreId); err != nil || store == nil {
|
|
|
|
|
RespJson(c, status.BadRequest, "未查询到门店信息")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-16 08:56:33 +00:00
|
|
|
|
list, total, err := req.GoodsList()
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("err:", err)
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
2023-09-20 10:05:53 +00:00
|
|
|
|
var ids []uint32
|
|
|
|
|
for _, goods := range list {
|
|
|
|
|
ids = append(ids, goods.GoodsId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(ids) > 0 {
|
|
|
|
|
cm := model.GetGoodsFirstSkuCombo(ids)
|
|
|
|
|
if cm != nil {
|
|
|
|
|
for j, combo := range cm {
|
|
|
|
|
for i, goods := range list {
|
|
|
|
|
if combo.GoodsId == goods.GoodsId {
|
|
|
|
|
list[i].Combo = &cm[j]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-01-16 08:56:33 +00:00
|
|
|
|
|
2025-09-02 06:30:21 +00:00
|
|
|
|
ret := model.GoodsListResp{
|
|
|
|
|
List: list,
|
|
|
|
|
CurPage: req.PageIdx,
|
|
|
|
|
TotalPage: total,
|
2022-01-16 08:56:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 02:54:02 +00:00
|
|
|
|
cm := model.GetGoodsFirstSkuCombo([]uint32{detail.GoodsId})
|
|
|
|
|
if len(cm) > 0 {
|
|
|
|
|
detail.Combo = &cm[0]
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-16 08:56:33 +00:00
|
|
|
|
RespOK(c, detail)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-14 09:37:22 +00:00
|
|
|
|
// GetCombinedCouponCode 定义一个函数来根据 number 和 couponType 组合结果
|
|
|
|
|
func GetCombinedCouponCode(goods *model.Goods, attribute *model.GoodsAttribute) (uint32, error) {
|
|
|
|
|
// 确保 goods 和 attribute 以及 SpecValues 不为空
|
|
|
|
|
if goods == nil || attribute == nil || attribute.SpecValues == nil {
|
|
|
|
|
return 0, fmt.Errorf("goods or attribute or SpecValues is nil")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确定 goods.Name 中的数字
|
|
|
|
|
var number int
|
|
|
|
|
switch {
|
|
|
|
|
case strings.Contains(goods.Name, "100"):
|
|
|
|
|
number = 100
|
|
|
|
|
case strings.Contains(goods.Name, "50"):
|
|
|
|
|
number = 50
|
|
|
|
|
case strings.Contains(goods.Name, "20"):
|
|
|
|
|
number = 20
|
|
|
|
|
case strings.Contains(goods.Name, "10"):
|
|
|
|
|
number = 10
|
|
|
|
|
case strings.Contains(goods.Name, "5"):
|
|
|
|
|
number = 5
|
|
|
|
|
default:
|
|
|
|
|
return 0, fmt.Errorf("优惠券金额有误")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 遍历 SpecValues 查找匹配的 display_value
|
|
|
|
|
var couponType int
|
|
|
|
|
for _, specValue := range attribute.SpecValues {
|
|
|
|
|
if specValue == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
switch specValue.DisplayValue {
|
|
|
|
|
case "周边券":
|
|
|
|
|
couponType = 3
|
|
|
|
|
case "配件券":
|
|
|
|
|
couponType = 2
|
|
|
|
|
case "游戏券":
|
|
|
|
|
couponType = 1
|
|
|
|
|
default:
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if couponType == 0 {
|
|
|
|
|
return 0, fmt.Errorf("优惠券规格有误")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成对应的组合字符串
|
|
|
|
|
resultStr := fmt.Sprintf("%d%d", number, couponType)
|
|
|
|
|
|
|
|
|
|
// 将组合字符串转换为 uint32
|
|
|
|
|
result, err := strconv.ParseUint(resultStr, 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, fmt.Errorf("转换为 uint32 时出错: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return uint32(result), nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
//type MallOrderCreateReq struct {
|
|
|
|
|
// 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"` // 购买数量
|
|
|
|
|
// AddressId uint32 `json:"address_id"` // 收货地址
|
|
|
|
|
// DeliveryExtraInfo string `json:"delivery_extra_info"` // 收货备注
|
|
|
|
|
// CouponCode string `json:"coupon_code"` // 优惠券券码
|
|
|
|
|
// NearestStoreId uint32 `json:"nearest_store_id"` // 定位最近的门店id
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//// MallOrderCreate 新建商城订单
|
|
|
|
|
//// @Summary 新建商城订单
|
|
|
|
|
//// @Tags 商城, V1.4.5
|
|
|
|
|
//// @Produce json
|
|
|
|
|
//// @Accept json
|
|
|
|
|
//// @Param request body MallOrderCreateReq true "新建商城订单模型"
|
|
|
|
|
//// @Success 200 {object} RespRet
|
|
|
|
|
//// @Router /api/v1/mall/order/create [post]
|
|
|
|
|
//func MallOrderCreate(c *gin.Context) {
|
|
|
|
|
// req := MallOrderCreateReq{}
|
|
|
|
|
// 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
|
|
|
|
|
// }
|
|
|
|
|
// 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)
|
|
|
|
|
// 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
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// 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
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 判断商品是否为erp同步商品,如果是则直接使用erp库存
|
|
|
|
|
// if goods.ErpCommodityId != 0 { // 是erp同步的商品
|
|
|
|
|
// // 查询库存是否充足
|
|
|
|
|
// var count int64
|
|
|
|
|
// err = model.DB.Table("erp_stock_commodity").Where("state = 1 and erp_commodity_id = ?",
|
|
|
|
|
// goods.ErpCommodityId).Count(&count).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// log.Error().Msgf("query erp_stock_commodity err:%#v", err)
|
|
|
|
|
// RespJson(c, status.OrderStockOut, "查询商品库存失败")
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if uint32(count) < req.Quantity {
|
|
|
|
|
// logger.Error("count < req.Quantity:", count, req.Quantity)
|
|
|
|
|
// RespJson(c, status.OrderStockOut, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
// } else {
|
|
|
|
|
// // 库存不足
|
|
|
|
|
// if attribute.Stock < req.Quantity {
|
|
|
|
|
// logger.Error("err:", err)
|
|
|
|
|
// RespJson(c, status.OrderStockOut, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 如果不是发放优惠券,需要判断用户地址
|
|
|
|
|
// if !(strings.Contains(goods.Name, "优惠券") || strings.Contains(goods.Name, "预售")) {
|
|
|
|
|
// // 检测收货地址是否正确
|
|
|
|
|
// count, _ := model.NewUserAddressQuerySet(model.DB).UidEq(uc.Uid).IDEq(req.AddressId).Count()
|
|
|
|
|
// if count != 1 {
|
|
|
|
|
// logger.Error("err:", err)
|
|
|
|
|
// RespJson(c, status.BadRequest, "收货地址错误")
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 判断是否已经购买或使用过新机预售券
|
|
|
|
|
// if strings.Contains(goods.Name, "预售") {
|
|
|
|
|
// var newMachineCoupon model.UserCoupon
|
|
|
|
|
// err = model.NewUserCouponQuerySet(model.DB).UidEq(user.Uid).ActivityIdEq(model.NewMachineActivityId).
|
|
|
|
|
// One(&newMachineCoupon)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// log.Error().Msgf("query newMachineCoupon err:%#v, code is:", err, req.CouponCode)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if newMachineCoupon.ID != 0 {
|
|
|
|
|
// RespJson(c, status.OutOffCouponLimit, "一个ID只能购买一张预售券")
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 查找用户优惠券,判断是否可用
|
|
|
|
|
// var userCoupon model.UserCoupon
|
|
|
|
|
// var coupon model.Coupon
|
|
|
|
|
// if req.CouponCode != "" {
|
|
|
|
|
// err = model.NewUserCouponQuerySet(model.DB).CodeEq(req.CouponCode).One(&userCoupon)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// log.Error().Msgf("query userCoupon err:%#v, code is:", err, req.CouponCode)
|
|
|
|
|
// } else {
|
|
|
|
|
// switch userCoupon.State {
|
|
|
|
|
// case 2: // 已使用
|
|
|
|
|
// log.Error().Msgf("优惠券已使用, code is:", req.CouponCode)
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// case 3: // 已过期
|
|
|
|
|
// log.Error().Msgf("优惠券已过期, code is:", req.CouponCode)
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// }
|
|
|
|
|
// if userCoupon.ActivityId != model.NewMachineActivityId {
|
|
|
|
|
// log.Error().Msgf("优惠券类型与商品不匹配, code is:", req.CouponCode)
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// model.NewCouponQuerySet(model.DB).ActivityIdEq(userCoupon.ActivityId).One(&coupon)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 读取折扣(是否有会员折扣)
|
|
|
|
|
// 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
|
|
|
|
|
// if combo.PriceVm > 0 && user.UserVm.Vm < totalVm {
|
|
|
|
|
// log.Error().Msgf("vm not enough")
|
|
|
|
|
// RespJson(c, status.UserVmNotEnough, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// totalRm := (combo.PriceRm*req.Quantity*discount + 5) / model.Rmb
|
|
|
|
|
// couponDiscount := userCoupon.Value
|
|
|
|
|
// if totalRm < couponDiscount {
|
|
|
|
|
// log.Error().Msgf("coupon value[%d] is err, code is:", couponDiscount, req.CouponCode)
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 开启事务
|
|
|
|
|
// tx := model.TransactionBegin()
|
|
|
|
|
// // 订单创建逻辑
|
|
|
|
|
// order := model.GoodsOrder{
|
|
|
|
|
// OrderId: model.CreateGoodsOrderId(),
|
|
|
|
|
// SerialNo: model.CreateGoodsOrderSerialNo(),
|
|
|
|
|
// Uid: uc.Uid,
|
|
|
|
|
// GoodsId: req.GoodsId,
|
|
|
|
|
// Rm: totalRm - couponDiscount,
|
|
|
|
|
// Vm: totalVm,
|
|
|
|
|
// Quantity: req.Quantity,
|
|
|
|
|
// 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,
|
|
|
|
|
// CouponDiscount: userCoupon.Value,
|
|
|
|
|
// CouponCode: userCoupon.Code,
|
|
|
|
|
// CouponName: coupon.Name,
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // 如果商品人民币价格为0,则是积分兑换
|
|
|
|
|
// if combo.PriceRm == 0 {
|
|
|
|
|
// order.PayTime = time.Now()
|
|
|
|
|
// order.PayStatus = model.PayStatusOK
|
|
|
|
|
// order.State = model.GoodsOrderStateOnDeliver
|
|
|
|
|
//
|
|
|
|
|
// // 如果发放的是优惠券,则默认为用户已收货
|
|
|
|
|
// if strings.Contains(goods.Name, "优惠券") {
|
|
|
|
|
// order.State = model.GoodsOrderStateReceived
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// err = order.Create(tx)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("err:", err)
|
|
|
|
|
// tx.Rollback()
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// err = model.OrderUpdateGoodsStock(req.GoodsAttributeId, 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.Vm)*-1, model.VmEventBuyGoods, "购买商品积分抵扣")
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// tx.Rollback()
|
|
|
|
|
// logger.Error("err:", err)
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if strings.Contains(goods.Name, "优惠券") {
|
|
|
|
|
// // 发放优惠券:判断优惠券金额和种类
|
|
|
|
|
// err = json.Unmarshal([]byte(attribute.SpecValueList), &attribute.SpecValues)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// log.Error().Msgf("spec value err:%#v", err)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// nActivityType, err := GetCombinedCouponCode(&goods, &attribute)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("GetCombinedCouponCode err:", err)
|
|
|
|
|
// RespJson(c, status.NoSpecValue, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// var coupons []model.Coupon
|
|
|
|
|
// err = model.NewCouponQuerySet(model.DB).ActivityIdEq(model.VmActivityId).ActivityTypeEq(nActivityType).All(&coupons)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("coupons err:", err)
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// for i, _ := range coupons {
|
|
|
|
|
// couponCode, err := utils.GenerateRandomNumber19()
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("GenerateRandomNumber19err:", err)
|
|
|
|
|
// }
|
|
|
|
|
// userCoupon := &model.UserCoupon{
|
|
|
|
|
// Uid: user.Uid,
|
|
|
|
|
// CouponId: coupons[i].ID,
|
|
|
|
|
// CouponType: coupons[i].CouponType,
|
|
|
|
|
// ActivityType: coupons[i].ActivityType,
|
|
|
|
|
// ActivityId: coupons[i].ActivityId,
|
|
|
|
|
// Value: coupons[i].Value,
|
|
|
|
|
// State: 1,
|
|
|
|
|
// ActiveStart: time.Now(),
|
|
|
|
|
// ActiveEnd: time.Now().AddDate(0, 0, 7),
|
|
|
|
|
// UseTime: time.Time{},
|
|
|
|
|
// MemberLevel: coupons[i].MemberLevel,
|
|
|
|
|
// Approach: 0,
|
|
|
|
|
// PromotionalSales: 0,
|
|
|
|
|
// RedeemCode: "",
|
|
|
|
|
// CategoryNumber: coupons[i].CategoryNumber,
|
|
|
|
|
// Code: couponCode,
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// err = model.DB.Create(userCoupon).Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("user coupon err:", err)
|
|
|
|
|
// continue
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// err = tx.Commit().Error
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// tx.Rollback()
|
|
|
|
|
// logger.Error("err:", err)
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// sub := model.DeliverTaskSub{
|
|
|
|
|
// Uid: order.Uid,
|
|
|
|
|
// UserAddressId: order.AddressId,
|
|
|
|
|
// OrderType: 2,
|
|
|
|
|
// OrderId: order.OrderId,
|
|
|
|
|
// StoreId: 13,
|
|
|
|
|
// }
|
|
|
|
|
// err = sub.Add()
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error("deliver task sub add err:", err)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// 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
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// configInfo, err := model.PayConfigInfo()
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error(err)
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// err = model.UserOpenMemberRecord{Uid: uc.Uid, OpenNo: order.SerialNo, OrderId: order.OrderId, OrderType: 6, Attach: wxpay.WxPayBuyGoods}.Insert()
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// logger.Error(errors.New("WebPay err"))
|
|
|
|
|
// RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if goods.GoodsAccountNum == model.AccountForDw { // 迪为账户收费
|
|
|
|
|
// webPay, err := wxpay.WebPay(order.SerialNo, order.Rm, user.WxOpenID, "N", wxpay.WxPayBuyGoods, configInfo.NotifyUrl, true)
|
|
|
|
|
// 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)
|
|
|
|
|
// } else { // 其他则默认明慧河马付账户收费
|
|
|
|
|
// webPay, err := wxpay.HmJsPayUnifiedOrderForBuyGoods(order.SerialNo, order.Rm, user.WxOpenID, configInfo.NotifyUrl)
|
|
|
|
|
// 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)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
// MallOrderCreateReq 新建商城订单请求结构
|
2025-01-09 07:57:20 +00:00
|
|
|
|
type MallOrderCreateReq struct {
|
2025-09-11 10:06:20 +00:00
|
|
|
|
NearestStoreId uint32 `json:"nearest_store_id"` // 用户选择的门店ID
|
|
|
|
|
Commodities []struct {
|
|
|
|
|
GoodsId uint32 `json:"goods_id"`
|
|
|
|
|
Quantity uint32 `json:"quantity"`
|
|
|
|
|
GoodsAttributeId uint32 `json:"goods_attribute_id"`
|
|
|
|
|
GoodsAttributeComboId uint32 `json:"goods_attribute_combo_id"`
|
|
|
|
|
CouponCode string `json:"coupon_code"`
|
|
|
|
|
} `json:"commodities"`
|
|
|
|
|
AddressId uint32 `json:"address_id"`
|
|
|
|
|
DeliveryExtraInfo string `json:"delivery_extra_info"`
|
2025-01-09 07:57:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MallOrderCreate 新建商城订单
|
|
|
|
|
// @Summary 新建商城订单
|
|
|
|
|
// @Tags 商城, V1.4.5
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Accept json
|
2025-01-15 07:40:03 +00:00
|
|
|
|
// @Param request body MallOrderCreateReq true "新建商城订单模型"
|
|
|
|
|
// @Success 200 {object} RespRet
|
2025-01-09 07:57:20 +00:00
|
|
|
|
// @Router /api/v1/mall/order/create [post]
|
2022-01-16 08:56:33 +00:00
|
|
|
|
func MallOrderCreate(c *gin.Context) {
|
2025-01-09 07:57:20 +00:00
|
|
|
|
req := MallOrderCreateReq{}
|
2022-01-16 08:56:33 +00:00
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
|
|
|
logger.Error(err)
|
|
|
|
|
RespJson(c, status.BadRequest, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
if req.NearestStoreId == 0 {
|
|
|
|
|
RespJson(c, status.BadRequest, "请选择门店")
|
2022-01-16 08:56:33 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2025-09-11 10:06:20 +00:00
|
|
|
|
userStore, err := model.GetStore(req.NearestStoreId)
|
|
|
|
|
if err != nil || userStore == nil {
|
|
|
|
|
RespJson(c, status.BadRequest, "未查询到门店信息,请选择门店")
|
2022-01-16 08:56:33 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
uc := auth.GetCurrentUser(c)
|
|
|
|
|
if uc == nil {
|
|
|
|
|
RespJson(c, status.Unauthorized, nil)
|
2022-01-16 08:56:33 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
user := model.GetUserByUid(uc.Uid)
|
|
|
|
|
if err := user.SetVm(); err != nil {
|
|
|
|
|
log.Error().Msgf("set vm err:%#v", err)
|
2022-05-28 06:18:27 +00:00
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-08-29 10:33:35 +00:00
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
tx := model.TransactionBegin()
|
|
|
|
|
defer func() {
|
|
|
|
|
if r := recover(); r != nil {
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
logger.Error("panic occurred:", r)
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
2025-08-29 10:33:35 +00:00
|
|
|
|
}
|
2025-09-11 10:06:20 +00:00
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
var erpCommodities []model.GoodsOrderCommodity
|
|
|
|
|
var onlineCommodities []model.GoodsOrderCommodity
|
2025-08-29 10:33:35 +00:00
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// ⚡ 记录全局收款账户(初始化为 0)
|
|
|
|
|
var orderAccountNum uint32
|
|
|
|
|
// 全局支付类型:0-未定,1-RMB,2-VM
|
|
|
|
|
var paymentType int = 0
|
|
|
|
|
|
|
|
|
|
// 先检查库存 + 收款账户一致性
|
|
|
|
|
for _, item := range req.Commodities {
|
|
|
|
|
var goods model.Goods
|
|
|
|
|
if err := model.NewGoodsQuerySet(model.DB).GoodsIdEq(item.GoodsId).One(&goods); err != nil {
|
|
|
|
|
RespJson(c, status.BadRequest, fmt.Sprintf("商品ID %d 不存在", item.GoodsId))
|
2025-08-29 10:33:35 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2025-09-11 10:06:20 +00:00
|
|
|
|
|
|
|
|
|
if goods.SaleStatus != model.SaleStatusYes {
|
|
|
|
|
RespJson(c, status.GoodsNotSale, fmt.Sprintf("商品 %s 不在售", goods.Name))
|
2025-08-29 10:33:35 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2022-01-16 08:56:33 +00:00
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// ---------- 支付方式检查 (来自 Goods 表) ----------
|
|
|
|
|
var itemPayType int
|
|
|
|
|
if goods.PriceRm != 0 && goods.PriceVm == 0 {
|
|
|
|
|
itemPayType = 1 // RMB
|
|
|
|
|
} else if goods.PriceVm != 0 && goods.PriceRm == 0 {
|
|
|
|
|
itemPayType = 2 // VM
|
|
|
|
|
} else {
|
|
|
|
|
RespJson(c, status.BadRequest, fmt.Sprintf("商品 %s 支付配置错误(PriceRm/PriceVm 必须且仅有一个非0)", goods.Name))
|
2024-09-14 09:37:22 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2025-09-11 10:06:20 +00:00
|
|
|
|
if paymentType == 0 {
|
|
|
|
|
paymentType = itemPayType
|
|
|
|
|
} else if paymentType != itemPayType {
|
|
|
|
|
RespJson(c, status.BadRequest, "不能混合使用人民币和积分购买,请分开下单")
|
|
|
|
|
return
|
2025-01-22 09:21:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// ⚡ 收款账户检查
|
|
|
|
|
if orderAccountNum == 0 {
|
|
|
|
|
orderAccountNum = goods.GoodsAccountNum
|
|
|
|
|
} else if orderAccountNum != goods.GoodsAccountNum {
|
|
|
|
|
RespJson(c, status.BadRequest, "下单失败:多个商品收款账户不一致,请分开下单")
|
2025-01-22 09:21:33 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
if goods.ErpCommodityId != 0 {
|
|
|
|
|
// ERP商品检查指定门店库存
|
|
|
|
|
var count int64
|
|
|
|
|
if err := model.DB.Table("erp_stock_commodity").
|
|
|
|
|
Where("state = 1 AND erp_commodity_id = ? AND store_id = ?", goods.ErpCommodityId, req.NearestStoreId).
|
|
|
|
|
Count(&count).Error; err != nil {
|
|
|
|
|
RespJson(c, status.OrderStockOut, "查询ERP库存失败")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if uint32(count) < item.Quantity {
|
|
|
|
|
RespJson(c, status.OrderStockOut, fmt.Sprintf("商品 %s 在当前门店库存不足", goods.Name))
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-01-09 07:57:20 +00:00
|
|
|
|
} else {
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 线上商品检查本地库存
|
|
|
|
|
var attribute model.GoodsAttribute
|
|
|
|
|
if err := model.NewGoodsAttributeQuerySet(model.DB).IDEq(item.GoodsAttributeId).One(&attribute); err != nil {
|
2025-01-09 07:57:20 +00:00
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
2025-09-11 10:06:20 +00:00
|
|
|
|
return
|
2025-01-09 07:57:20 +00:00
|
|
|
|
}
|
2025-09-11 10:06:20 +00:00
|
|
|
|
if attribute.Stock < item.Quantity {
|
|
|
|
|
RespJson(c, status.OrderStockOut, fmt.Sprintf("商品 %s 库存不足", goods.Name))
|
|
|
|
|
return
|
2025-01-09 07:57:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-28 06:18:27 +00:00
|
|
|
|
}
|
2025-01-09 07:57:20 +00:00
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 创建订单对象(只创建一次)
|
2022-01-16 08:56:33 +00:00
|
|
|
|
order := model.GoodsOrder{
|
2025-01-09 07:57:20 +00:00
|
|
|
|
OrderId: model.CreateGoodsOrderId(),
|
|
|
|
|
SerialNo: model.CreateGoodsOrderSerialNo(),
|
2025-09-11 10:06:20 +00:00
|
|
|
|
NearestStoreId: req.NearestStoreId,
|
|
|
|
|
NearestStoreName: userStore.Name,
|
2025-01-09 07:57:20 +00:00
|
|
|
|
Uid: uc.Uid,
|
2022-05-28 06:18:27 +00:00
|
|
|
|
PayStatus: model.PayStatusInit,
|
|
|
|
|
AddressId: req.AddressId,
|
|
|
|
|
DeliveryExtraInfo: req.DeliveryExtraInfo,
|
|
|
|
|
DeliveryStatus: model.DeliveryStatusUnDeliver,
|
2025-09-11 10:06:20 +00:00
|
|
|
|
GoodsOrderCommodities: []model.GoodsOrderCommodity{},
|
2022-05-28 06:18:27 +00:00
|
|
|
|
State: model.GoodsOrderStateUnPay,
|
2025-09-11 10:06:20 +00:00
|
|
|
|
TotalDiscount: 0,
|
2022-01-16 08:56:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
var totalVm, totalRm float64
|
2022-05-28 06:18:27 +00:00
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
for _, item := range req.Commodities {
|
|
|
|
|
// 商品是否存在
|
|
|
|
|
var goods model.Goods
|
|
|
|
|
if err := model.NewGoodsQuerySet(model.DB).GoodsIdEq(item.GoodsId).One(&goods); err != nil {
|
2022-03-26 03:25:15 +00:00
|
|
|
|
tx.Rollback()
|
2025-09-11 10:06:20 +00:00
|
|
|
|
RespJson(c, status.BadRequest, fmt.Sprintf("商品ID %d 不存在", item.GoodsId))
|
2022-03-26 03:25:15 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 获取商品属性
|
|
|
|
|
var attribute model.GoodsAttribute
|
|
|
|
|
if err := model.NewGoodsAttributeQuerySet(model.DB).IDEq(item.GoodsAttributeId).One(&attribute); err != nil {
|
2022-03-26 03:25:15 +00:00
|
|
|
|
tx.Rollback()
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 收货地址检查
|
|
|
|
|
if !(strings.Contains(goods.Name, "优惠券") || strings.Contains(goods.Name, "预售")) {
|
|
|
|
|
count, _ := model.NewUserAddressQuerySet(model.DB).UidEq(user.Uid).IDEq(req.AddressId).Count()
|
|
|
|
|
if count != 1 {
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
RespJson(c, status.BadRequest, "收货地址错误")
|
2024-09-14 09:37:22 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2025-09-11 10:06:20 +00:00
|
|
|
|
}
|
2024-09-14 09:37:22 +00:00
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 预售券限制
|
|
|
|
|
if strings.Contains(goods.Name, "预售") {
|
|
|
|
|
var newMachineCoupon model.UserCoupon
|
|
|
|
|
_ = model.NewUserCouponQuerySet(model.DB).UidEq(user.Uid).ActivityIdEq(model.NewMachineActivityId).One(&newMachineCoupon)
|
|
|
|
|
if newMachineCoupon.ID != 0 {
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
RespJson(c, status.OutOffCouponLimit, "一个ID只能购买一张预售券")
|
2024-09-14 09:37:22 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2025-09-11 10:06:20 +00:00
|
|
|
|
}
|
2024-09-14 09:37:22 +00:00
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 用户优惠券
|
|
|
|
|
var userCoupon model.UserCoupon
|
|
|
|
|
var coupon model.Coupon
|
|
|
|
|
if item.CouponCode != "" {
|
|
|
|
|
_ = model.NewUserCouponQuerySet(model.DB).CodeEq(item.CouponCode).One(&userCoupon)
|
|
|
|
|
if userCoupon.ID != 0 {
|
|
|
|
|
model.NewCouponQuerySet(model.DB).ActivityIdEq(userCoupon.ActivityId).One(&coupon)
|
2024-09-14 09:37:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 会员折扣
|
|
|
|
|
discount, _ := goods.GetUserDiscount(user)
|
|
|
|
|
|
|
|
|
|
// 套餐信息
|
|
|
|
|
var combo model.GoodsAttributeCombo
|
|
|
|
|
if err := model.NewGoodsAttributeComboQuerySet(model.DB).IDEq(item.GoodsAttributeComboId).One(&combo); err != nil {
|
2022-03-26 03:25:15 +00:00
|
|
|
|
tx.Rollback()
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
2022-06-03 03:30:03 +00:00
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 金额计算
|
|
|
|
|
vm := combo.PriceVm * item.Quantity
|
|
|
|
|
rm := (combo.PriceRm * item.Quantity) * discount
|
|
|
|
|
if rm < userCoupon.Value {
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
RespJson(c, status.InternalServerError, "优惠券金额大于订单金额")
|
|
|
|
|
return
|
2022-06-03 03:30:03 +00:00
|
|
|
|
}
|
2025-09-11 10:06:20 +00:00
|
|
|
|
|
|
|
|
|
totalVm += float64(vm)
|
|
|
|
|
totalRm += float64(rm) - float64(userCoupon.Value)
|
|
|
|
|
// 2) 支付方式全局校验:如果是 VM 支付,则用户积分总额是否足够
|
|
|
|
|
if paymentType == 2 {
|
|
|
|
|
// totalVm 是积分总数(以 combo.PriceVm 单位),比较 user.UserVm.Vm
|
|
|
|
|
if uint32(totalVm) > user.UserVm.Vm {
|
|
|
|
|
RespJson(c, status.UserVmNotEnough, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
2022-06-03 03:30:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 构建订单商品明细
|
|
|
|
|
orderCommodity := model.GoodsOrderCommodity{
|
|
|
|
|
GoodsId: item.GoodsId,
|
|
|
|
|
ErpCommodityId: goods.ErpCommodityId,
|
|
|
|
|
Quantity: item.Quantity,
|
|
|
|
|
PriceRm: combo.PriceRm,
|
|
|
|
|
PriceVm: combo.PriceVm,
|
|
|
|
|
Discount: discount,
|
|
|
|
|
GoodsAttributeId: item.GoodsAttributeId,
|
|
|
|
|
GoodsAttributeComboId: item.GoodsAttributeComboId,
|
|
|
|
|
CouponID: userCoupon.ID,
|
|
|
|
|
CouponCode: userCoupon.Code,
|
|
|
|
|
CouponName: coupon.Name,
|
|
|
|
|
CouponDiscount: userCoupon.Value,
|
2022-03-26 03:25:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
order.GoodsOrderCommodities = append(order.GoodsOrderCommodities, orderCommodity)
|
|
|
|
|
|
|
|
|
|
if goods.ErpCommodityId != 0 {
|
|
|
|
|
erpCommodities = append(erpCommodities, orderCommodity)
|
|
|
|
|
} else {
|
|
|
|
|
onlineCommodities = append(onlineCommodities, orderCommodity)
|
|
|
|
|
}
|
2022-03-26 03:25:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 订单总额
|
|
|
|
|
order.Vm = uint32(totalVm)
|
|
|
|
|
order.Rm = uint32(totalRm)
|
|
|
|
|
order.Amount = uint32(totalVm)
|
|
|
|
|
|
|
|
|
|
// 写入订单
|
|
|
|
|
if err := order.Create(tx); err != nil {
|
2022-03-26 03:25:15 +00:00
|
|
|
|
tx.Rollback()
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 批量写入商品明细
|
|
|
|
|
for i := range order.GoodsOrderCommodities {
|
|
|
|
|
order.GoodsOrderCommodities[i].GoodsOrderId = order.ID
|
|
|
|
|
if err := tx.Create(&order.GoodsOrderCommodities[i]).Error; err != nil {
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
RespJson(c, status.InternalServerError, fmt.Sprintf("写入商品明细失败: %v", err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 积分扣减
|
|
|
|
|
if paymentType == 2 && totalVm > 0 {
|
|
|
|
|
if err := model.UserVmUpdate(user.Uid, int(totalVm*-1), model.VmEventBuyGoods, "购买商品积分抵扣"); err != nil {
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理优惠券类商品直接发放
|
|
|
|
|
for _, com := range order.GoodsOrderCommodities {
|
|
|
|
|
var goods model.Goods
|
|
|
|
|
_ = model.NewGoodsQuerySet(model.DB).GoodsIdEq(com.GoodsId).One(&goods)
|
|
|
|
|
if strings.Contains(goods.Name, "优惠券") {
|
|
|
|
|
_ = model.NewGoodsOrderQuerySet(model.DB).IDEq(order.ID).GetUpdater().
|
|
|
|
|
SetState(model.GoodsOrderStateReceived).Update()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 记录用户会员购买信息
|
|
|
|
|
_ = model.UserOpenMemberRecord{
|
|
|
|
|
Uid: uc.Uid,
|
|
|
|
|
OpenNo: order.SerialNo,
|
|
|
|
|
OrderId: order.OrderId,
|
|
|
|
|
OrderType: 6,
|
|
|
|
|
Attach: wxpay.WxPayBuyGoods,
|
|
|
|
|
}.Insert()
|
|
|
|
|
|
|
|
|
|
// 提交事务
|
|
|
|
|
if err := tx.Commit().Error; err != nil {
|
2022-03-07 06:14:05 +00:00
|
|
|
|
tx.Rollback()
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
// 支付
|
2022-04-25 05:59:56 +00:00
|
|
|
|
configInfo, err := model.PayConfigInfo()
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(err)
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-01-09 07:57:20 +00:00
|
|
|
|
|
2025-09-11 10:06:20 +00:00
|
|
|
|
if orderAccountNum == model.AccountForDw { // 迪为账户收费
|
2025-01-15 07:40:03 +00:00
|
|
|
|
webPay, err := wxpay.WebPay(order.SerialNo, order.Rm, user.WxOpenID, "N", wxpay.WxPayBuyGoods, configInfo.NotifyUrl, true)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(errors.New("WebPay err"))
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
2022-03-07 06:14:05 +00:00
|
|
|
|
|
2025-01-15 07:40:03 +00:00
|
|
|
|
ret := map[string]interface{}{
|
|
|
|
|
"web_pay": webPay,
|
|
|
|
|
"order_id": order.ID,
|
|
|
|
|
"order": order,
|
|
|
|
|
}
|
2022-03-07 06:14:05 +00:00
|
|
|
|
|
2025-01-15 07:40:03 +00:00
|
|
|
|
RespOK(c, ret)
|
2025-05-30 01:51:36 +00:00
|
|
|
|
} else { // 其他则默认明慧河马付账户收费
|
|
|
|
|
webPay, err := wxpay.HmJsPayUnifiedOrderForBuyGoods(order.SerialNo, order.Rm, user.WxOpenID, configInfo.NotifyUrl)
|
2025-01-15 07:40:03 +00:00
|
|
|
|
if err != nil {
|
2025-09-11 10:06:20 +00:00
|
|
|
|
logger.Error(errors.New("HmPay err"))
|
2025-01-15 07:40:03 +00:00
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret := map[string]interface{}{
|
|
|
|
|
"web_pay": webPay,
|
|
|
|
|
"order_id": order.ID,
|
|
|
|
|
"order": order,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RespOK(c, ret)
|
|
|
|
|
}
|
2025-01-09 07:57:20 +00:00
|
|
|
|
|
2022-01-16 08:56:33 +00:00
|
|
|
|
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()
|
|
|
|
|
|
2022-04-21 09:03:33 +00:00
|
|
|
|
// 减少库存
|
|
|
|
|
// 确认下是在支付后减少,还是下单后?
|
|
|
|
|
// 减少用户积分
|
2022-01-16 08:56:33 +00:00
|
|
|
|
|
|
|
|
|
// 更新支付状态
|
|
|
|
|
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
|
|
|
|
|
}
|
2022-03-07 06:14:05 +00:00
|
|
|
|
|
2022-05-28 06:18:27 +00:00
|
|
|
|
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
|
|
|
|
|
}
|
2025-05-28 08:53:07 +00:00
|
|
|
|
|
2025-01-22 09:21:33 +00:00
|
|
|
|
if goodsOrder.Amount == 0 && goodsOrder.DeliverStoreId == 0 { // 新机预售券
|
|
|
|
|
// 查询新机预售券状态,只有未使用才能退
|
|
|
|
|
var newMachineCoupon model.UserCoupon
|
|
|
|
|
err = model.NewUserCouponQuerySet(model.DB).UidEq(goodsOrder.Uid).ActivityIdEq(model.NewMachineActivityId).
|
|
|
|
|
One(&newMachineCoupon)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(err)
|
|
|
|
|
RespJson(c, status.BadRequest, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch newMachineCoupon.State {
|
|
|
|
|
case 2:
|
|
|
|
|
RespJson(c, status.NewMachineCouponUsed, nil)
|
|
|
|
|
return
|
|
|
|
|
case 3:
|
|
|
|
|
RespJson(c, status.NewMachineCouponOutOfTime, nil)
|
|
|
|
|
return
|
|
|
|
|
case 4:
|
|
|
|
|
RespJson(c, status.NewMachineCouponDisabled, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
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
|
|
|
|
|
}
|
2022-05-28 06:18:27 +00:00
|
|
|
|
}
|
2025-01-22 09:21:33 +00:00
|
|
|
|
|
2022-05-28 06:18:27 +00:00
|
|
|
|
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
|
|
|
|
|
}
|
2025-01-22 09:21:33 +00:00
|
|
|
|
if goodsOrder.DeliverStoreId != 0 { // 线上购买预售券时没有发货门店
|
|
|
|
|
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
|
2022-05-28 06:18:27 +00:00
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
}
|
2025-05-28 08:53:07 +00:00
|
|
|
|
|
2022-05-28 06:18:27 +00:00
|
|
|
|
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 {
|
2024-09-14 09:37:22 +00:00
|
|
|
|
err = model.UserVmUpdate(goodsOrder.Uid, int(goodsOrder.Vm), model.VmEventBuyGoodsReject, "购买商品积分抵扣取消")
|
2022-05-28 06:18:27 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error("err:", err)
|
|
|
|
|
RespJson(c, status.InternalServerError, nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-03 03:30:03 +00:00
|
|
|
|
model.UpdateDeliverTaskSubStateCancel(goodsOrder.OrderId)
|
2022-05-28 06:18:27 +00:00
|
|
|
|
RespOK(c, "")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-14 09:37:22 +00:00
|
|
|
|
// MallUserVmRecord 用户积分记录
|
|
|
|
|
// @Summary 用户积分记录
|
|
|
|
|
// @Tags 用户信息
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Param request body model.MallUserVmRecordReq true "用户登陆模型"
|
|
|
|
|
// @Success 200 {object} model.MallUserVmRecordResp
|
|
|
|
|
// @Router /api/v1/mall/user/vm_record [post]
|
2022-03-07 06:14:05 +00:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-14 09:37:22 +00:00
|
|
|
|
ret := model.MallUserVmRecordResp{
|
|
|
|
|
List: list,
|
|
|
|
|
CurPage: req.PageIdx,
|
|
|
|
|
TotalPage: total,
|
2022-03-07 06:14:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
2022-05-28 06:18:27 +00:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|