604 lines
20 KiB
Go
604 lines
20 KiB
Go
package localjx
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"fmt"
|
|
"math"
|
|
"sort"
|
|
"time"
|
|
|
|
"git.rosy.net.cn/baseapi/utils"
|
|
"git.rosy.net.cn/baseapi/utils/errlist"
|
|
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
|
|
"git.rosy.net.cn/jx-callback/business/jxutils"
|
|
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
|
"git.rosy.net.cn/jx-callback/business/model"
|
|
"git.rosy.net.cn/jx-callback/business/model/dao"
|
|
"git.rosy.net.cn/jx-callback/business/partner"
|
|
"git.rosy.net.cn/jx-callback/business/partner/delivery"
|
|
)
|
|
|
|
const (
|
|
OrderCreateTypePre = 0 // 预创建
|
|
OrderCreateTypeNormal = 1 // 正常创建
|
|
|
|
PayWaitingTime = 10 * time.Minute // 等待支付的最长时间
|
|
DingShiDaMinTime = 1 * time.Hour
|
|
)
|
|
|
|
type JxSkuInfo struct {
|
|
SkuID int `json:"skuID"`
|
|
Count int `json:"count"`
|
|
|
|
Price int64 `json:"price,omitempty"` // 原价
|
|
SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
|
|
|
|
Name string `json:"name"`
|
|
Weight int `json:"weight"`
|
|
}
|
|
|
|
type JxSkuInfoList []*JxSkuInfo
|
|
|
|
func (l JxSkuInfoList) Len() int {
|
|
return len(l)
|
|
}
|
|
|
|
func (l JxSkuInfoList) Less(i, j int) bool {
|
|
if l[i].SkuID == l[j].SkuID {
|
|
return l[i].SalePrice < l[j].SalePrice
|
|
}
|
|
return l[i].SkuID < l[j].SkuID
|
|
}
|
|
|
|
func (l JxSkuInfoList) Swap(i, j int) {
|
|
l[i], l[j] = l[j], l[i]
|
|
}
|
|
|
|
type JxOrderInfo struct {
|
|
BuyerComment string `json:"buyerComment"`
|
|
StoreID int `json:"storeID"`
|
|
Skus []*JxSkuInfo `json:"skus"`
|
|
|
|
ExpectedDeliveredTimestamp int64 `json:"expectedDeliveredTimestamp"` // 预期送达时间
|
|
|
|
TotalPrice int64 `json:"totalPrice"` // 单位为分 订单总价
|
|
FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费
|
|
OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格
|
|
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
|
|
|
|
OrderID int64 `json:"orderID"`
|
|
StoreName string `json:"storeName"`
|
|
Weight int `json:"weight"`
|
|
}
|
|
|
|
type DeliveryTimeItem struct {
|
|
ViewTime string `json:"viewTime"`
|
|
UnixTime int64 `json:"unixTime"`
|
|
ViewShippingFee string `json:"viewShippingFee"`
|
|
}
|
|
|
|
type DeliveryDayTimeInfo struct {
|
|
Date string `json:"date"`
|
|
TimeList []*DeliveryTimeItem `json:"timeList"`
|
|
}
|
|
|
|
var (
|
|
orderNoBeginTimestamp int64
|
|
|
|
weekdayMap = map[int]string{
|
|
1: "一",
|
|
2: "二",
|
|
3: "三",
|
|
4: "四",
|
|
5: "五",
|
|
6: "六",
|
|
7: "七",
|
|
}
|
|
dayList = []string{"今天", "明天"}
|
|
)
|
|
|
|
func init() {
|
|
orderNoBeginTimestamp = utils.Str2Time("2010-01-01 00:00:00").Unix()
|
|
}
|
|
|
|
func GetMyOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
|
|
db := dao.GetDB()
|
|
params["vendorIDs"] = string(utils.MustMarshal([]int{model.VendorIDJX}))
|
|
tmpOrderList, totalCount, err := dao.GetOrders(db, nil, false, false, fromDateStr, toDateStr, false, nil, false, ctx.GetUserID(), params, offset, pageSize)
|
|
if err == nil {
|
|
pagedInfo = &model.PagedInfo{
|
|
TotalCount: totalCount,
|
|
}
|
|
if totalCount > 0 {
|
|
var ids []int64
|
|
for _, v := range tmpOrderList {
|
|
ids = append(ids, v.ID)
|
|
}
|
|
orderSkuList, _, err2 := dao.GetOrders(db, ids, true, false, "", "", false, nil, false, "", nil, 0, model.UnlimitedPageSize)
|
|
if err = err2; err == nil {
|
|
orderMap := make(map[string]*model.GoodsOrderExt)
|
|
var orderList []*model.GoodsOrderExt
|
|
for _, v := range orderSkuList {
|
|
universalOrderID := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID)
|
|
if orderMap[universalOrderID] == nil {
|
|
orderMap[universalOrderID] = v
|
|
orderList = append(orderList, v)
|
|
}
|
|
orderMap[universalOrderID].SkuList = append(orderMap[universalOrderID].SkuList, &v.ShortSkuInfo)
|
|
}
|
|
pagedInfo.Data = orderList
|
|
} else {
|
|
pagedInfo = nil
|
|
}
|
|
}
|
|
}
|
|
return pagedInfo, err
|
|
}
|
|
|
|
func GetMyOrderCountInfo(ctx *jxcontext.Context, fromDate, toDate time.Time, statuss []int) (countInfo []*model.GoodsOrderCountInfo, err error) {
|
|
countInfo, err = dao.GetMyOrderCountInfo(dao.GetDB(), ctx.GetUserID(), fromDate, toDate, statuss)
|
|
return countInfo, err
|
|
}
|
|
|
|
func CreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, createType int) (outJxOrder *JxOrderInfo, err error) {
|
|
outJxOrder, deliveryAddress, err := generateOrder(ctx, jxOrder, addressID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if createType != OrderCreateTypePre {
|
|
if outJxOrder.TotalPrice != jxOrder.TotalPrice {
|
|
return nil, fmt.Errorf("商品或配送信息发生改变,请重新下单")
|
|
}
|
|
outJxOrder.OrderID = GenOrderNo(ctx)
|
|
order, err2 := jxOrder2GoodsOrder(ctx, outJxOrder, deliveryAddress)
|
|
if err = err2; err == nil {
|
|
order.Status = model.OrderStatusWait4Pay
|
|
callNewOrder(order)
|
|
}
|
|
}
|
|
return outJxOrder, err
|
|
}
|
|
|
|
// 买家取消(或申请取消)订单
|
|
func BuyerCancelOrder(ctx *jxcontext.Context, orderID int64) (canceled bool, err error) {
|
|
order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX)
|
|
if err == nil {
|
|
if order.Status < model.OrderStatusNew {
|
|
order.Status = model.OrderStatusCanceled
|
|
order.VendorStatus = utils.Int2Str(model.OrderStatusCanceled)
|
|
if err = partner.CurOrderManager.UpdateOrderFields(order, []string{model.FieldStatus, "VendorStatus"}); err == nil {
|
|
canceled = true
|
|
}
|
|
} else {
|
|
err = changeOrderStatus(utils.Int64ToStr(orderID), model.OrderStatusApplyCancel, fmt.Sprintf("用户%s主动取消", ctx.GetUserName()))
|
|
}
|
|
}
|
|
return canceled, err
|
|
}
|
|
|
|
func Pay4Order(ctx *jxcontext.Context, orderID int64, payType int, vendorPayType string) (orderPay *model.OrderPay, err error) {
|
|
order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX)
|
|
if err == nil {
|
|
switch payType {
|
|
case model.PayTypeWX:
|
|
if orderPay, err = pay4OrderByWX(ctx, order, vendorPayType); err == nil {
|
|
dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName())
|
|
err = dao.CreateEntity(dao.GetDB(), orderPay)
|
|
}
|
|
default:
|
|
err = fmt.Errorf("支付方式:%d当前不支持", payType)
|
|
}
|
|
}
|
|
return orderPay, err
|
|
}
|
|
|
|
func time2ShortTimeStr(t time.Time) string {
|
|
return t.Format("15:04")
|
|
}
|
|
|
|
func GetAvailableDeliverTime(ctx *jxcontext.Context, storeID int) (deliverTimerList []*DeliveryDayTimeInfo, err error) {
|
|
db := dao.GetDB()
|
|
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if storeDetail.Status != model.StoreStatusOpened {
|
|
return nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
|
|
}
|
|
|
|
now := time.Now()
|
|
beginDate := utils.Time2Date(now)
|
|
minDingShiDaTime := now.Add(DingShiDaMinTime)
|
|
for i := 0; i < 2; i++ {
|
|
openTime1 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime1, beginDate)
|
|
closeTime1 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime1, beginDate)
|
|
openTime2 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime2, beginDate)
|
|
closeTime2 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime2, beginDate)
|
|
timeInfo := &DeliveryDayTimeInfo{
|
|
Date: fmt.Sprintf("%s(周%s)", dayList[i], weekdayMap[int(beginDate.Weekday())]),
|
|
}
|
|
if i == 0 {
|
|
timeInfo.TimeList = append(timeInfo.TimeList, &DeliveryTimeItem{
|
|
ViewTime: "立即送出",
|
|
UnixTime: 0,
|
|
ViewShippingFee: "约6.6元配送费",
|
|
})
|
|
}
|
|
deliverTimerList = append(deliverTimerList, timeInfo)
|
|
for j := 0; j < 24*3; j++ {
|
|
deliveryTime := beginDate.Add(time.Duration(j) * 20 * time.Minute)
|
|
if deliveryTime.Sub(minDingShiDaTime) >= 0 {
|
|
if (deliveryTime.Sub(openTime1) >= 0 && deliveryTime.Sub(closeTime1) <= 0) ||
|
|
(storeDetail.OpenTime2 > 0 && deliveryTime.Sub(openTime2) >= 0 && deliveryTime.Sub(closeTime2) <= 0) {
|
|
timeInfo.TimeList = append(timeInfo.TimeList, &DeliveryTimeItem{
|
|
ViewTime: time2ShortTimeStr(deliveryTime),
|
|
UnixTime: deliveryTime.Unix(),
|
|
ViewShippingFee: "约6.6元配送费",
|
|
})
|
|
}
|
|
}
|
|
}
|
|
beginDate = beginDate.Add(24 * time.Hour)
|
|
}
|
|
return deliverTimerList, err
|
|
}
|
|
|
|
func OnPayFinished(orderPay *model.OrderPay) (err error) {
|
|
order, err := partner.CurOrderManager.LoadOrder(orderPay.VendorOrderID, orderPay.VendorID)
|
|
if err == nil {
|
|
db := dao.GetDB()
|
|
dao.UpdateEntity(db, orderPay)
|
|
order.Status = model.OrderStatusNew
|
|
order.VendorStatus = utils.Int2Str(model.OrderStatusNew)
|
|
order.StatusTime = *orderPay.PayFinishedAt
|
|
err = callNewOrder(order)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func GenOrderNo(ctx *jxcontext.Context) (orderNo int64) {
|
|
const prefix = 88
|
|
const randPartNum = 1000
|
|
orderNo = time.Now().Unix() - orderNoBeginTimestamp
|
|
// fmt.Println(orderNo)
|
|
orderNo = orderNo * randPartNum
|
|
md5Bytes := md5.Sum([]byte(utils.GetUUID()))
|
|
randPart := 0
|
|
for k, v := range md5Bytes {
|
|
randPart += int(v) << ((k % 3) * 8)
|
|
}
|
|
orderNo += int64(randPart % randPartNum)
|
|
orderNo += int64(math.Pow10(int(math.Log10(float64(orderNo)))+1)) * prefix
|
|
return orderNo
|
|
}
|
|
|
|
func GenPayOrderID(order *model.GoodsOrder) (payOrderID int64) {
|
|
return utils.Str2Int64(order.VendorOrderID)
|
|
}
|
|
|
|
func GenRefundID(order *model.GoodsOrder) (refundID int64) {
|
|
const suffix = 100000
|
|
refundID = utils.Str2Int64(order.VendorOrderID) * suffix
|
|
refundID += int64(time.Now().Sub(order.OrderFinishedAt) / time.Minute)
|
|
return refundID
|
|
}
|
|
|
|
func formalizeSkus(skus []*JxSkuInfo) (outSkus []*JxSkuInfo) {
|
|
skuMap := make(map[int]int)
|
|
for _, v := range skus {
|
|
skuMap[v.SkuID] += v.Count
|
|
}
|
|
for skuID, skuCount := range skuMap {
|
|
outSkus = append(outSkus, &JxSkuInfo{
|
|
SkuID: skuID,
|
|
Count: skuCount,
|
|
})
|
|
}
|
|
return outSkus
|
|
}
|
|
|
|
func isTimeInOpTime(openTime1, closeTime1, openTime2, closeTime2 int16, time2Check time.Time) bool {
|
|
timeStrList := []string{
|
|
jxutils.OperationTime2StrWithSecond(openTime1),
|
|
jxutils.OperationTime2StrWithSecond(closeTime1),
|
|
}
|
|
if openTime1 > 0 {
|
|
timeStrList = append(timeStrList,
|
|
jxutils.OperationTime2StrWithSecond(openTime2),
|
|
jxutils.OperationTime2StrWithSecond(closeTime2),
|
|
)
|
|
}
|
|
checkTimeStr := utils.Time2TimeStr(time2Check)
|
|
for i := 0; i < len(timeStrList); i += 2 {
|
|
if checkTimeStr >= timeStrList[i] && checkTimeStr <= timeStrList[i+1] {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64) (outJxOrder *JxOrderInfo, deliveryAddress *dao.UserDeliveryAddressEx, err error) {
|
|
db := dao.GetDB()
|
|
if jxOrder.StoreID == 0 {
|
|
return nil, nil, fmt.Errorf("没有指定门店信息")
|
|
}
|
|
// 配送范围检查
|
|
storeDetail, err := dao.GetStoreDetail(db, jxOrder.StoreID, model.VendorIDJX)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
addressList, _, err := dao.QueryUserDeliveryAddress(db, addressID, []string{ctx.GetUserID()}, 0, 0)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
if len(addressList) == 0 {
|
|
return nil, nil, fmt.Errorf("地址ID不正确")
|
|
}
|
|
deliveryAddress = addressList[0]
|
|
if distance := jxutils.Point2StoreDistance(deliveryAddress.Lng, deliveryAddress.Lat, storeDetail.Lng, storeDetail.Lat, storeDetail.DeliveryRangeType, storeDetail.DeliveryRange); distance == 0 {
|
|
return nil, nil, fmt.Errorf("当前送货地址不在门店%s的配送范围", storeDetail.Name)
|
|
}
|
|
|
|
// 营业状态及时间检查
|
|
if storeDetail.Status != model.StoreStatusOpened { // model.StoreStatusDisabled {
|
|
return nil, nil, fmt.Errorf("门店:%s状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
|
|
}
|
|
checkTime := time.Now()
|
|
if jxOrder.ExpectedDeliveredTimestamp == 0 {
|
|
if storeDetail.Status != model.StoreStatusOpened {
|
|
return nil, nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
|
|
}
|
|
} else {
|
|
checkTime = utils.Timestamp2Time(jxOrder.ExpectedDeliveredTimestamp)
|
|
if checkTime.Sub(time.Now()) < DingShiDaMinTime {
|
|
return nil, nil, fmt.Errorf("预订单只能在1小时后")
|
|
}
|
|
if utils.Time2Date(time.Now()).Sub(utils.Time2Date(checkTime)) > 24*time.Hour {
|
|
return nil, nil, fmt.Errorf("预订单只能预定当天或第二天")
|
|
}
|
|
}
|
|
if !isTimeInOpTime(storeDetail.OpenTime1, storeDetail.CloseTime1, storeDetail.OpenTime2, storeDetail.CloseTime2, checkTime) {
|
|
return nil, nil, fmt.Errorf("门店:%s不在营业时间范围", storeDetail.Name)
|
|
}
|
|
|
|
outJxOrder2 := *jxOrder
|
|
outJxOrder2.Skus = nil
|
|
outJxOrder2.OrderPrice = 0
|
|
outJxOrder2.Weight = 0
|
|
outJxOrder = &outJxOrder2
|
|
outJxOrder.StoreName = storeDetail.Name
|
|
|
|
skus := formalizeSkus(jxOrder.Skus)
|
|
// 允许空商品列表(一般用于测试配送地址,门店信息是否合适)
|
|
if len(skus) > 0 {
|
|
var skuIDs []int
|
|
for _, v := range skus {
|
|
skuIDs = append(skuIDs, v.SkuID)
|
|
}
|
|
storeSkuInfo, err := cms.GetStoreSkus(ctx, jxOrder.StoreID, skuIDs, true, "", true, false, map[string]interface{}{
|
|
"actVendorID": model.VendorIDJX,
|
|
}, 0, model.UnlimitedPageSize)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
storeSkuMap := make(map[int]*dao.StoreSkuExt)
|
|
for _, v1 := range storeSkuInfo.SkuNames {
|
|
for _, v2 := range v1.Skus {
|
|
storeSkuMap[v2.SkuID] = v2
|
|
}
|
|
}
|
|
|
|
skuList, err := dao.GetSkus(db, skuIDs, nil, nil, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
skuMap := make(map[int]*model.SkuAndName)
|
|
for _, v := range skuList {
|
|
skuMap[v.ID] = v
|
|
}
|
|
|
|
for _, v := range skus {
|
|
if storeSkuBind := storeSkuMap[v.SkuID]; storeSkuBind != nil {
|
|
if sku := skuMap[v.SkuID]; sku != nil {
|
|
jxSku := &JxSkuInfo{
|
|
SkuID: v.SkuID,
|
|
Price: int64(storeSkuBind.JxPrice),
|
|
Count: v.Count,
|
|
SalePrice: int64(storeSkuBind.JxPrice), // todo 考虑活动价
|
|
Weight: sku.Weight,
|
|
Name: jxutils.ComposeSkuName(sku.Prefix, sku.Name, sku.Comment, sku.Unit, sku.SpecQuality, sku.SpecUnit, 0),
|
|
}
|
|
if storeSkuBind.ActPrice != 0 && storeSkuBind.ActPrice < storeSkuBind.JxPrice {
|
|
jxSku.SalePrice = int64(storeSkuBind.ActPrice)
|
|
jxSku.Count = 1
|
|
|
|
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
|
|
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
|
|
outJxOrder.Weight += jxSku.Count * jxSku.Weight
|
|
if v.Count-1 > 0 {
|
|
jxSku2 := *jxSku
|
|
jxSku2.SalePrice = jxSku.Price
|
|
jxSku2.Count = v.Count - 1
|
|
|
|
jxSku = &jxSku2
|
|
} else {
|
|
jxSku = nil
|
|
}
|
|
}
|
|
if jxSku != nil {
|
|
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
|
|
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
|
|
outJxOrder.Weight += jxSku.Count * jxSku.Weight
|
|
}
|
|
}
|
|
}
|
|
}
|
|
sort.Sort(JxSkuInfoList(outJxOrder.Skus))
|
|
outJxOrder.FreightPrice, _, err = delivery.CalculateDeliveryFee(dao.GetDB(), jxOrder.StoreID, "",
|
|
jxutils.StandardCoordinate2Int(deliveryAddress.Lng), jxutils.StandardCoordinate2Int(deliveryAddress.Lat),
|
|
model.CoordinateTypeMars, outJxOrder.Weight, checkTime)
|
|
} else {
|
|
outJxOrder.FreightPrice = 0
|
|
}
|
|
if err == nil {
|
|
outJxOrder.TotalPrice = outJxOrder.OrderPrice + outJxOrder.FreightPrice
|
|
outJxOrder.ActualPayPrice = outJxOrder.TotalPrice
|
|
} else {
|
|
outJxOrder = nil
|
|
deliveryAddress = nil
|
|
}
|
|
return outJxOrder, deliveryAddress, err
|
|
}
|
|
|
|
func jxOrder2GoodsOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, deliveryAddress *dao.UserDeliveryAddressEx) (order *model.GoodsOrder, err error) {
|
|
order = &model.GoodsOrder{
|
|
VendorOrderID: utils.Int64ToStr(jxOrder.OrderID),
|
|
VendorID: model.VendorIDJX,
|
|
VendorStoreID: utils.Int2Str(jxOrder.StoreID),
|
|
StoreID: jxOrder.StoreID,
|
|
StoreName: jxOrder.StoreName,
|
|
UserID: ctx.GetUserID(),
|
|
|
|
ConsigneeName: deliveryAddress.ConsigneeName,
|
|
ConsigneeMobile: deliveryAddress.ConsigneeMobile,
|
|
ConsigneeMobile2: deliveryAddress.ConsigneeMobile,
|
|
ConsigneeAddress: fmt.Sprintf("%s%s", deliveryAddress.Address, deliveryAddress.DetailAddress),
|
|
CoordinateType: model.CoordinateTypeMars,
|
|
ConsigneeLng: jxutils.StandardCoordinate2Int(deliveryAddress.Lng),
|
|
ConsigneeLat: jxutils.StandardCoordinate2Int(deliveryAddress.Lat),
|
|
|
|
Status: model.OrderStatusUnknown,
|
|
VendorStatus: "realnew",
|
|
OrderSeq: 0,
|
|
BuyerComment: jxOrder.BuyerComment,
|
|
|
|
DeliveryType: model.OrderDeliveryTypeStoreSelf,
|
|
StatusTime: time.Now(),
|
|
}
|
|
order.OrderCreatedAt = order.StatusTime
|
|
order.VendorUserID = order.UserID
|
|
if jxOrder.ExpectedDeliveredTimestamp != 0 {
|
|
order.ExpectedDeliveredTime = utils.Timestamp2Time(jxOrder.ExpectedDeliveredTimestamp)
|
|
order.BusinessType = model.BusinessTypeDingshida
|
|
} else {
|
|
order.ExpectedDeliveredTime = utils.DefaultTimeValue
|
|
order.BusinessType = model.BusinessTypeImmediate
|
|
}
|
|
for _, sku := range jxOrder.Skus {
|
|
order.Skus = append(order.Skus, &model.OrderSku{
|
|
Count: sku.Count,
|
|
VendorSkuID: utils.Int2Str(sku.SkuID),
|
|
SkuID: sku.SkuID,
|
|
SkuName: sku.Name,
|
|
VendorPrice: sku.Price,
|
|
SalePrice: sku.SalePrice,
|
|
})
|
|
order.TotalShopMoney += int64(sku.Count) * sku.SalePrice
|
|
}
|
|
order.TotalShopMoney += jxOrder.FreightPrice
|
|
order.ActualPayPrice = order.TotalShopMoney
|
|
|
|
return order, err
|
|
}
|
|
|
|
func AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
|
|
var status int
|
|
if isAcceptIt {
|
|
status = model.OrderStatusAccepted
|
|
} else {
|
|
status = model.OrderStatusCanceled
|
|
}
|
|
return changeOrderStatus(order.VendorOrderID, status, "")
|
|
}
|
|
|
|
func AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
|
|
return err
|
|
}
|
|
|
|
func PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
|
|
return changeOrderStatus(order.VendorOrderID, model.OrderStatusFinishedPickup, "")
|
|
}
|
|
|
|
func SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
|
|
return changeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "")
|
|
}
|
|
|
|
func SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
|
|
return changeOrderStatus(order.VendorOrderID, model.OrderStatusFinished, "")
|
|
}
|
|
|
|
func CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
|
|
if order.Status < model.OrderStatusDelivering {
|
|
db := dao.GetDB()
|
|
payList, err2 := dao.GetOrderPayList(db, order.VendorOrderID, jxutils.GetPossibleVendorIDFromVendorOrderID(order.VendorOrderID))
|
|
if err = err2; err == nil {
|
|
errList := errlist.New()
|
|
for _, orderPay := range payList {
|
|
if orderPay.Status == model.PayStatusYes {
|
|
// refundID := utils.Int64ToStr(GenRefundID(order))
|
|
refundID := order.VendorOrderID
|
|
orderPayRefund, err2 := refundOrderByWX(ctx, orderPay, refundID, orderPay.TotalFee, reason)
|
|
if err2 == nil {
|
|
dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName())
|
|
errList.AddErr(dao.CreateEntity(dao.GetDB(), orderPayRefund))
|
|
} else {
|
|
errList.AddErr(err2)
|
|
}
|
|
} else {
|
|
orderPay.Status = model.PayStatusCanceled
|
|
_, err2 := dao.UpdateEntity(db, orderPay)
|
|
errList.AddErr(err2)
|
|
}
|
|
}
|
|
if errList.GetErrListAsOne() == nil {
|
|
errList.AddErr(changeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, reason))
|
|
}
|
|
err = errList.GetErrListAsOne()
|
|
}
|
|
} else {
|
|
err = fmt.Errorf("当前订单状态:%s不允许取消", model.OrderStatusName[order.Status])
|
|
}
|
|
return err
|
|
}
|
|
|
|
func AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
|
|
if isAgree {
|
|
err = CancelOrder(ctx, order, reason)
|
|
} else {
|
|
err = changeOrderStatus(order.VendorOrderID, model.OrderStatusVendorRejectCancel, reason)
|
|
}
|
|
return err
|
|
}
|
|
|
|
// todo 消息用异步可能导致丢失,单同步又有重入相关的问题
|
|
func callNewOrder(order *model.GoodsOrder) (err error) {
|
|
jxutils.CallMsgHandlerAsync(func() {
|
|
err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
|
|
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, model.VendorIDJX))
|
|
return err
|
|
}
|
|
|
|
func changeOrderStatus(vendorOrderID string, status int, remark string) (err error) {
|
|
orderStatus := &model.OrderStatus{
|
|
VendorOrderID: vendorOrderID,
|
|
VendorID: model.VendorIDJX,
|
|
OrderType: model.OrderTypeOrder,
|
|
RefVendorOrderID: vendorOrderID,
|
|
RefVendorID: model.VendorIDJX,
|
|
VendorStatus: utils.Int2Str(status),
|
|
Status: status,
|
|
StatusTime: time.Now(),
|
|
Remark: remark,
|
|
}
|
|
jxutils.CallMsgHandlerAsync(func() {
|
|
err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus)
|
|
}, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJX))
|
|
return err
|
|
}
|
|
|
|
func GetOrderPay(ctx *jxcontext.Context, vendorOrderID string) (payList []*model.OrderPay, err error) {
|
|
db := dao.GetDB()
|
|
payList, err = dao.GetOrderPayList(db, vendorOrderID, jxutils.GetPossibleVendorIDFromVendorOrderID(vendorOrderID))
|
|
return payList, err
|
|
}
|