From 4e5246cbdaec7803b8f26ecf052f398dbefdeb00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E5=AE=97=E6=A5=A0?= Date: Wed, 29 Jun 2022 15:59:47 +0800 Subject: [PATCH] =?UTF-8?q?=E7=89=A9=E6=B5=81=E7=AC=91=E5=98=BB=E5=98=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/cms/order.go | 2 + business/jxstore/cms/user2.go | 5 - business/jxstore/common/common.go | 334 ++++++++++---------- business/jxstore/financial/financial.go | 94 ++---- business/model/dao/user_delivery_address.go | 14 + business/model/order.go | 2 +- business/model/order_pay_refund.go | 22 ++ business/model/user_vendor_order.go | 46 ++- business/q_bida/q_bida_server.go | 178 +++++++++-- controllers/q_bida.go | 38 ++- globals/beegodb/beegodb.go | 73 ++--- routers/commentsRouter_controllers.go | 9 + 12 files changed, 509 insertions(+), 308 deletions(-) create mode 100644 business/model/dao/user_delivery_address.go create mode 100644 business/model/order_pay_refund.go diff --git a/business/jxstore/cms/order.go b/business/jxstore/cms/order.go index d7a7867d1..210373cc2 100644 --- a/business/jxstore/cms/order.go +++ b/business/jxstore/cms/order.go @@ -106,6 +106,8 @@ func Pay(ctx *jxcontext.Context, orderID string, payType int, vendorPayType, app panic(r) } }() + + // 给用户创建一个银行卡账户 userBill, err := dao.GetUserBill(db, order.UserID, "") if userBill == nil { err = financial.AddUserBill(txDB, jxutils.GenBillID(), order.UserID) diff --git a/business/jxstore/cms/user2.go b/business/jxstore/cms/user2.go index da5fb2d3a..858857592 100644 --- a/business/jxstore/cms/user2.go +++ b/business/jxstore/cms/user2.go @@ -321,11 +321,6 @@ func AddMyDeliveryAddress(ctx *jxcontext.Context, address *model.UserDeliveryAdd return list[0], err } -// GetAddressDetail 获取配送地址详情 -func GetAddressDetail(id int, userId string) { - -} - func DeleteUserDeliveryAddress(ctx *jxcontext.Context, userID string, addressID int) (err error) { num, err := dao.DeleteEntityLogically(dao.GetDB(), &model.UserDeliveryAddress{}, nil, ctx.GetUserName(), map[string]interface{}{ model.FieldID: addressID, diff --git a/business/jxstore/common/common.go b/business/jxstore/common/common.go index d55e80483..b6dfa7617 100644 --- a/business/jxstore/common/common.go +++ b/business/jxstore/common/common.go @@ -1,16 +1,7 @@ package common import ( - "fmt" - "sort" - - "git.rosy.net.cn/baseapi/platformapi/autonavi" - "git.rosy.net.cn/baseapi/utils" - "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/globals/api" ) type Store4User struct { @@ -62,165 +53,166 @@ func (x Store4UserList) Swap(i, j int) { x[i], x[j] = x[j], x[i] } -func GetNearSupplyGoodsStoreByStoreID(ctx *jxcontext.Context, storeID int) (store *model.Store, err error) { - var ( - stores []*model.Store - db = dao.GetDB() - ) - store2, _ := dao.GetStoreDetail(db, storeID, model.VendorIDJX) - if store2 == nil { - return nil, fmt.Errorf("该门店未绑定京西平台!storeID: %v", storeID) - } - if store2.IsSupplyGoods == model.YES { - return nil, fmt.Errorf("该门店已经是货源门店,无法从其他货源门店进货!storeID: %v", storeID) - } - sql := ` - SELECT a.* - FROM store a - JOIN store_map b ON b.store_id = a.id - JOIN store c ON c.city_code = a.city_code AND c.id = ? - WHERE a.deleted_at = ? - AND b.deleted_at = ? - AND b.vendor_id = ? - AND b.is_supply_goods = ? - AND a.status = ? - ` - sqlParams := []interface{}{ - storeID, - utils.DefaultTimeValue, utils.DefaultTimeValue, - model.VendorIDJX, model.YES, model.StoreStatusOpened, - } - err = dao.GetRows(db, &stores, sql, sqlParams) - if len(stores) > 0 { - realDistance := float64(0) - for _, v := range stores { - distance := jxutils.EarthDistance(jxutils.IntCoordinate2Standard(v.Lng), jxutils.IntCoordinate2Standard(v.Lat), jxutils.IntCoordinate2Standard(store2.Lng), jxutils.IntCoordinate2Standard(store2.Lat)) - if realDistance == 0 { - realDistance = distance - store = v - } else { - if realDistance > distance { - realDistance = distance - store = v - } - } - } - } - return store, err -} - -func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, maxRadius int, needWalkDistance, isJds bool) (storeList []*Store4User, err error) { - const ( - maxStoreCount4User = 5 - ) - - var ( - sql string - sqlParams []interface{} - ) - - lng2, _ := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 90) - _, lat2 := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 0) - lng1 := lng - (lng2 - lng) - lat1 := lat - (lat2 - lat) - // globals.SugarLogger.Debugf("%f,%f,%f,%f\n", lng1, lng2, lat1, lat2) - if !isJds { - sql = ` - SELECT t1.*, - city.name city_name - FROM store t1 - JOIN place city ON city.code = t1.city_code - JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status <> ? - WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.lng > ? AND t1.lng < ? AND t1.lat > ? AND t1.lat < ? - AND sm.is_order <> ? - AND t1.id <> ? - ORDER BY t1.id - ` - sqlParams = []interface{}{ - model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled, - utils.DefaultTimeValue, model.StoreStatusDisabled, jxutils.StandardCoordinate2Int(lng1), jxutils.StandardCoordinate2Int(lng2), jxutils.StandardCoordinate2Int(lat1), jxutils.StandardCoordinate2Int(lat2), - model.YES, - model.MatterStoreID, - } - } else { - sql = ` - SELECT t1.*, - city.name city_name - FROM store t1 - JOIN place city ON city.code = t1.city_code - JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status = ? - WHERE t1.deleted_at = ? AND t1.status = ? AND t1.lng > ? AND t1.lng < ? AND t1.lat > ? AND t1.lat < ? - AND sm.is_order <> ? - AND t1.id <> ? - ORDER BY t1.id - ` - sqlParams = []interface{}{ - model.VendorIDJDShop, utils.DefaultTimeValue, model.StoreStatusOpened, - utils.DefaultTimeValue, model.StoreStatusOpened, jxutils.StandardCoordinate2Int(lng1), jxutils.StandardCoordinate2Int(lng2), jxutils.StandardCoordinate2Int(lat1), jxutils.StandardCoordinate2Int(lat2), - model.YES, - model.MatterStoreID, - } - } - var storeList1 []*Store4User - if err = dao.GetRows(dao.GetDB(), &storeList1, sql, sqlParams...); err == nil { - var storeList2 []*Store4User - for _, v := range storeList1 { - distance := jxutils.Point2StoreDistance(lng, lat, v.Lng, v.Lat, v.DeliveryRangeType, v.DeliveryRange) - if distance > 0 || (lng == jxutils.IntCoordinate2Standard(v.Lng) && lat == jxutils.IntCoordinate2Standard(v.Lat)) { - v.Distance = distance - storeList2 = append(storeList2, v) - } - } - - // 为了审核用 - if len(storeList2) == 0 { - sql2 := ` - SELECT t1.*, - city.name city_name - FROM store t1 - JOIN place city ON city.code = t1.city_code - WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.id = ? - ` - sqlParams2 := []interface{}{ - // model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled, - utils.DefaultTimeValue, - model.StoreStatusDisabled, - // jxutils.StandardCoordinate2Int(0), - // jxutils.StandardCoordinate2Int(10000), - // jxutils.StandardCoordinate2Int(0), - // jxutils.StandardCoordinate2Int(10000), - // model.YES, - 102919, //商城模板店 - } - dao.GetRows(dao.GetDB(), &storeList2, sql2, sqlParams2...) - // if len(storeList2) > 1 { - // storeList2 = storeList2[:1] - // } - } - - // 如果要求以步行距离来算 - if needWalkDistance { - var coordList []*autonavi.Coordinate - for _, v := range storeList2 { - coordList = append(coordList, &autonavi.Coordinate{ - Lng: v.FloatLng, - Lat: v.FloatLat, - }) - } - if distanceList, err2 := api.AutonaviAPI.BatchWalkingDistance(lng, lat, coordList); err2 == nil { - for k, v := range storeList2 { - v.WalkDistance = int(distanceList[k]) - } - } else { - return nil, err2 - } - } - - sort.Sort(Store4UserList(storeList2)) - storeList = storeList2 - if len(storeList) > maxStoreCount4User { - storeList = storeList[:maxStoreCount4User] - } - } - return storeList, err -} +// +//func GetNearSupplyGoodsStoreByStoreID(ctx *jxcontext.Context, storeID int) (store *model.Store, err error) { +// var ( +// stores []*model.Store +// db = dao.GetDB() +// ) +// store2, _ := dao.GetStoreDetail(db, storeID, model.VendorIDJX) +// if store2 == nil { +// return nil, fmt.Errorf("该门店未绑定京西平台!storeID: %v", storeID) +// } +// if store2.IsSupplyGoods == model.YES { +// return nil, fmt.Errorf("该门店已经是货源门店,无法从其他货源门店进货!storeID: %v", storeID) +// } +// sql := ` +// SELECT a.* +// FROM store a +// JOIN store_map b ON b.store_id = a.id +// JOIN store c ON c.city_code = a.city_code AND c.id = ? +// WHERE a.deleted_at = ? +// AND b.deleted_at = ? +// AND b.vendor_id = ? +// AND b.is_supply_goods = ? +// AND a.status = ? +// ` +// sqlParams := []interface{}{ +// storeID, +// utils.DefaultTimeValue, utils.DefaultTimeValue, +// model.VendorIDJX, model.YES, model.StoreStatusOpened, +// } +// err = dao.GetRows(db, &stores, sql, sqlParams) +// if len(stores) > 0 { +// realDistance := float64(0) +// for _, v := range stores { +// distance := jxutils.EarthDistance(jxutils.IntCoordinate2Standard(v.Lng), jxutils.IntCoordinate2Standard(v.Lat), jxutils.IntCoordinate2Standard(store2.Lng), jxutils.IntCoordinate2Standard(store2.Lat)) +// if realDistance == 0 { +// realDistance = distance +// store = v +// } else { +// if realDistance > distance { +// realDistance = distance +// store = v +// } +// } +// } +// } +// return store, err +//} +// +//func GetStoreListByLocation(ctx *jxcontext.Context, lng, lat float64, maxRadius int, needWalkDistance, isJds bool) (storeList []*Store4User, err error) { +// const ( +// maxStoreCount4User = 5 +// ) +// +// var ( +// sql string +// sqlParams []interface{} +// ) +// +// lng2, _ := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 90) +// _, lat2 := jxutils.ConvertDistanceToLogLat(lng, lat, float64(maxRadius), 0) +// lng1 := lng - (lng2 - lng) +// lat1 := lat - (lat2 - lat) +// // globals.SugarLogger.Debugf("%f,%f,%f,%f\n", lng1, lng2, lat1, lat2) +// if !isJds { +// sql = ` +// SELECT t1.*, +// city.name city_name +// FROM store t1 +// JOIN place city ON city.code = t1.city_code +// JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status <> ? +// WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.lng > ? AND t1.lng < ? AND t1.lat > ? AND t1.lat < ? +// AND sm.is_order <> ? +// AND t1.id <> ? +// ORDER BY t1.id +// ` +// sqlParams = []interface{}{ +// model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled, +// utils.DefaultTimeValue, model.StoreStatusDisabled, jxutils.StandardCoordinate2Int(lng1), jxutils.StandardCoordinate2Int(lng2), jxutils.StandardCoordinate2Int(lat1), jxutils.StandardCoordinate2Int(lat2), +// model.YES, +// model.MatterStoreID, +// } +// } else { +// sql = ` +// SELECT t1.*, +// city.name city_name +// FROM store t1 +// JOIN place city ON city.code = t1.city_code +// JOIN store_map sm ON sm.store_id = t1.id AND sm.vendor_id = ? AND sm.deleted_at = ? AND sm.status = ? +// WHERE t1.deleted_at = ? AND t1.status = ? AND t1.lng > ? AND t1.lng < ? AND t1.lat > ? AND t1.lat < ? +// AND sm.is_order <> ? +// AND t1.id <> ? +// ORDER BY t1.id +// ` +// sqlParams = []interface{}{ +// model.VendorIDJDShop, utils.DefaultTimeValue, model.StoreStatusOpened, +// utils.DefaultTimeValue, model.StoreStatusOpened, jxutils.StandardCoordinate2Int(lng1), jxutils.StandardCoordinate2Int(lng2), jxutils.StandardCoordinate2Int(lat1), jxutils.StandardCoordinate2Int(lat2), +// model.YES, +// model.MatterStoreID, +// } +// } +// var storeList1 []*Store4User +// if err = dao.GetRows(dao.GetDB(), &storeList1, sql, sqlParams...); err == nil { +// var storeList2 []*Store4User +// for _, v := range storeList1 { +// distance := jxutils.Point2StoreDistance(lng, lat, v.Lng, v.Lat, v.DeliveryRangeType, v.DeliveryRange) +// if distance > 0 || (lng == jxutils.IntCoordinate2Standard(v.Lng) && lat == jxutils.IntCoordinate2Standard(v.Lat)) { +// v.Distance = distance +// storeList2 = append(storeList2, v) +// } +// } +// +// // 为了审核用 +// if len(storeList2) == 0 { +// sql2 := ` +// SELECT t1.*, +// city.name city_name +// FROM store t1 +// JOIN place city ON city.code = t1.city_code +// WHERE t1.deleted_at = ? AND t1.status <> ? AND t1.id = ? +// ` +// sqlParams2 := []interface{}{ +// // model.VendorIDJX, utils.DefaultTimeValue, model.StoreStatusDisabled, +// utils.DefaultTimeValue, +// model.StoreStatusDisabled, +// // jxutils.StandardCoordinate2Int(0), +// // jxutils.StandardCoordinate2Int(10000), +// // jxutils.StandardCoordinate2Int(0), +// // jxutils.StandardCoordinate2Int(10000), +// // model.YES, +// 102919, //商城模板店 +// } +// dao.GetRows(dao.GetDB(), &storeList2, sql2, sqlParams2...) +// // if len(storeList2) > 1 { +// // storeList2 = storeList2[:1] +// // } +// } +// +// // 如果要求以步行距离来算 +// if needWalkDistance { +// var coordList []*autonavi.Coordinate +// for _, v := range storeList2 { +// coordList = append(coordList, &autonavi.Coordinate{ +// Lng: v.FloatLng, +// Lat: v.FloatLat, +// }) +// } +// if distanceList, err2 := api.AutonaviAPI.BatchWalkingDistance(lng, lat, coordList); err2 == nil { +// for k, v := range storeList2 { +// v.WalkDistance = int(distanceList[k]) +// } +// } else { +// return nil, err2 +// } +// } +// +// sort.Sort(Store4UserList(storeList2)) +// storeList = storeList2 +// if len(storeList) > maxStoreCount4User { +// storeList = storeList[:maxStoreCount4User] +// } +// } +// return storeList, err +//} diff --git a/business/jxstore/financial/financial.go b/business/jxstore/financial/financial.go index a22bc6c1c..9d561a5d2 100644 --- a/business/jxstore/financial/financial.go +++ b/business/jxstore/financial/financial.go @@ -6,6 +6,7 @@ import ( "crypto/sha256" "encoding/json" "fmt" + "git.rosy.net.cn/jx-callback/business/q_bida" "github.com/astaxie/beego/client/orm" "sort" "strings" @@ -97,7 +98,6 @@ func (p *PayHandler) CreatePay(txDB orm.TxOrmer, subAppID string) (err error) { // TotalFee: int(order.ActualPayPrice), //} } - // 暂时不支持微信直接支付 case model.PayTypeWX: param := &wxpayapi.CreateOrderParam{ @@ -257,20 +257,26 @@ func onTLpayFinished(call *tonglianpayapi.CallBackResult) (err error) { t1, _ := time.ParseInLocation("20060102150405", call.PayTime, loc) order.PayFinishedAt = t1 order.OriginalData = utils.Format4Output(call, true) + payStatus := 0 if call.TrxStatus == tonglianpayapi.TrxStatusSuccess { order.Status = model.OrderStatusFinished + payStatus = model.OrderStatusSuccessPay } else { order.Status = model.OrderStatusCanceled + payStatus = model.OrderStatusFailPay } if _, err := dao.UpdateEntity(db, order); err != nil { return err } + if _, err := dao.UpdateEntity(db, &model.UserVendorOrder{LocalWayBill: order.OrderID, OrderStatus: payStatus}, "OrderStatus"); err != nil { + return err + } if call.TrxStatus == tonglianpayapi.TrxStatusSuccess { switch order.OrderType { case model.PayType4Express: - + err = q_bida.CreateOrder2QBiDa(order.OrderID) case model.PayType4Member, model.PayType4Recharge: err = OnPayFinished(order) } @@ -282,70 +288,34 @@ func onTLpayFinished(call *tonglianpayapi.CallBackResult) (err error) { } func onTLpayRefund(call *tonglianpayapi.CallBackResult) (err error) { - // orderPayRefund := &model.OrderPayRefund{ - // RefundID: call.CusorderID, - // } - // db := dao.GetDB() - // if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil { - // if call.TrxStatus == tonglianpayapi.TrxStatusSuccess { - // orderPayRefund.Status = model.RefundStatusYes - // } else { - // orderPayRefund.Status = model.RefundStatusFailed - // } - // orderPayRefund.OriginalData = utils.Format4Output(call, true) - // dao.UpdateEntity(db, orderPayRefund) - // } else if dao.IsNoRowsError(err) { - // globals.SugarLogger.Warnf("收到异常的退款事件, call:%s", utils.Format4Output(call, true)) - // } + orderPayRefund := &model.OrderPayRefund{ + RefundID: call.CusorderID, + } + db := dao.GetDB() + if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil { + if call.TrxStatus == tonglianpayapi.TrxStatusSuccess { + orderPayRefund.Status = model.RefundStatusYes + } else { + orderPayRefund.Status = model.RefundStatusFailed + } + orderPayRefund.OriginalData = utils.Format4Output(call, true) + dao.UpdateEntity(db, orderPayRefund) + } else if dao.IsNoRowsError(err) { + globals.SugarLogger.Warnf("收到异常的退款事件, call:%s", utils.Format4Output(call, true)) + } - // orderPay := &model.OrderPay{ - // VendorOrderID: orderPayRefund.VendorOrderID, - // VendorID: jxutils.GetPossibleVendorIDFromVendorOrderID(orderPayRefund.VendorOrderID), - // PayType: model.PayTypeWX, - // Status: model.PayStatusYes, - // } - // orderPay.DeletedAt = utils.DefaultTimeValue - // if err = dao.GetEntity(db, orderPay, "VendorOrderID", "VendorID", "PayType", "Status", "DeletedAt"); err == nil { - // orderPay.Status = model.PayStatusRefund - // dao.UpdateEntity(db, orderPay) - // } + orderPay := &model.Order{ + OrderID: orderPayRefund.VendorOrderID, + } + if err = dao.GetEntity(db, orderPay, "VendorOrderID"); err == nil { + orderPay.Status = model.OrderStatusCancel + dao.UpdateEntity(db, orderPay) + } + + dao.UpdateEntity(db, &model.UserVendorOrder{LocalWayBill: call.CusorderID, OrderStatus: model.OrderStatusCancel}, "OrderStatus") return err } -// func RefundOrderByTL(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) { -// result, err := api.TLpayAPI.PayRefund(&tonglianpayapi.PayRefundParam{ -// Trxamt: refundFee, -// Reqsn: utils.GetUUID(), -// Remark: refundDesc, -// OldTrxID: orderPay.TransactionID, -// }) -// if err == nil { -// orderPayRefund = &model.OrderPayRefund{ -// RefundID: refundID, -// VendorRefundID: result.TrxID, -// VendorOrderID: orderPay.VendorOrderID, -// VendorID: orderPay.VendorID, -// Status: model.RefundStatusNo, -// TransactionID: orderPay.TransactionID, -// RefundFee: refundFee, -// RefundCreatedAt: time.Now(), -// } -// dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName()) -// db := dao.GetDB() -// if result.TrxStatus == tonglianpayapi.TrxStatusSuccess { -// orderPayRefund.Status = model.RefundStatusYes -// } else { -// orderPayRefund.Status = model.RefundStatusFailed -// } -// orderPayRefund.OriginalData = utils.Format4Output(result, true) -// dao.CreateEntity(db, orderPayRefund) - -// orderPay.Status = model.PayStatusRefund -// dao.UpdateEntity(db, orderPay) -// } -// return orderPayRefund, err -// } - func OnWxPayCallback(msg *wxpayapi.CallbackMsg) (err error) { globals.SugarLogger.Debugf("OnWxPayCallback msg:%s", utils.Format4Output(msg, true)) switch msg.MsgType { diff --git a/business/model/dao/user_delivery_address.go b/business/model/dao/user_delivery_address.go new file mode 100644 index 000000000..5dab70a09 --- /dev/null +++ b/business/model/dao/user_delivery_address.go @@ -0,0 +1,14 @@ +package dao + +import ( + "git.rosy.net.cn/jx-callback/business/model" +) + +func GetAddressDetail(id int) (*model.UserDeliveryAddress, error) { + param := &model.UserDeliveryAddress{} + param.ModelIDCULD.ID = id + if err := GetEntity(GetDB(), param, "ID"); err != nil { + return nil, err + } + return param, nil +} diff --git a/business/model/order.go b/business/model/order.go index 3d188e7a8..7cb0ebf81 100644 --- a/business/model/order.go +++ b/business/model/order.go @@ -58,7 +58,7 @@ type Order struct { Type int `json:"type"` // 支付还是提现 OrderType int `json:"orderType"` // 订单类型,1为发任务,2为冲会员,3为发快递 Way string `json:"way"` //weixinapp ,weixinmini - Status int `json:"status"` //订单状态,待支付2,已支付5,支付成功110,支付失败115 + Status int `json:"status"` //订单状态,待支付2,已支付5,支付成功110,支付失败115,150取消 PayPrice int `json:"payPrice"` //支付金额 TransactionID string `orm:"column(transaction_id);size(48)" json:"transactionID"` // 支付成功后,支付方生成的事务ID PayFinishedAt time.Time `orm:"type(datetime);null" json:"payFinishedAt"` // 支付完成时间 diff --git a/business/model/order_pay_refund.go b/business/model/order_pay_refund.go new file mode 100644 index 000000000..8b1fed13d --- /dev/null +++ b/business/model/order_pay_refund.go @@ -0,0 +1,22 @@ +package model + +import "time" + +type OrderPayRefund struct { + ModelIDCULD + RefundID string `orm:"column(refund_id);unique;size(48)" json:"refundID"` // 三方运单Id + VendorRefundID string `orm:"column(vendor_refund_id);unique;size(48)" json:"vendorRefundID"` // 支付方退款成功后生成的退款单号 + VendorOrderID string `orm:"column(vendor_order_id);index;size(48)" json:"vendorOrderID"` + TransactionID string `orm:"column(transaction_id);index;size(48)" json:"transactionID"` // 支付成功后,支付方生成的事务ID + Status int `json:"status"` + RefundCreatedAt time.Time `orm:"type(datetime);index" json:"payCreatedAt"` + RefundFinishedAt *time.Time `orm:"type(datetime);null" json:"payFinishedAt"` + RefundFee int `json:"refundFee"` + OriginalData string `orm:"type(text)" json:"-"` +} + +func (v *OrderPayRefund) TableUnique() [][]string { + return [][]string{ + []string{"ID"}, + } +} diff --git a/business/model/user_vendor_order.go b/business/model/user_vendor_order.go index 195c488ed..c2d9bb68a 100644 --- a/business/model/user_vendor_order.go +++ b/business/model/user_vendor_order.go @@ -1,6 +1,8 @@ package model -import "time" +import ( + "time" +) type UserVendorOrder struct { ModelIDCUL @@ -30,11 +32,20 @@ type UserVendorOrder struct { Bulk float64 `orm:"column(bulk)" json:"bulk"` // 体积抛比系数 Increment float64 `orm:"column(increment)" json:"increment"` // 增值(物流) ChannelType int `orm:"size(8);column(channel_type)" json:"channelType"` // 渠道类型(1-快递,2-物流,3-国际物流,4-整车) - OrderStatus int `orm:"size(8);column(order_status)" json:"orderType"` // 订单状态(2-待支付,3-支付失败,4-支付成功,5-取件,6-配送,25-取消) + OrderStatus int `orm:"size(8);column(order_status)" json:"orderType"` // 订单状态(2-待支付,3-支付失败,4-支付成功,5-待取件,6-配送,110-完成,150-取消) Img string `orm:"column(img)" json:"img"` // 包裹图片 IsForward int `orm:"column(is_forward)" json:"isForward"` // 1否,2是 转寄单 } +const ( + OrderStatusWaitPay = 2 // 待支付 + OrderStatusFailPay = 3 // 支付失败 + OrderStatusSuccessPay = 4 // 支付成功 + OrderStatusWaitPickup = 5 // 待取件 + OrderStatusCancel = 150 // 取消订单 + // 。。。。。 +) + func (*UserVendorOrder) TableUnique() [][]string { return [][]string{ []string{"LocalWayBill"}, @@ -42,11 +53,11 @@ func (*UserVendorOrder) TableUnique() [][]string { } } -//func (*UserVendorOrder) TableIndex()[][]string { -// return [][]string{ -// []string{""}, -// } -//} +func (*UserVendorOrder) TableIndex() [][]string { + return [][]string{ + []string{"CreatedAt"}, + } +} // MakeOrderParamReq 下订单请求参数 type MakeOrderParamReq struct { @@ -98,3 +109,24 @@ type UserOrderList struct { SenderAddress string `orm:"column(sender_address)" json:"senderAddress"` // 发货城市 ReceiveAddress string `orm:"column(receive_address)" json:"receiveAddress"` // 收货城市 } + +// OrderListRes 查询订单列表 +type OrderListRes struct { + UserVendorOrder + UserName string `orm:"column(user_name)" json:"userName"` // 系统用户 + SendUserName string `orm:"column(send_user_name)" json:"sendUserName"` // 发货人 + ReceiveUserName string `orm:"column(receive_user_name)" json:"receiveUserName"` // 收货人 + SenderAddress string `orm:"column(sender_address)" json:"senderAddress"` // 发货城市 + ReceiveAddress string `orm:"column(receive_address)" json:"receiveAddress"` // 收货城市 +} + +// OrderListReq 请求参数 +type OrderListReq struct { + ExpressType int `json:"expressType"` // 快递公司 + OrderNo string `json:"orderNo"` // 订单Id + OrderStatus int `json:"orderStatus"` // 订单状态 + PageNum int `json:"pageNum"` // 页码 + PageSize int `json:"pageSize"` // 页数 + StartTime time.Time `json:"startTime"` // 开始时间 + EndTime time.Time `json:"endTime"` // 结束时间 +} diff --git a/business/q_bida/q_bida_server.go b/business/q_bida/q_bida_server.go index 7cbc303c3..f1e32181b 100644 --- a/business/q_bida/q_bida_server.go +++ b/business/q_bida/q_bida_server.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" bida "git.rosy.net.cn/baseapi/platformapi/q_bida" + "git.rosy.net.cn/baseapi/platformapi/tonglianpayapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" @@ -93,7 +94,7 @@ func CreateWayOrder(ctx *jxcontext.Context, param *model.MakeOrderParamReq, user Bulk: param.Bulk, Increment: param.Increment, ChannelType: param.ChannelType, - OrderStatus: 2, // 创建待支付 + OrderStatus: model.OrderStatusWaitPay, // 创建待支付 Img: param.Images, IsForward: model.YES, // } @@ -121,7 +122,7 @@ func CreateWayOrder(ctx *jxcontext.Context, param *model.MakeOrderParamReq, user Type: model.OrderTypePay, OrderType: model.PayType4Express, Way: "", - Status: model.OrderTypeCash, // 待支付状态 + Status: model.OrderStatusWaitPay, // 待支付状态 PayPrice: int(vendorOrder.ChannelFee * 100), TransactionID: "", PayFinishedAt: time.Time{}, @@ -145,13 +146,54 @@ func CreateWayOrder(ctx *jxcontext.Context, param *model.MakeOrderParamReq, user } // CancelWayOrder 取消运单 todo -func CancelWayOrder(param *bida.CancelOrderReq) error { - if err := api.QBiDaAPI.CancelOrder(param); err != nil { +func CancelWayOrder(ctx *jxcontext.Context, userId string, param *bida.CancelOrderReq) error { + // 查询订单 + order := &model.UserVendorOrder{UserId: userId, OtherWayBill: param.OrderNo} + if err := dao.GetEntity(dao.GetDB(), order, "UserId", "OtherWayBill"); err != nil { return err } - // 发起退款 - // 修改本地订单状态 + // 待支付或者支付失败 + switch order.OrderStatus { + case model.OrderStatusFailPay, model.OrderStatusWaitPay: // 待支付订单,或者支付失败订单,不需要退款,取消本地订单以及order记录表 + db := dao.GetDB() + tx, _ := dao.Begin(db) + defer func() { + if r := recover(); r != nil { + panic(r) + } + }() + + order.OrderStatus = model.OrderStatusCancel + if _, err := dao.UpdateEntityTx(tx, order, "OrderStatus"); err != nil { + tx.Rollback() + return err + } + if _, err := dao.UpdateEntityTx(tx, &model.Order{OrderID: param.OrderNo, UserID: userId, Status: model.OrderStatusCancel}, "Status"); err != nil { + tx.Rollback() + return err + } + tx.Commit() + case model.OrderStatusSuccessPay: // 支付成功,取消三方订单,本地转取消状态,,原路退款 + // 发起QBiDa取消,过去取消通过,则取消本地!不通过,则不予取消! + if err := api.QBiDaAPI.CancelOrder(param); err != nil { + return err + } + // 暂时考虑余额支付渠道,加载order表判断支付渠道方式 + orderWay := &model.Order{OrderID: param.OrderNo, UserID: userId} + if err := dao.GetEntity(dao.GetDB(), orderWay, "OrderID", "UserID"); err != nil { + return err + } + if orderWay.PayMethod == 1 { // 余额支付 + // 支付方式为余额支付,则需要修改order/userVendorOrder,修改订单状态,给用户账户价钱,生成一个价钱数据 + } else if orderWay.PayMethod == 2 { // 微信支付 + // 微信支付原路退款,发起退款申请 + _, err := RefundOrderByTL(ctx, orderWay, order.OtherWayBill, int(order.ChannelFee*100), "申请退款") + return err + } + + } + return nil } @@ -183,12 +225,12 @@ func QueryUserOrderList(userId string, expressType, orderStatus int, pageNum, pa SELECT  a.type,a.other_way_bill,a.local_way_bill,a.user_id,a.receive_address_id,a.sender_address_id, a.create_at,a.order_status,a.channel_fee,add.consignee_name send_user_name,add2.consignee_name receive_user_name, - city.col_areaName sender_address,city2.col_areaName receive_address + district.name sender_address,city.name receive_address FROM user_vendor_order a LEFT JOIN user_delivery_address add ON a.sender_address_id = add.id LEFT JOIN user_delivery_address add2 ON a.receive_address_id = add2.id - LEFT JOIN jde_city city ON city.clo_tencentAddressCode = add.district_code - LEFT JOIN jde_city city2 ON city2.clo_tencentAddressCode = add2.district_code + LEFT JOIN place district ON district.code = add.district_code + LEFT JOIN place city ON city.code = add2.district_code WHERE a.user_id = ? ` param := make([]interface{}, 0, 0) @@ -214,16 +256,16 @@ func QueryUserOrderList(userId string, expressType, orderStatus int, pageNum, pa } // CreateOrder2QBiDa 订单回调成功,且为运费支付时使用该接口 -func CreateOrder2QBiDa(orderId string) { +func CreateOrder2QBiDa(orderId string) error { // 加载订单 order := &model.UserVendorOrder{} sql := `SELECT * FROM user_vendor_order WHERE local_way_bill = ? ` if err := dao.GetRow(dao.GetDB(), order, sql, []interface{}{orderId}...); err != nil { - return + return err } // 创建QBIDA订单 - otherId, err := createOtherOrder(&bida.MakeOrderReq{ + makeOrder := &bida.MakeOrderReq{ PromiseTimeType: order.PromiseTimeType, DeliveryType: order.DeliveryType, Goods: order.Goods, @@ -238,20 +280,110 @@ func CreateOrder2QBiDa(orderId string) { ThirdPlatform: order.ThirdPlatform, Type: order.Type, Img: order.Img, - // - //ReceiveAddress: order.ReceiveAddressID, - //ReceiveName: "", - //ReceivePhone: "", - //SenderAddress: "", - //SenderName: "", - //SenderPhone: "", - - }) + } // 获取发货地址以及送货地址 - + // GetAddressDetail 获取配送地址详情 + sendAddress, err := dao.GetAddressDetail(int(order.SenderAddressID)) + if err != nil { + return err + } + makeOrder.SenderAddress = sendAddress.AutoAddress + makeOrder.SenderName = sendAddress.ConsigneeName + makeOrder.SenderPhone = sendAddress.ConsigneeMobile + receiveAddress, err := dao.GetAddressDetail(int(order.ReceiveAddressID)) + if err != nil { + return err + } + makeOrder.ReceiveAddress = receiveAddress.AutoAddress + makeOrder.ReceiveName = receiveAddress.ConsigneeName + makeOrder.ReceivePhone = receiveAddress.ConsigneeMobile + otherId, err := createOtherOrder(makeOrder) if err != nil { return err } - order.OrderStatus = model.PayStatusYes + 3 // 支付成功 + //order.OrderStatus = model.OrderStatusSuccessPay // 支付成功 + order.OtherWayBill = otherId + order.OrderStatus = model.OrderStatusWaitPickup + order.UpdatedAt = time.Now() + if _, err = dao.UpdateEntity(dao.GetDB(), order, "UserId", "LocalWayBill"); err != nil { + return err + } + return nil +} + +// RefundOrderByTL 发起取消订单 +func RefundOrderByTL(ctx *jxcontext.Context, orderPay *model.Order, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) { + result, err := api.TLpayAPI.PayRefund(&tonglianpayapi.PayRefundParam{ + Trxamt: refundFee, + Reqsn: utils.GetUUID(), + Remark: refundDesc, + OldTrxID: orderPay.TransactionID, + }) + if err == nil { + orderPayRefund = &model.OrderPayRefund{ + RefundID: refundID, + VendorRefundID: result.TrxID, + VendorOrderID: orderPay.OrderID, //本地生成Id + Status: model.RefundStatusNo, + TransactionID: orderPay.TransactionID, // 支付事务id + RefundFee: refundFee, + RefundCreatedAt: time.Now(), + } + dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName()) + db := dao.GetDB() + if result.TrxStatus == tonglianpayapi.TrxStatusSuccess { + orderPayRefund.Status = model.RefundStatusYes + } else { + orderPayRefund.Status = model.RefundStatusFailed + } + orderPayRefund.OriginalData = utils.Format4Output(result, true) + dao.CreateEntity(db, orderPayRefund) + + //orderPay.Status = model.OrderStatusCancel + //dao.UpdateEntity(db, orderPay) + + } + return orderPayRefund, err +} + +// ManagerGetOrderList 管理系统查询订单列表 +func ManagerGetOrderList(param *model.OrderListReq) ([]*model.UserVendorOrder, error) { + sql := `SELECT * FROM user_vendor_order uo WHERE 1=1 ` + paramSql := make([]interface{}, 0, 0) + + result := make([]*model.UserVendorOrder, 0, 0) + if param.OrderNo != "" { + sql += `AND (uo.local_way_bill = ? OR uo.other_way_bill = ? )` + paramSql = append(paramSql, param.OrderNo, param.OrderNo) + if err := dao.GetRows(dao.GetDB(), result, sql, paramSql...); err != nil { + return nil, err + } + return result, nil + } + + if param.StartTime.IsZero() && param.EndTime.IsZero() { + sql += `AND ou.created_at >= ? AND ou.created_at <= ? ` + paramSql = append(paramSql, param.StartTime, param.EndTime) + } + if param.ExpressType != 0 { + sql += `AND ou.type = ? ` + paramSql = append(paramSql, param.ExpressType) + } + if param.OrderStatus != 0 { + sql += `AND ou.order_status = ? ` + paramSql = append(paramSql, param.OrderStatus) + } + if param.PageNum == 0 { + param.PageNum = 1 + } + if param.PageSize == 0 { + param.PageSize = 10 + } + sql += ` ORDER BY uo.created_at DESC LIMIT ? OFFSET ? ` + paramSql = append(paramSql, param.PageSize, (param.PageNum-1)*param.PageSize) + if err := dao.GetRows(dao.GetDB(), result, sql, paramSql...); err != nil { + return nil, err + } + return result, nil } diff --git a/controllers/q_bida.go b/controllers/q_bida.go index fb2f5634f..28dfd943b 100644 --- a/controllers/q_bida.go +++ b/controllers/q_bida.go @@ -1,6 +1,7 @@ package controllers import ( + "fmt" bida "git.rosy.net.cn/baseapi/platformapi/q_bida" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/model" @@ -32,6 +33,7 @@ type QBiDaExpressController struct { // @router /QueryExpressPrice [post] func (c *QBiDaExpressController) QueryExpressPrice() { c.callQueryExpressPrice(func(params *tExpressQueryExpressPriceParams) (interface{}, string, error) { + fmt.Println("================", params.MapData) param := &bida.GetExpressPriceReq{ PromiseTimeType: params.PromiseTimeType, DeliveryType: params.DeliveryType, @@ -54,8 +56,8 @@ func (c *QBiDaExpressController) QueryExpressPrice() { // @Title Q必达 // @Description 下单 // @Param token header string true "管理员token" -// @Param promiseTimeType formData int true "快递时效产品" -// @Param deliveryType formData int true "产品类型" +// @Param promiseTimeType formData int false "快递时效产品" +// @Param deliveryType formData int false "产品类型" // @Param goods formData string true "商品名称" // @Param guaranteeValueAmount formData float64 false "保价金额" // @Param weight formData int true "重量kg" @@ -145,7 +147,7 @@ func (c *QBiDaExpressController) CancelWayVendorOrder() { Type: params.Type, } - if err := bidaServer.CancelWayOrder(cancel); err != nil { + if err := bidaServer.CancelWayOrder(params.Ctx, params.Ctx.GetUserID(), cancel); err != nil { return nil, "", err } return nil, "", nil @@ -191,3 +193,33 @@ func (c *QBiDaExpressController) GetOrderDetail() { return result, "", nil }) } + +// GetOrderList 管理系统获取订单详情 +// @Title Q必达 +// @Description 管理系统获取订单详情 +// @Param token header string true "管理员token" +// @Param expressType formData int false "就是type快递公司" +// @Param orderNo formData string false "订单Id,三方Id" +// @Param orderStatus formData int false "订单状态" +// @Param pageNum formData int true "页码" +// @Param pageSize formData int true "页数" +// @Param startTime formData string true "开始时间" +// @Param endTime formData string true "结束时间" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetOrderList [post] +func (c *QBiDaExpressController) GetOrderList() { + c.callGetOrderList(func(params *tExpressGetOrderListParams) (interface{}, string, error) { + listParam := &model.OrderListReq{ + ExpressType: params.ExpressType, + OrderNo: params.OrderNo, + OrderStatus: params.OrderStatus, + PageNum: params.PageNum, + PageSize: params.PageSize, + StartTime: utils.Str2Time(params.StartTime), + EndTime: utils.Str2Time(params.EndTime), + } + result, err := bidaServer.ManagerGetOrderList(listParam) + return result, "", err + }) +} diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index 95a7627f8..4ca7f7fb8 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -11,44 +11,45 @@ func Init() { // set default database orm.RegisterDataBase("default", "mysql", beego.AppConfig.String("dbConnectStr")) //orm.RegisterDataBase("api", "mysql", "root:WebServer@1@tcp(gold1.jxc4.com:3306)/api?charset=utf8mb4&loc=Local&parseTime=true") - if beego.BConfig.RunMode == "rsm" { - //用户 - orm.RegisterModel(&model.AuthBind{}, &model.User{}) - orm.RegisterModel(&model.UserMember{}) - orm.RegisterModel(&model.UserDeliveryAddress{}) - orm.RegisterModel(&model.UserCityManager{}) - orm.RegisterModel(&model.UserSearch{}) - orm.RegisterModel(&model.UserUnionBind{}) //联盟相关绑定 - orm.RegisterModel(&model.UserUnionBindImg{}) //多个活动图片 - //账单 - orm.RegisterModel(&model.UserBill{}, &model.BillIncome{}, &model.BillExpend{}) - //支付订单 - orm.RegisterModel(&model.Order{}) - orm.RegisterModel(&model.DeliveryOrder{}) - //联盟订单 - orm.RegisterModel(&model.UnionOrder{}) - orm.RegisterModel(&model.UnionOrderStatus{}) - orm.RegisterModel(&model.UnionOrderSettle{}) //订单结算 - //任务 - orm.RegisterModel(&model.Job{}, &model.JobCategory{}, &model.JobStep{}, &model.JobImg{}) - orm.RegisterModel(&model.JobOrder{}) - orm.RegisterModel(&model.JobTimer{}) - orm.RegisterModel(&model.JobSpan{}) - //聊天 - orm.RegisterModel(&model.ImMessageRecord{}, &model.MessageGroup{}, &model.MessageGroupMember{}) - orm.RegisterModel(&model.MessageGroupRead{}) + //if beego.BConfig.RunMode == "rsm" { + //用户 + orm.RegisterModel(&model.AuthBind{}, &model.User{}) + orm.RegisterModel(&model.UserMember{}) + orm.RegisterModel(&model.UserDeliveryAddress{}) + orm.RegisterModel(&model.UserCityManager{}) + orm.RegisterModel(&model.UserSearch{}) + orm.RegisterModel(&model.UserUnionBind{}) //联盟相关绑定 + orm.RegisterModel(&model.UserUnionBindImg{}) //多个活动图片 + //账单 + orm.RegisterModel(&model.UserBill{}, &model.BillIncome{}, &model.BillExpend{}) + //支付订单 + orm.RegisterModel(&model.Order{}) + orm.RegisterModel(&model.DeliveryOrder{}) + //联盟订单 + orm.RegisterModel(&model.UnionOrder{}) + orm.RegisterModel(&model.UnionOrderStatus{}) + orm.RegisterModel(&model.UnionOrderSettle{}) //订单结算 + //任务 + orm.RegisterModel(&model.Job{}, &model.JobCategory{}, &model.JobStep{}, &model.JobImg{}) + orm.RegisterModel(&model.JobOrder{}) + orm.RegisterModel(&model.JobTimer{}) + orm.RegisterModel(&model.JobSpan{}) + //聊天 + orm.RegisterModel(&model.ImMessageRecord{}, &model.MessageGroup{}, &model.MessageGroupMember{}) + orm.RegisterModel(&model.MessageGroupRead{}) - orm.RegisterModel(&model.Place{}, &model.StationInfo{}) - orm.RegisterModel(&model.OperateEventDetail{}) - orm.RegisterModel(&model.MtMember{}) - orm.RegisterModel(&model.OperateEvent{}) - orm.RegisterModel(&model.NewConfig{}, &legacymodel.Config{}) - orm.RegisterModel(&model.AddressDistinguish{}) - orm.RegisterModel(&model.VendorMatterCategory{}) //平台物流分类(手动添的) + orm.RegisterModel(&model.Place{}, &model.StationInfo{}) + orm.RegisterModel(&model.OperateEventDetail{}) + orm.RegisterModel(&model.MtMember{}) + orm.RegisterModel(&model.OperateEvent{}) + orm.RegisterModel(&model.NewConfig{}, &legacymodel.Config{}) + orm.RegisterModel(&model.AddressDistinguish{}) + orm.RegisterModel(&model.VendorMatterCategory{}) //平台物流分类(手动添的) + orm.RegisterModel(&model.OrderPayRefund{}) // 退款表 - // 物流订单 - orm.RegisterModel(&model.UserVendorOrder{}) - } + // 物流订单 + orm.RegisterModel(&model.UserVendorOrder{}) + //} //打印机 orm.RegisterModel(&model.PrintMsg{}) diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index d13914d97..7f569dd11 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1060,4 +1060,13 @@ func init() { MethodParams: param.Make(), Filters: nil, Params: nil}) + // 管理系统获取订单详情 + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:QBiDaExpressController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:QBiDaExpressController"], + beego.ControllerComments{ + Method: "GetOrderList", + Router: "/GetOrderList", + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) }