物流笑嘻嘻

This commit is contained in:
邹宗楠
2022-06-29 15:59:47 +08:00
parent 301a430666
commit 4e5246cbda
12 changed files with 509 additions and 308 deletions

View File

@@ -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)

View File

@@ -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,

View File

@@ -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
//}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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"` // 支付完成时间

View File

@@ -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"},
}
}

View File

@@ -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"` // 结束时间
}

View File

@@ -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
}

View File

@@ -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
})
}

View File

@@ -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{})

View File

@@ -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})
}