mh_goadmin_server/app/admin/models/mall.go

1496 lines
42 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 models
import (
"encoding/json"
"errors"
"fmt"
"github.com/rs/zerolog/log"
utils "go-admin/app/admin/models/tools"
orm "go-admin/common/global"
"go-admin/logger"
"gorm.io/gorm"
"sort"
"strconv"
"strings"
"time"
)
const (
SaleStatusUnknown = iota
SaleStatusYes
SaleStatusNo
)
const (
PayTypeUnknown = iota
PayTypeRm // 人民币
PayTypeVm // 积分
)
const (
PayStatusUnknown = iota
PayStatusInit
PayStatusOK
PayStatusFail
)
// 商品
// 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"` // 图片列表,用,隔开
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
PriceOriginal uint32 `json:"price_original"` // 市场价
DeliveryFee uint32 `json:"delivery_fee"` // 邮费
DealType uint32 `json:"deal_type"` // 1-积分兑换 2-购买 3-抵扣
VersionId uint64 `json:"version_id"` // 乐观锁
PriceVm uint32 `json:"price_vm"` // 积分价格
PriceRm uint32 `json:"price_rm"` // 人民币价格
//Stock uint32 `json:"stock"` // 库存
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:"-"`
}
func (*Goods) TableName() string {
return "goods"
}
type GoodsDiscount struct {
Gold uint32 `json:"gold"` // 黄金折扣
Platinum uint32 `json:"platinum"` // 白金折扣
BlackGold uint32 `json:"black_gold"` // 黑金折扣
}
type GoodsSpec struct {
Spec Spec `json:"spec"`
Values []SpecValue `json:"values"`
}
//// gen:qs
//type GoodsCat struct {
// Model
// Color string `json:"color"`
//}
// 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:"-"` // 子列表
// goods_cat
}
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"` // 已销售数量
Sort int `json:"sort"` //排序
//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:"-"`
Combos []GoodsAttributeCombo `json:"combos" gorm:"-"`
Combo *GoodsAttributeCombo `json:"combo" gorm:"-"`
// goods_attribute
}
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"` // 人民币价格
// goods_attribute_combo
}
//type GoodsSpec struct {
// Model
//}
type Spec struct {
Model
DisplayName string `json:"display_name"`
Name string `json:"name"`
State uint32 `json:"state"` // 1-未使用 2-使用
Sort uint32 `json:"sort"`
Values []SpecValue `json:"values" gorm:"-"`
}
type SpecValue struct {
Model
SpecId uint32 `json:"spec_id"`
SpecDisplayName string `json:"spec_display_name"`
SpecName string `json:"spec_name"`
DisplayValue string `json:"display_value"`
State uint32 `json:"state"` // 1-未使用 2-使用
Value string `json:"value"`
SpecSort uint32 `json:"spec_sort"`
Sort uint32 `json:"sort"`
// spec_value
}
func CreateGoodsSerialNo() string {
for {
serialNo := utils.GenSerialNo()
var count int64
err := orm.Eloquent.Table("goods").Where("serial_no=?", serialNo).Count(&count).Error
if err != nil {
logger.Errorf("err:", err)
return ""
}
if count > 0 {
continue
}
//if count, err := NewGoodsQuerySet(DB).SerialNoEq(serialNo).Count(); err == nil && count > 0 {
// continue
//}
return serialNo
}
}
func CreateGoodsId() uint32 {
for {
orderId := utils.GenUid()
var count int64
err := orm.Eloquent.Table("goods").Where("goods_id=?", orderId).Count(&count).Error
if err != nil {
logger.Errorf("err:", err)
return 0
}
if count > 0 {
continue
}
//if count, err := NewGoodsQuerySet(DB).GoodsIdEq(orderId).Count(); err == nil && count > 0 {
// continue
//}
return orderId
}
}
type GoodsListReq struct {
PageIdx int `json:"pageIndex"`
PageSize int `json:"pageSize"`
Name string `json:"name"`
SaleStatus uint32 `json:"sale_status"` // 在售状态 1-在售 2-下架
}
func (m *GoodsListReq) GoodsList() ([]Goods, int64, error) {
page := m.PageIdx - 1
if page < 0 {
page = 0
}
if m.PageSize == 0 {
m.PageSize = 10
}
var goodsList []Goods
qs := orm.Eloquent.Table("goods")
//qs := NewGoodsQuerySet(DB)
if m.Name != "" {
qs = qs.Where("name LIKE ?", "%"+m.Name+"%")
}
if m.SaleStatus != 0 {
qs = qs.Where("sale_status = ?", m.SaleStatus)
}
var count int64
err := qs.Count(&count).Error
if err != nil {
logger.Errorf("err:", err)
return nil, 0, err
}
//totalPage := int(count)/m.PageSize + 1
//err = qs.Order("cat_sort DESC,sort DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&goodsList).Error
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&goodsList).Error
if err != nil {
logger.Errorf("err:", err)
return nil, 0, err
}
GoodsListSetGoodsCat(goodsList)
return goodsList, count, 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).GoodsIdEq(m.GoodsId).One(&goods)
err := orm.Eloquent.Table("goods").Where("goods_id=?", m.GoodsId).Find(&goods).Error
if err != nil {
logger.Errorf("err:", err)
return nil, err
}
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:"-"`
}
func (*GoodsOrder) TableName() string {
return "goods_order"
}
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:"pageIndex"`
PageSize int `json:"pageSize"`
Uid uint32 `json:"uid"`
State string `json:"state"`
OrderId uint32 `json:"order_id"`
GoodsId uint32 `json:"goods_id"` // 商品id
RefundExpressNo string `json:"refund_express_no"` // 退货物流单号
//DeliveryStatus uint32 `json:"delivery_status"`
}
func (m *GoodsOrderListReq) OrderList() ([]GoodsOrder, int64, error) {
page := m.PageIdx - 1
if page < 0 {
page = 0
}
if m.PageSize == 0 {
m.PageSize = 10
}
var list []GoodsOrder
qs := orm.Eloquent.Table("goods_order") // NewGoodsOrderQuerySet(DB)
if m.Uid != 0 {
qs = qs.Where("uid=?", m.Uid)
}
if m.State != "" {
qs = qs.Where("state=?", m.State)
} else {
qs = qs.Where("state!=?", GoodsOrderStateUnPay)
}
if m.RefundExpressNo != "" {
qs = qs.Where("refund_express_no=?", m.RefundExpressNo)
}
if m.OrderId != 0 {
qs = qs.Where("order_id=?", m.OrderId)
}
if m.GoodsId != 0 {
qs = qs.Where("goods_id=?", m.GoodsId)
}
var count int64
err := qs.Count(&count).Error
if err != nil {
logger.Errorf("err:", err)
return nil, 0, err
}
//totalPage := int(count)/m.PageSize + 1
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&list).Error
if err != nil {
logger.Errorf("err:", err)
return nil, 0, err
}
GoodsOrderListSetGoods(list)
return list, count, nil
}
type GoodsOrderDetailReq struct {
OrderId uint32 `json:"order_id"`
}
func (m *GoodsOrderDetailReq) OrderDetail() (*GoodsOrder, error) {
var order GoodsOrder
qs := orm.Eloquent.Table("goods_order").Where("order_id=?", m.OrderId)
// NewGoodsOrderQuerySet(DB).OrderIdEq(m.OrderId)
//if uid != 0 {
// //qs = qs.UidEq(uid)
// qs = qs.Where("uid=?", uid)
//}
err := qs.Find(&order).Error
if err != nil {
logger.Errorf("err:", err)
return nil, err
}
//orders := GoodsOrderListSetGoods([]GoodsOrder{order})
//if len(orders) > 0 {
// order.Goods = orders[0].Goods
//}
//var goods Goods
goods, err := GetGoods(order.GoodsId)
if err != nil {
logger.Errorf("err:", err)
return nil, err
}
var goodsAttribute GoodsAttribute
err = orm.Eloquent.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)
//GoodsAttributeListSetCombos(attributes)
combo, err := GetCombo(order.GoodsAttributeComboId)
if err != nil {
log.Error().Msgf("get combo:%#v", err)
return nil, err
}
if len(attributes) > 0 {
attributes[0].Combo = combo
}
goods.Attributes = attributes
order.Goods = &goods
var userAddress UserAddress
err = orm.Eloquent.Table("user_address").Where("id=?", order.AddressId).Find(&userAddress).Error
if err != nil {
logger.Errorf("err:", err)
return nil, err
}
order.UserAddress = &userAddress
err = order.SetDeliverStore()
if err != nil {
logger.Errorf(" err:", err)
}
return &order, nil
}
func (m *Goods) GoodsCreate() error {
m.SerialNo = CreateGoodsSerialNo()
m.GoodsId = CreateGoodsId()
err := orm.Eloquent.Create(m).Error
if err != nil {
logger.Errorf("err:", err.Error())
return err
}
return nil
}
func (m *Goods) Edit() error {
err := orm.Eloquent.Save(m).Error
if err != nil {
logger.Errorf("err:", err.Error())
return err
}
return nil
}
func (m *Goods) GetDetail() error {
err := orm.Eloquent.Table("goods").Where("goods_id=?", m.GoodsId).Find(m).Error
if err != nil {
logger.Errorf("err:", err.Error())
return err
}
var goodsAttributes []GoodsAttribute
err = orm.Eloquent.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 err
}
if m.DiscountList != "" {
discount := new(GoodsDiscount)
err = json.Unmarshal([]byte(m.DiscountList), discount)
if err != nil {
log.Error().Msgf("goods discount err:%#v", err)
return err
}
m.GoodsDiscount = discount
}
cat, err := GetGoodsCat(m.CatId)
if err != nil {
log.Error().Msgf("goods cat err:%#v", err)
}
m.GoodsCat = cat
GoodsAttributeListSetSpecValues(goodsAttributes)
GoodsAttributeListSetCombos(goodsAttributes)
m.Attributes = goodsAttributes
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 := orm.Eloquent.Table("goods").Where("goods_id IN (?)", ids).Find(&goodsList).Error
//err := NewGoodsQuerySet(DB).GoodsIdIn(ids...).All(&goodsList)
if err != nil {
logger.Errorf("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
}
}
return
}
type GoodsOrderDeliverReq struct {
OrderId uint32 `json:"order_id"`
DeliveryTrackingNo string `json:"delivery_tracking_no"` // 物流单号
DeliveryCompanyNo string `json:"delivery_company_no"` // 物流公司编号
DeliveryCompany string `json:"delivery_company"` // 物流公司
DeliverStoreId uint32 `json:"deliver_store_id"` // 发货门店
}
func (m *GoodsOrderDeliverReq) OrderDeliver() (*GoodsOrder, error) {
var order GoodsOrder
err := orm.Eloquent.Table("goods_order").Where("order_id=?", m.OrderId).Find(&order).Error
if err != nil {
logger.Errorf("err:", err)
return nil, err
}
if order.State != GoodsOrderStateOnDeliver {
log.Error().Msg("state err")
return nil, errors.New("state err")
}
err = orm.Eloquent.Table("goods_order").Where("order_id=?", m.OrderId).Updates(map[string]interface{}{
"delivery_tracking_no": m.DeliveryTrackingNo,
"delivery_company": m.DeliveryCompany,
//"refund_express_company_no": m.DeliveryCompanyNo,
"delivery_company_no": m.DeliveryCompanyNo,
"state": GoodsOrderStateDelivered,
"deliver_time": Now(),
"deliver_store_id": m.DeliverStoreId,
//"delivery_status": 2,
}).Error
if err != nil {
logger.Errorf("err:", err)
return nil, err
}
order.DeliveryTrackingNo = m.DeliveryTrackingNo
order.DeliveryCompany = m.DeliveryCompany
order.DeliveryCompanyNo = m.DeliveryCompanyNo
order.State = GoodsOrderStateDelivered
order.DeliverTime = Now()
order.DeliverStoreId = m.DeliverStoreId
//orders := []GoodsOrder{order}
//GoodsOrderListSetGoods(orders)
//if len(orders) > 0 {
// order.Goods = orders[0].Goods
//}
goods, err := GetGoods(order.GoodsId)
if err != nil {
logger.Errorf("err:", err)
return nil, err
}
var goodsAttribute GoodsAttribute
err = orm.Eloquent.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
}
attributes := []GoodsAttribute{goodsAttribute}
GoodsAttributeListSetSpecValues(attributes)
combo, err := GetCombo(order.GoodsAttributeComboId)
if err != nil {
log.Error().Msgf("get combo:%#v", err)
return nil, err
}
if len(attributes) > 0 {
attributes[0].Combo = combo
}
goods.Attributes = attributes
order.Goods = &goods
var userAddress UserAddress
err = orm.Eloquent.Table("user_address").Where("id=?", order.AddressId).Find(&userAddress).Error
if err != nil {
logger.Errorf("err:", err)
return nil, err
}
order.UserAddress = &userAddress
UpdateDeliverTaskSubState(order.OrderId)
return &order, nil
}
type MallUserVmRecordReq struct {
PageIdx int `json:"pageIndex"`
PageSize int `json:"pageSize"`
Uid uint32 `json:"uid"` // 用户ID
Tel string `json:"tel"` // 用户手机号
StartTime string `json:"start_time"` // 开始时间示例2006-01-02T15:04:05+08:00
EndTime string `json:"end_time"` // 结束时间示例2006-01-02T15:04:05+08:00
}
type MallUserVmRecordResp struct {
Count int64 `json:"count"`
List []MallUserVmRecordData `json:"list"`
PageIndex int `json:"page_index"`
PageSize int `json:"page_size"`
}
type MallUserVmRecordData struct {
UserVmRecord
Tel string `json:"tel"` // 用户手机号
}
func (m *MallUserVmRecordReq) MallUserVmRecordList() ([]MallUserVmRecordData, int64, error) {
page := m.PageIdx - 1
if page < 0 {
page = 0
}
if m.PageSize == 0 {
m.PageSize = 10
}
var list []MallUserVmRecordData
qs := orm.Eloquent.Table("user_vm_record")
countQuery := orm.Eloquent.Table("user_vm_record").
Joins("LEFT JOIN user ON user_vm_record.uid = user.uid")
if m.Uid != 0 {
qs = qs.Where("user_vm_record.uid=?", m.Uid)
countQuery = countQuery.Where("user_vm_record.uid=?", m.Uid)
}
if m.Tel != "" {
qs = qs.Where("user.tel=?", m.Tel)
countQuery = countQuery.Where("user.tel=?", m.Tel)
}
if m.StartTime != "" {
startTime, err := time.Parse(QueryTimeFormat, m.StartTime)
if err == nil {
qs = qs.Where("user_vm_record.created_at>?", startTime)
countQuery = countQuery.Where("user_vm_record.created_at>?", startTime)
} else {
logger.Errorf("MallUserVmRecordList time start parse err:", err.Error())
}
}
if m.EndTime != "" {
endTime, err := time.Parse(QueryTimeFormat, m.EndTime)
if err == nil {
qs = qs.Where("user_vm_record.created_at<?", endTime)
countQuery = countQuery.Where("user_vm_record.created_at<?", endTime)
} else {
logger.Errorf("MallUserVmRecordList time end parse err:", err.Error())
}
}
qs = qs.Select("user_vm_record.*, user.tel").
Joins("Left JOIN user ON user_vm_record.uid = user.uid")
err := qs.Offset(page * m.PageSize).Limit(m.PageSize).Find(&list).Error
if err != nil {
logger.Errorf("err:", err)
return nil, 0, err
}
// 计算count
var count int64
err = countQuery.Count(&count).Error
if err != nil {
logger.Errorf("err:", err)
return nil, 0, err
}
return list, count, nil
}
func MallUserVmRecordListSetUser(list []UserVmRecord) []UserVmRecord {
ids := make([]uint32, 0, len(list))
for i, _ := range list {
ids = append(ids, list[i].Uid)
}
if len(ids) == 0 {
return list
}
infoMap, err := GetUserInfoMap(ids)
if err != nil {
logger.Errorf("user info map err:", logger.Field("err", err))
return list
}
for i, _ := range list {
v, ok := infoMap[list[i].Uid]
if ok {
list[i].User = &v
}
fmt.Println("UserInfo:", v)
}
return list
}
//func (c *GoodsCat) Add() error {
// err := orm.Eloquent.Create(c).Error
//}
func SpecListSetValue(list []Spec) []Spec {
sids := make([]uint32, 0, len(list))
for i, _ := range list {
sids = append(sids, list[i].ID)
}
specValueMap, err := GetSpecValueMap(sids)
if err != nil {
logger.Errorf("get spec value map err:", err)
return list
}
for i, _ := range list {
v, ok := specValueMap[list[i].ID]
if ok {
list[i].Values = v
}
}
return list
}
func GetSpecValueMap(ids []uint32) (map[uint32][]SpecValue, error) {
specValueMap := make(map[uint32][]SpecValue, 0)
if len(ids) == 0 {
return specValueMap, nil
}
var specValues []SpecValue
err := orm.Eloquent.Table("spec_value").Where("spec_id in (?)", ids).
Order("spec_id DESC,sort DESC").Find(&specValues).Error
if err != nil {
logger.Errorf("create spec value list err:", err)
return specValueMap, err
}
for i, _ := range specValues {
specValueMap[specValues[i].SpecId] = append(specValueMap[specValues[i].SpecId], specValues[i])
}
return specValueMap, nil
}
func (a *GoodsAttribute) SetSpecValues() {
if a.SpecValueIndex == "" {
return
}
err := orm.Eloquent.Table("spec_value").Where(fmt.Sprintf("id in (%s)", a.SpecValueIndex)).
Find(&a.SpecValues).Error
if err != nil {
logger.Errorf("set spec value list err:", err)
return
}
}
func GetGoods(id uint32) (Goods, error) {
var goods Goods
err := orm.Eloquent.Table("goods").Where("goods_id=?", id).Find(&goods).Error
if err != nil {
logger.Errorf("goods err:", err)
return goods, err
}
return goods, 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.Errorf("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 (g *Goods) UpdateSpecList() {
//fmt.Println("更新goods id", g.GoodsId)
var attributeList []GoodsAttribute
err := orm.Eloquent.Table("goods_attribute").Where("goods_id=?", g.GoodsId).Find(&attributeList).Error
if err != nil && err != RecordNotFound {
log.Error().Msgf(" attribute list err:%#v", err)
return
}
var goods Goods
err = orm.Eloquent.Table("goods").Where("goods_id=?", g.GoodsId).Find(&goods).Error
if err != nil && err != RecordNotFound {
log.Error().Msgf(" attribute list err:%#v", err)
return
}
var combo GoodsAttributeCombo
err = orm.Eloquent.Table("goods_attribute_combo").Where("goods_id=?", g.GoodsId).
Order("price_rm ASC").Limit(1).Find(&combo).Error
if err != nil && err != RecordNotFound {
log.Error().Msgf(" attribute list err:%#v", err)
return
}
//priceRm := uint32(0)
//if g.PriceRm == 1000000 {
// priceRm = goods.PriceRm
// if goods.PriceRm > combo.PriceRm {
// priceRm = combo.PriceRm
// }
//} else {
// priceRm = g.PriceRm
// if g.PriceRm > combo.PriceRm {
// priceRm = combo.PriceRm
// }
//}
if len(attributeList) == 0 {
err = orm.Eloquent.Table("goods").Where("goods_id=?", g.GoodsId).Updates(map[string]interface{}{
"spec_list": "",
"spec_index": "",
//"price_rm": priceRm,
}).Error
if err != nil {
log.Error().Msgf("update goods spec list err:%#v", err)
}
return
}
ids := make([]string, 0)
idMap := make(map[string]int, 0)
for i, _ := range attributeList {
idxList := strings.Split(attributeList[i].SpecValueIndex, ",")
for _, idx := range idxList {
_, ok := idMap[idx]
if !ok {
idMap[idx] = i
ids = append(ids, idx)
}
}
}
//fmt.Println("更新goods id------------1", g.GoodsId)
var val []SpecValue
err = orm.Eloquent.Table("spec_value").Where("id in (?)", ids).
Order("spec_sort DESC,sort DESC").Find(&val).Error
if err != nil {
log.Error().Msgf("spec value err:%#v", err)
return
}
specIds := ""
specList := make([]GoodsSpec, 0)
valMap := make(map[uint32][]SpecValue, 0)
for i, _ := range val {
_, ok := valMap[val[i].SpecId]
if ok {
valMap[val[i].SpecId] = append(valMap[val[i].SpecId], val[i])
} else {
spec := Spec{
DisplayName: val[i].SpecDisplayName,
Sort: val[i].SpecSort,
}
spec.ID = val[i].SpecId
specList = append(specList, GoodsSpec{Spec: spec})
specIds += fmt.Sprintf("%d,", spec.ID)
valMap[val[i].SpecId] = []SpecValue{val[i]}
}
}
//fmt.Println("更新goods id------------2", g.GoodsId)
for i, _ := range specList {
v, ok := valMap[specList[i].Spec.ID]
if ok {
specList[i].Values = v
}
}
sortString, err := IndexSortString(specIds[:len(specIds)-1])
if err != nil {
log.Error().Msgf("index sort err:%#v", err)
return
}
specString, err := json.Marshal(specList)
if err != nil {
log.Error().Msgf("marshal spec list err:%#v", err)
return
}
err = orm.Eloquent.Table("goods").Where("goods_id=?", g.GoodsId).Updates(map[string]interface{}{
"spec_list": specString,
"spec_index": sortString,
//"price_rm": priceRm,
}).Error
if err != nil {
log.Error().Msgf("update goods spec list err:%#v", err)
return
}
//fmt.Println("更新goods id------------3", g.GoodsId)
return
}
func UpdateSpecList(goodsId, miniRm uint32) {
goods := &Goods{}
goods.GoodsId = goodsId
goods.PriceRm = miniRm
goods.UpdateSpecList()
}
func IndexToString(ids []int) string {
sort.Ints(ids)
idString := ""
for i, _ := range ids {
idString += fmt.Sprintf("%d,", ids[i])
}
return idString[:len(idString)-1]
}
func GetGoodsAttribute(id uint32) (*GoodsAttribute, error) {
var attribute GoodsAttribute
err := orm.Eloquent.Table("goods_attribute").Where("id=?", id).Find(&attribute).Error
if err != nil {
log.Error().Msgf("attribute err:%#v", err)
return &attribute, err
}
return &attribute, nil
}
func GoodsListSetGoodsCat(list []Goods) {
ids := make([]uint32, 0, len(list))
for i, _ := range list {
ids = append(ids, list[i].CatId)
}
if len(ids) == 0 {
return
}
catMap, err := GetGoodsCatMap(ids)
if err != nil {
log.Error().Msgf("goods cat err:%#v", err)
return
}
for i, _ := range list {
v, ok := catMap[list[i].CatId]
if ok {
list[i].GoodsCat = v
}
}
}
func GetGoodsCatMap(ids []uint32) (map[uint32]*GoodsCat, error) {
catMap := make(map[uint32]*GoodsCat, 0)
if len(ids) == 0 {
return catMap, nil
}
var cats []GoodsCat
err := orm.Eloquent.Table("goods_cat").Where("id in (?)", ids).Find(&cats).Error
if err != nil {
log.Error().Msgf("goods cat err:%#v", err)
return catMap, err
}
for i, _ := range cats {
catMap[cats[i].ID] = &cats[i]
}
return catMap, nil
}
func GetGoodsCat(id uint32) (*GoodsCat, error) {
var cat GoodsCat
err := orm.Eloquent.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 := orm.Eloquent.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 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
}
}
//GoodsAttribute{}
}
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 := orm.Eloquent.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 := orm.Eloquent.Table("goods_attribute_combo").Where("id=?", id).Find(&combo).Error
if err != nil {
log.Error().Msgf("goods attribute combo err:%#v", err)
return nil, err
}
return &combo, nil
}
type GoodsOrderRefundSendReceiveReq struct {
OrderId uint32 `json:"order_id"`
SysUser SysUser `json:"sys_user"`
}
func (r *GoodsOrderRefundSendReceiveReq) Receive() error {
var goodsOrder GoodsOrder
err := orm.Eloquent.Table("goods_order").Where("order_id=?", r.OrderId).Find(&goodsOrder).Error
if err != nil {
log.Error().Msgf("goods order err:%#v", err)
return err
}
//combo, err := GetCombo(goodsOrder.GoodsAttributeComboId)
//if err != nil {
// logger.Errorf("get err:",)
//}
if goodsOrder.State == GoodsOrderStateRefundedCancel {
logger.Errorf("state err")
return errors.New("state err")
}
if goodsOrder.Vm != 0 {
err = UserVmUpdate(nil, goodsOrder.Uid, int(goodsOrder.Vm), VmEventBuyGoods, "购买商品积分抵扣取消")
if err != nil {
logger.Errorf("update user vm err:", err)
return err
}
}
var goodsAttribute GoodsAttribute
err = orm.Eloquent.Table("goods_attribute").Where("id=?", goodsOrder.GoodsAttributeId).Find(&goodsAttribute).Error
if err != nil {
log.Error().Msgf("get goods attribute err:%#v", err)
return err
}
outTradeNo, err := GetWxPayExpressFeeRefundRecord(goodsOrder.OrderId)
if err != nil {
log.Error().Msgf("express fee refund record err:%#v", err)
return err
}
memberRecord := &UserOpenMemberRecord{OpenNo: GetOrderSn(), OrderType: 8, GoodsOrder: &goodsOrder}
err = memberRecord.MallGoodsOrderRefund(outTradeNo)
if err != nil {
log.Error().Msgf("order refund err:%#v", err)
return err
}
begin := orm.Eloquent.Begin()
err = begin.Table("goods_order").Where("order_id=?", r.OrderId).Update("state", GoodsOrderStateRefunded).Error
if err != nil {
begin.Rollback()
log.Error().Msgf("update state err:%#v", err)
return err
}
err = OrderUpdateGoodsStockBack(goodsAttribute.ID, goodsOrder.Quantity, begin)
if err != nil {
begin.Rollback()
log.Error().Msgf("goods stock back err:%#v", err)
return err
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
log.Error().Msgf("commit err:%#v", err)
return err
}
operationLog := &OperationLog{
SysUid: uint32(r.SysUser.UserId),
Description: "商城购买退货入库",
OperationType: OperationTypeMallOrderRefundSendReceive,
CorrelationId: goodsOrder.OrderId,
CorrelationName: "order_id",
StoreId: goodsOrder.DeliverStoreId,
StoreName: "",
CooperativeName: r.SysUser.CooperativeName,
CooperativeBusinessId: r.SysUser.CooperativeBusinessId,
Detail: "",
}
operationLog.AddLog()
return nil
}
func GetWxPayExpressFeeRefundRecord(orderId uint32) (string, error) {
var openMemberRecord UserOpenMemberRecord
err := orm.Eloquent.Table("user_open_member_record").Where("order_id=?", orderId).
Order("id DESC").Limit(1).Find(&openMemberRecord).Error
if err != nil {
logger.Errorf("err:", err)
return "", err
}
return openMemberRecord.OpenNo, nil
}
func OrderUpdateGoodsStockBack(attributeId, count uint32, gdb *gorm.DB) error {
if gdb == nil {
gdb = orm.Eloquent
}
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.Errorf("err:", err)
return err
}
return nil
}
// 发货
const (
DeliverTaskStateOnDeliver = "on_deliver" // 待发货
DeliverTaskStateDelivered = "delivered" // 已发货
DeliverTaskStateCancel = "cancel" // 已取消
DeliverTaskStateComplete = "complete" // 已完成
)
// gen:qs
type DeliverTask struct {
Model
Uid uint32 `json:"uid"`
UserAddressId uint32 `json:"user_address_id"` // 用户地址
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"` // 发货门店
UserAddress *UserAddress `json:"user_address" gorm:"-"` // 用户地址
Subs []*DeliverTaskSub `json:"subs" gorm:"-"`
Store *Store `json:"store" gorm:"-"` // 门店
// deliver_task
}
// gen:qs
type DeliverTaskSub struct {
Model
Uid uint32 `json:"uid"`
DeliverTaskId uint32 `json:"deliver_task_id"`
UserAddressId uint32 `json:"user_address_id"` // 用户地址
State string `json:"state"` // 状态
OrderType uint32 `json:"order_type"` // 1-借卡 2-商城购买 3-收回卡
OrderId uint32 `json:"order_id"` // 订单id
StoreId uint32 `json:"store_id"` //
GoodsOrder *GoodsOrder `json:"goods_order" gorm:"-"`
Order *Order `json:"order" gorm:"-"`
// deliver_task_sub
}
type DeliverTaskReq struct {
PageIdx int `json:"pageIndex"`
PageSize int `json:"pageSize"`
Uid uint32 `json:"uid"`
State string `json:"state"` // 状态
StoreId uint32 `json:"store_id"`
}
func (m *DeliverTaskReq) List() ([]DeliverTask, int64, error) {
page := m.PageIdx - 1
if page < 0 {
page = 0
}
if m.PageSize == 0 {
m.PageSize = 10
}
var list []DeliverTask
qs := orm.Eloquent.Table("deliver_task")
if m.State != "" {
qs = qs.Where("state=?", m.State)
}
if m.Uid != 0 {
qs = qs.Where("uid=?", m.Uid)
}
if m.StoreId != 0 {
if m.StoreId == 13 {
fmt.Println("mendianid", m.StoreId)
qs = qs.Where("store_id in (?)", []uint32{0, m.StoreId})
} else {
qs = qs.Where("store_id=?", m.StoreId)
}
}
var count int64
err := qs.Count(&count).Error
if err != nil {
logger.Errorf("err:", err)
return nil, 0, err
}
//totalPage := int(count)/m.PageSize + 1
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&list).Error
if err != nil {
logger.Errorf("err:", err)
return nil, 0, err
}
DeliverTaskListSetUserAddress(list)
DeliverTaskListSetStore(list)
return list, count, nil
}
func DeliverTaskListSetUserAddress(list []DeliverTask) {
ids := make([]uint32, 0)
for i, _ := range list {
ids = append(ids, list[i].UserAddressId)
}
addressMap := GetUserAddressMap(ids)
for i, _ := range list {
v, ok := addressMap[list[i].UserAddressId]
if ok {
list[i].UserAddress = v
}
}
}
func DeliverTaskListSetStore(list []DeliverTask) {
ids := make([]uint32, 0)
for i, _ := range list {
ids = append(ids, list[i].StoreId)
}
ids = append(ids, 13)
storeMap := GetStoreMapByIds(ids)
//addressMap := GetUserAddressMap(ids)
for i, _ := range list {
storeId := list[i].StoreId
if storeId == 0 {
storeId = 13
}
v, ok := storeMap[uint64(list[i].StoreId)]
if ok {
list[i].Store = v
}
}
}
func GetUserAddressMap(ids []uint32) map[uint32]*UserAddress {
addressMap := make(map[uint32]*UserAddress, 0)
if len(ids) == 0 {
return addressMap
}
var list []UserAddress
err := orm.Eloquent.Table("user_address").Where("id in (?)", ids).Find(&list).Error
if err != nil {
log.Error().Msgf("user address err:%#v", err)
return addressMap
}
for i, _ := range list {
addressMap[list[i].ID] = &list[i]
}
return addressMap
}
func DeliverTaskSubListSetDetail(list []*DeliverTaskSub) {
for i, _ := range list {
if list[i].OrderType == 1 {
var order Order
err := orm.Eloquent.Table("order").Where("id=?", list[i].OrderId).
Find(&order).Error
if err != nil {
log.Error().Msgf("goods order err:%#v", err)
return
}
var orderCards []OrderCard
err = orm.Eloquent.Table("order_card").Where("order_id=?", order.ID).Find(&orderCards).Error
if err != nil {
logger.Errorf("err:", err)
return
}
order.OrderCards = OrderCardListSetGameInfo(orderCards)
list[i].Order = &order
} else if list[i].OrderType == 2 {
var goodsOrder GoodsOrder
err := orm.Eloquent.Table("goods_order").Where("order_id=?", list[i].OrderId).
Find(&goodsOrder).Error
if err != nil {
log.Error().Msgf("goods order err:%#v", err)
return
}
goods := &Goods{GoodsId: goodsOrder.GoodsId}
err = goods.GetDetail()
if err != nil {
log.Error().Msgf("GetDetail err:%#v", err)
return
}
goodsOrder.Goods = goods
list[i].GoodsOrder = &goodsOrder
}
}
}
func UpdateDeliverTaskSubState(orderId uint32) {
err := orm.Eloquent.Table("deliver_task_sub").Where("order_id=?", orderId).
Update("state", DeliverTaskStateDelivered).Error
if err != nil {
log.Error().Msgf("deliver task sub err:%#v", err)
return
}
var sub DeliverTaskSub
err = orm.Eloquent.Table("deliver_task_sub").Where("order_id=?", orderId).Find(&sub).Error
if err != nil {
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 {
logger.Errorf("deliver task sub exist err:", err)
return
}
if !exist {
err := orm.Eloquent.Table("deliver_task").Where("id=?", sub.DeliverTaskId).
Update("state", DeliverTaskStateDelivered).Error
if err != nil {
log.Error().Msgf("deliver task sub err:%#v", err)
return
}
}
}
func (o *GoodsOrder) SetDeliverStore() error {
store, err := GetStore(o.DeliverStoreId)
if err != nil {
logger.Errorf("set deliver store err:", err)
return err
}
o.DeliverStore = store
return nil
}
func GetGoodsFirstSkuCombo(goodsId []uint32) []GoodsAttributeCombo {
var list []GoodsAttributeCombo
//查询每个商品按sort字端排序的最大的一个sku的价格
err := orm.Eloquent.
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.Errorf("get goods first sku failed", err)
return nil
}
return list
}