mh_server/model/mall.go

1158 lines
32 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"encoding/json"
"errors"
"fmt"
"github.com/codinl/go-logger"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"github.com/rs/zerolog/log"
"mh-server/lib/utils"
"net/url"
"sort"
"strconv"
"strings"
"time"
)
const (
SaleStatusUnknown = iota
SaleStatusYes
SaleStatusNo
)
const (
PayTypeUnknown = iota
PayTypeRm // 人民币
PayTypeVm // 积分
)
const (
PayStatusUnknown = iota
PayStatusInit
PayStatusOK
PayStatusFail
)
const (
DeliveryStatusUnknown = iota
DeliveryStatusUnDeliver // 1-待发货
DeliveryStatusDelivered // 2-已发货
DeliveryStatusHarvestGoods // 3-已收货
)
const (
Rmb = 100
)
// 商品
// gen:qs
//
//go:generate goqueryset -in mall.go
type Goods struct {
Model
GoodsId uint32 `json:"goods_id" gorm:"unique_index"`
SerialNo string `json:"serial_no" gorm:"unique_index"` // 序列号
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;"` // 详情, 富文本
SoldCount uint32 `json:"sold_count"` // 已销售数量
SaleStatus uint32 `json:"sale_status"` // 在售状态 1-在售 2-下架
CatSort uint32 `json:"cat_sort"`
Sort uint32 `json:"sort"`
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"` // 乐观锁
ShowDiscount int8 `json:"show_discount"` //
GoodsCat *GoodsCat `json:"goods_cat" gorm:"-"`
GoodsDiscount *GoodsDiscount `json:"goods_discount" gorm:"-"`
Attributes []GoodsAttribute `json:"attributes" gorm:"-"`
Combo *GoodsAttributeCombo `json:"combo" gorm:"-"`
}
// 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
//}
// 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()
if count, err := NewGoodsQuerySet(DB).SerialNoEq(serialNo).Count(); err == nil && count > 0 {
continue
}
return serialNo
}
}
func CreateGoodsId() uint32 {
for {
orderId := utils.GenUid()
if count, err := NewGoodsQuerySet(DB).GoodsIdEq(orderId).Count(); err == nil && count > 0 {
continue
}
return orderId
}
}
type GoodsListReq struct {
CatId uint32 `json:"cat_id"`
PageIdx int `json:"page_idx"`
PageSize int `json:"page_size"`
}
func (m *GoodsListReq) GoodsList() ([]Goods, int, error) {
page := m.PageIdx - 1
if page < 0 {
page = 0
}
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 {
logger.Error("err:", err)
return nil, 0, err
}
totalPage := count/m.PageSize + 1
err = qs.OrderDescByCatSort().OrderDescBySort().Offset(page * m.PageSize).Limit(m.PageSize).All(&goodsList)
if err != nil {
logger.Error("err:", err)
return nil, 0, err
}
return goodsList, totalPage, nil
}
type GoodsDetailReq struct {
GoodsId uint32 `json:"goods_id"`
}
func (m *GoodsDetailReq) GoodsDetail() (*Goods, error) {
var goods Goods
err := NewGoodsQuerySet(DB).GoodsIdEq(m.GoodsId).One(&goods)
if err != nil {
logger.Error("err:", err)
return nil, err
}
var goodsAttributes []GoodsAttribute
err = DB.Table("goods_attribute").
Where("goods_id=?", m.GoodsId).
Order("sort DESC").
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
}
// 商品分类
// gen:qs
type GoodsCategory struct {
Model
CatId uint32 `json:"cat_id"`
ParentCatId uint32 `json:"parent_cat_id"`
Name string `json:"name"`
Sort uint32 `json:"sort"` // 排序
Level uint32 `json:"level"`
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 {
Model
OrderId uint32 `json:"order_id" gorm:"unique_index"` // 订单 id
SerialNo string `json:"serial_no" gorm:"unique_index"` // 序列号
Uid uint32 `json:"uid" gorm:"index"`
GoodsId uint32 `json:"goods_id" gorm:"index"` // 商品id
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-失败
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"` //
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:"-"`
DeliverStore *Store `json:"deliver_store" gorm:"-"`
GoodsAttribute *GoodsAttribute `json:"goods_attribute" gorm:"-"`
}
func CreateGoodsOrderSerialNo() string {
for {
serialNo := utils.GenSerialNo()
if count, err := NewGoodsOrderQuerySet(DB).SerialNoEq(serialNo).Count(); err == nil && count > 0 {
continue
}
return serialNo
}
}
func CreateGoodsOrderId() uint32 {
for {
orderId := utils.GenUid()
if count, err := NewGoodsOrderQuerySet(DB).OrderIdEq(orderId).Count(); err == nil && count > 0 {
continue
}
return orderId
}
}
type GoodsOrderListReq struct {
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) {
page := m.PageIdx - 1
if page < 0 {
page = 0
}
if m.PageSize == 0 {
m.PageSize = 10
}
var list []GoodsOrder
qs := NewGoodsOrderQuerySet(DB).PayStatusEq(PayStatusOK).UidEq(uid)
//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 {
logger.Error("err:", err)
return nil, 0, err
}
totalPage := count/m.PageSize + 1
err = qs.OrderDescByID().Offset(page * m.PageSize).Limit(m.PageSize).All(&list)
if err != nil {
logger.Error("err:", err)
return nil, 0, err
}
GoodsOrderListSetGoods(list)
GoodsOrderListSetAttribute(list)
return list, totalPage, nil
}
type GoodsOrderDetailReq struct {
OrderId uint32 `json:"order_id"`
}
func (m *GoodsOrderDetailReq) OrderDetail(uid uint32) (*GoodsOrder, error) {
var order GoodsOrder
qs := NewGoodsOrderQuerySet(DB).OrderIdEq(m.OrderId).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 := []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 {
logger.Error("err:", err)
return nil, err
}
order.UserAddress = &userAddress
store, err := GetStore(order.DeliverStoreId)
if err != nil {
logger.Error("store err:", err)
}
order.DeliverStore = store
return &order, nil
}
func OrderDeductionUserVm(uid uint32, userVmAmount, vm int, gdb *gorm.DB) error {
sql := fmt.Sprintf("UPDATE user_vm SET vm = vm+? WHERE uid=? ")
err := gdb.Exec(sql, vm, uid).Error
if err != nil {
logger.Error("err:", err)
return err
}
vmRecord := &UserVmRecord{
Uid: uid,
BeforeVm: uint32(userVmAmount),
AfterVm: uint32(int(userVmAmount) + vm),
Alter: vm,
Event: "exchange_goods",
Describe: "兑换礼品",
}
err = gdb.Create(vmRecord).Error
if err != nil {
logger.Error("err:", err)
return err
}
return nil
}
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)
return err
}
return nil
}
func GetGoodsMapByIds(ids []uint32) map[uint32]Goods {
goodsMap := make(map[uint32]Goods, 0)
if len(ids) == 0 {
return goodsMap
}
var goodsList []Goods
err := NewGoodsQuerySet(DB).GoodsIdIn(ids...).All(&goodsList)
if err != nil {
logger.Error("err:", err)
return goodsMap
}
for i, _ := range goodsList {
goodsMap[goodsList[i].GoodsId] = goodsList[i]
}
return goodsMap
}
func GoodsOrderListSetGoods(orders []GoodsOrder) {
if len(orders) == 0 {
return
}
ids := make([]uint32, 0, len(orders))
for i, _ := range orders {
ids = append(ids, orders[i].GoodsId)
}
goodsMap := GetGoodsMapByIds(ids)
for i, _ := range orders {
v, ok := goodsMap[orders[i].GoodsId]
if ok {
orders[i].Goods = &v
}
}
}
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 {
PageIdx int `json:"page_idx"`
PageSize int `json:"page_size"`
VmType uint32 `json:"vm_type"` // 默认0-正常查询1-查询7天内即将过期积分
//Uid uint32 `json:"uid"`
}
type MallUserVmRecordResp struct {
List []UserVmRecord `json:"list"`
CurPage int `json:"cur_page"`
TotalPage int `json:"total_page"`
}
func (m *MallUserVmRecordReq) UserVmRecordList(uid uint32) ([]UserVmRecord, int, error) {
page := m.PageIdx - 1
if page < 0 {
page = 0
}
if m.PageSize == 0 {
m.PageSize = 10
}
var list []UserVmRecord
qs := NewUserVmRecordQuerySet(DB)
if uid != 0 {
qs = qs.UidEq(uid)
}
if m.VmType != 0 {
now := time.Now()
year, month, day := now.Date()
startTime := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
endTime := time.Date(year, month, day, 23, 59, 59, 0, time.UTC).AddDate(0, 0, 7)
qs = qs.ExpiryDateAtGte(startTime)
qs = qs.ExpiryDateLte(endTime)
qs = qs.AlterGt(0)
qs = qs.AlterNeUsedVm()
}
count, err := qs.Count()
if err != nil {
logger.Error("err:", err)
return nil, 0, err
}
totalPage := count/m.PageSize + 1
err = qs.OrderDescByID().Offset(page * m.PageSize).Limit(m.PageSize).All(&list)
if err != nil && err != RecordNotFound {
logger.Error("err:", err)
return nil, 0, err
}
for i, _ := range list {
list[i].ExpiryVm = list[i].Alter - list[i].UsedVm
}
return list, totalPage, nil
}
type MallGoodsOrderConfirmReceiptReq struct {
OrderId uint32 `json:"order_id"`
}
func (m *MallGoodsOrderConfirmReceiptReq) MallGoodsOrderConfirmReceipt(uid uint32) error {
_, err := NewGoodsOrderQuerySet(DB).OrderIdEq(m.OrderId).UidEq(uid).GetUpdater().
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
}
g.GoodsDiscount = discount
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.Platinum, nil
case MemberLevelBlackGold:
return g.GoodsDiscount.BlackGold, 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
}
// 发货
const (
DeliverTaskStateOnDeliver = "on_deliver" // 待发货
DeliverTaskStateDelivered = "delivered" // 已发货
DeliverTaskStateCancel = "cancel" // 已取消
DeliverTaskStateComplete = "complete" // 已完成
)
// gen:qs
type DeliverTask struct {
Model
Uid uint32 `json:"uid" gorm:"index"`
UserAddressId uint32 `json:"user_address_id" gorm:"index"` // 用户地址
State string `json:"state"` // 状态
OrderType uint32 `json:"order_type"` // 1-借卡 2-商城购买 3-收回卡
StoreId uint32 `json:"store_id"` //
DeliverTime time.Time `json:"deliver_time"` // 发货时间
DeliverStoreId uint32 `json:"deliver_store_id" gorm:"index"` // 发货门店
// deliver_task
}
// gen:qs
type DeliverTaskSub struct {
Model
Uid uint32 `json:"uid"`
DeliverTaskId uint32 `json:"deliver_task_id" gorm:"index"`
UserAddressId uint32 `json:"user_address_id" gorm:"index"` // 用户地址
State string `json:"state"` // 状态
OrderType uint32 `json:"order_type"` // 1-借卡 2-商城购买 3-收回卡
OrderId uint32 `json:"order_id" gorm:"index"` // 订单id
StoreId uint32 `json:"store_id"` //
GoodsOrder *GoodsOrder `json:"goods_order" gorm:"-"`
Order *Order `json:"order" gorm:"-"`
ShareCardRetrieve *ShareCardRetrieve `json:"share_card_retrieve" gorm:"-"`
// deliver_task_sub
}
func (m *DeliverTaskSub) Add() error {
//exist, err := QueryRecordExist(
// fmt.Sprintf("SELECT * FROM deliver_task WHERE user_address_id = %d AND state='%s'",
// m.UserAddressId, DeliverTaskStateOnDeliver))
//if err != nil {
// log.Error().Msgf("deliver_task exist err:%#v", err)
// return err
//}
//var deliver DeliverTask
//if exist {
// err = NewDeliverTaskQuerySet(DB).UserAddressIdEq(m.UserAddressId).
// StateEq(DeliverTaskStateOnDeliver).One(&deliver)
// if err != nil {
// log.Error().Msgf("deliver err:%#v", err)
// return err
// }
// m.DeliverTaskId = deliver.ID
// m.State = DeliverTaskStateOnDeliver
//
// err = DB.Create(m).Error
// if err != nil {
// log.Error().Msgf("create deliver task sub err:%#v", err)
// return err
// }
// return nil
//}
//var deliver DeliverTask
//err := NewDeliverTaskQuerySet(DB).UserAddressIdEq(m.UserAddressId).
// StateEq(DeliverTaskStateOnDeliver).OrderTypeEq(1).One(&deliver)
//if err != nil && err != RecordNotFound {
// log.Error().Msgf("deliver err:%#v", err)
// return err
//}
//
//if err == RecordNotFound || (deliver.StoreId != 0 && deliver.StoreId != m.StoreId) {
//
// begin := DB.Begin()
// deliver = DeliverTask{
// Uid: m.Uid,
// UserAddressId: m.UserAddressId,
// State: DeliverTaskStateOnDeliver,
// StoreId: m.StoreId,
// }
// err = begin.Create(&deliver).Error
// if err != nil {
// begin.Rollback()
// log.Error().Msgf("create deliver task err:%#v", err)
// return err
// }
//
// m.DeliverTaskId = deliver.ID
// m.State = DeliverTaskStateOnDeliver
// err = begin.Create(m).Error
// if err != nil {
// begin.Rollback()
// log.Error().Msgf("create deliver task sub err:%#v", err)
// return err
// }
// err = begin.Commit().Error
// if err != nil {
// begin.Rollback()
// log.Error().Msgf("commit deliver task sub err:%#v", err)
// return err
// }
// return nil
//}
//
//m.DeliverTaskId = deliver.ID
//m.State = DeliverTaskStateOnDeliver
//
//err = DB.Create(m).Error
//if err != nil {
// log.Error().Msgf("create deliver task sub err:%#v", err)
// return err
//}
//if deliver.StoreId == 0 {
// err = NewDeliverTaskQuerySet(DB).IDEq(deliver.ID).GetUpdater().SetStoreId(m.StoreId).Update()
// if err != nil {
// logger.Error("deliver task err:", err)
// }
//}
var deliver DeliverTask
err := NewDeliverTaskQuerySet(DB).UserAddressIdEq(m.UserAddressId).
StateEq(DeliverTaskStateOnDeliver).OrderTypeEq(m.OrderType).StoreIdEq(m.StoreId).One(&deliver)
if err != nil && err != RecordNotFound {
log.Error().Msgf("deliver err:%#v", err)
return err
}
if err == RecordNotFound {
begin := DB.Begin()
deliver = DeliverTask{
Uid: m.Uid,
UserAddressId: m.UserAddressId,
State: DeliverTaskStateOnDeliver,
StoreId: m.StoreId,
OrderType: m.OrderType,
}
err = begin.Create(&deliver).Error
if err != nil {
begin.Rollback()
log.Error().Msgf("create deliver task err:%#v", err)
return err
}
m.DeliverTaskId = deliver.ID
m.State = DeliverTaskStateOnDeliver
//m.OrderType = deliver.OrderType
err = begin.Create(m).Error
if err != nil {
begin.Rollback()
log.Error().Msgf("create deliver task sub err:%#v", err)
return err
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
log.Error().Msgf("commit deliver task sub err:%#v", err)
return err
}
return nil
}
m.DeliverTaskId = deliver.ID
m.State = DeliverTaskStateOnDeliver
err = DB.Create(m).Error
if err != nil {
log.Error().Msgf("create deliver task sub err:%#v", err)
return err
}
//if deliver.StoreId == 0 {
// err = NewDeliverTaskQuerySet(DB).IDEq(deliver.ID).GetUpdater().SetStoreId(m.StoreId).Update()
// if err != nil {
// logger.Error("deliver task err:", err)
// }
//}
return nil
}
func UpdateDeliverTaskSubStateCancel(orderId uint32) {
var sub DeliverTaskSub
err := DB.Table("deliver_task_sub").Where("order_id=?", orderId).Find(&sub).Error
if err != nil {
log.Error().Msgf("deliver task sub err:%#v", err)
return
}
//begin := DB.Begin()
err = DB.Table("deliver_task_sub").Where("order_id=?", orderId).
Update("state", DeliverTaskStateCancel).Error
if err != nil {
//begin.Rollback()
log.Error().Msgf("deliver task sub err:%#v", err)
return
}
exist, err := QueryRecordExist(
fmt.Sprintf("SELECT * FROM deliver_task_sub WHERE deliver_task_id=%d AND state='%s'",
sub.DeliverTaskId, DeliverTaskStateOnDeliver))
if err != nil {
//begin.Rollback()
logger.Error("deliver task sub exist err:", err)
return
}
if !exist {
err := DB.Table("deliver_task").Where("id=?", sub.DeliverTaskId).
Update("state", DeliverTaskStateCancel).Error
if err != nil {
//begin.Rollback()
log.Error().Msgf("deliver task sub err:%#v", err)
return
}
}
//err = begin.Commit().Error
//if err != nil {
// logger.Error("commit err:", err)
//}
}
func ParaToSubstance(c *gin.Context, sign string) (string, error) {
urlString := c.Request.URL.String()
urlPara, err := url.QueryUnescape(urlString)
if err != nil {
return "", errors.New("url query unescape err")
}
if !strings.Contains(urlPara, "/api/v1/wxpay/notice?") {
return "", errors.New("url err")
}
para := strings.Replace(urlPara, "/api/v1/wxpay/notice?", "", -1)
//fmt.Println("para--", para)
conspire := strings.Split(para, "&")
signConspire := make([]string, 0, len(conspire))
for i, _ := range conspire {
if !strings.Contains(conspire[i], "sign=") {
//fmt.Println("conspire---------", conspire[i])
signConspire = append(signConspire, conspire[i])
}
}
sort.Strings(signConspire)
//signDataJson2, _ := json.MarshalIndent(&signData, "", " ")
//fmt.Println("signDataJson2", string(signDataJson2))
signStr := strings.Join(signConspire, "&")
//signStr = signStr + "&key=" + payKey
logger.Info("签字符串1 :", signStr)
return signStr, nil
}
func GetGoodsFirstSkuCombo(goodsId []uint32) []GoodsAttributeCombo {
var list []GoodsAttributeCombo
//查询每个商品按sort字端排序的最大的一个sku的价格
err := DB.
Raw(`
SELECT b.*
FROM (SELECT id
FROM goods_attribute d
INNER JOIN (SELECT goods_id, MAX(sort) AS max_sort FROM goods_attribute GROUP BY goods_id) c
ON c.goods_id = d.goods_id AND c.max_sort = d.sort) AS a
INNER JOIN goods_attribute_combo b ON a.id = b.goods_attribute_id
WHERE b.goods_id IN (?)
GROUP BY b.goods_id
`, goodsId).
Scan(&list).
Error
if err != nil {
logger.Error("get goods first sku failed", err)
return nil
}
return list
}