Files
jx-callback/business/q_bida/q_bida_server.go
2022-06-29 15:59:47 +08:00

390 lines
13 KiB
Go
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package q_bida
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"
"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"
"time"
)
// QueryExpressPrice 查询配送价格,获取所有快递价格
func QueryExpressPrice(param *bida.GetExpressPriceReq) (map[string]*bida.GetExpressPriceRes, error) {
if param.Weight <= 0 {
return nil, errors.New("物品重量必须大于0")
}
result := make(map[string]*bida.GetExpressPriceRes, 0)
if param.Type == 0 {
// 渠道费每公斤加价两毛
for i := 1; i <= 14; i++ {
param.Type = i
fee, err := api.QBiDaAPI.GetExpressPrice(param)
if err != nil {
return nil, err
}
if fee.Code != 0 {
result[fmt.Sprintf("%d", i)] = fee
continue
}
if fee.Data.ChannelFee != 0 {
addFee := fee.Data.ChannelFee + utils.Int2Float64(param.Width*2)
fee.Data.ChannelFee = addFee
result[fmt.Sprintf("%d", i)] = fee
}
}
} else {
fee, err := api.QBiDaAPI.GetExpressPrice(param)
if err != nil {
return nil, err
}
if fee.Code != 0 {
// result[fmt.Sprintf("%d", param.Type)] = fee
return nil, errors.New(fee.Msg)
}
if fee.Data.ChannelFee != 0 {
addFee := fee.Data.ChannelFee + utils.Int2Float64(param.Width*2)
fee.Data.ChannelFee = addFee
result[fmt.Sprintf("%d", param.Type)] = fee
}
}
return result, nil
}
// CreateWayOrder 创建快递订单
func CreateWayOrder(ctx *jxcontext.Context, param *model.MakeOrderParamReq, userId string) error {
// 检查价格
reallyCannelleFee := param.ChannelFee
if err := checkWayFeeIsTrue(param); err != nil {
return err
}
// 第三方数据创建成功,则创建本地数据
vendorOrder := &model.UserVendorOrder{
UserId: userId,
LocalWayBill: utils.Int64ToStr(time.Now().Unix()) + userId[:4], // 当前时间秒数加用户ID前四位
OtherWayBill: utils.Int64ToStr(time.Now().Unix()) + userId[:4],
PromiseTimeType: param.PromiseTimeType,
DeliveryType: param.DeliveryType,
Goods: param.Goods,
GuaranteeValueAmount: param.GuaranteeValueAmount,
Weight: param.Weight,
Length: param.Length,
Height: param.Height,
Width: param.Width,
OrderSendTime: param.OrderSendTime,
PackageNum: param.PackageNum,
ReceiveAddressID: param.ReceiveAddressId,
Remark: param.Remark,
SenderAddressID: param.SenderAddressId,
ThirdPlatform: param.ThirdPlatform,
Type: param.Type,
ReallyChannelFee: reallyCannelleFee,
ChannelFee: param.ChannelFee,
ServiceCharge: param.ServiceCharge,
GuarantFee: param.GuarantFee,
OriginalFee: param.OriginalFee,
Bulk: param.Bulk,
Increment: param.Increment,
ChannelType: param.ChannelType,
OrderStatus: model.OrderStatusWaitPay, // 创建待支付
Img: param.Images,
IsForward: model.YES, //
}
// 事务创建待支付运单和待支付order
db := dao.GetDB()
tdb, _ := dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db, tdb)
panic(r)
}
}()
// 添加运单表
dao.WrapAddIDCULEntity(vendorOrder, ctx.GetUserName())
if err := dao.CreateEntity(db, vendorOrder); err != nil {
dao.Rollback(db, tdb)
return err
}
// 添加待支付订单表
orderPayStatus := &model.Order{
OrderID: vendorOrder.LocalWayBill,
UserID: vendorOrder.UserId,
Type: model.OrderTypePay,
OrderType: model.PayType4Express,
Way: "",
Status: model.OrderStatusWaitPay, // 待支付状态
PayPrice: int(vendorOrder.ChannelFee * 100),
TransactionID: "",
PayFinishedAt: time.Time{},
PrepayID: "",
OriginalData: "",
Comment: "",
Lng: 0,
Lat: 0,
CityCode: 0,
DistrictCode: 0,
Address: "",
PayMethod: 0,
}
if err := dao.CreateEntity(db, orderPayStatus); err != nil {
dao.Rollback(db, tdb)
return err
}
dao.Commit(db, tdb)
return nil
}
// CancelWayOrder 取消运单 todo
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
}
// QueryOrderDetail 获取订单详细信息
func QueryOrderDetail(typeCode int, orderNo string) (*bida.OrderDetail, error) {
detail, err := api.QBiDaAPI.GetOrderDetail(&bida.GetOrderDetailReq{
Type: typeCode,
OrderNo: orderNo,
})
if err != nil {
return nil, err
}
// 本地查询获取真是支付快递费用
sql := `SELECT * FROM user_vendor_order a WHERE a.other_way_bill = ? and a.type = ? `
data := &model.UserVendorOrder{}
param := []interface{}{orderNo, typeCode}
if err := dao.GetRow(dao.GetDB(), data, sql, param); err != nil {
return nil, err
}
detail.ExpressFee = utils.Float64ToStr(data.ChannelFee)
return detail, nil
}
// QueryUserOrderList 查询用户订单列表
func QueryUserOrderList(userId string, expressType, orderStatus int, pageNum, pageSize int) ([]*model.UserOrderList, error) {
sql := `
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,
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 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)
param = append(param, userId)
if expressType != 0 {
sql = sql + ` a.type = ? `
param = append(param, expressType)
}
if orderStatus != 0 {
sql = sql + ` a.order_status = ? `
param = append(param, orderStatus)
}
sql = sql + ` ORDER BY a.create_at DESC LIMIT ? OFFSET ? `
pageSize = jxutils.FormalizePageSize(pageSize)
param = append(param, pageSize, (pageNum-1)*pageSize)
// 获取数据
result := make([]*model.UserOrderList, 0, 0)
if err := dao.GetRows(dao.GetDB(), result, sql, param...); err != nil {
return nil, err
}
return result, nil
}
// CreateOrder2QBiDa 订单回调成功,且为运费支付时使用该接口
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 err
}
// 创建QBIDA订单
makeOrder := &bida.MakeOrderReq{
PromiseTimeType: order.PromiseTimeType,
DeliveryType: order.DeliveryType,
Goods: order.Goods,
GuaranteeValueAmount: order.GuaranteeValueAmount,
Weight: order.Weight,
Length: order.Length,
Height: order.Height,
Width: order.Width,
OrderSendTime: order.OrderSendTime,
PackageNum: order.PackageNum,
Remark: order.Remark,
ThirdPlatform: order.ThirdPlatform,
Type: order.Type,
Img: order.Img,
}
// 获取发货地址以及送货地址
// 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.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
}