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 { continue } fmt.Println("原价:", fee.Data.TypeName, fee.Data.Type, fee.Data.ChannelFee) if fee.Code != 0 { result[fmt.Sprintf("%d", i)] = fee continue } if fee.Data.ChannelFee != 0 { addFee := int(fee.Data.ChannelFee*100) + param.Weight*20 fee.Data.ChannelFee = utils.Int2Float64(addFee) / float64(100) result[fmt.Sprintf("%d", i)] = fee fmt.Println("加价:", fee.Data.TypeName, fee.Data.Type, fee.Data.ChannelFee) } } } 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) } fmt.Println("原价:", fee.Data.TypeName, fee.Data.Type, fee.Data.ChannelFee) if fee.Data.ChannelFee != 0 { addFee := int(fee.Data.ChannelFee*100) + param.Weight*20 fee.Data.ChannelFee = utils.Int2Float64(addFee) / float64(100) result[fmt.Sprintf("%d", param.Type)] = fee fmt.Println("加价:", fee.Data.TypeName, fee.Data.Type, fee.Data.ChannelFee) } } return result, nil } // CreateWayOrder 创建快递订单 func CreateWayOrder(ctx *jxcontext.Context, param *model.MakeOrderParamReq, userId string) (*model.UserVendorOrder, error) { // 检查价格 reallyCannelleFee := param.ChannelFee if err := checkWayFeeIsTrue(param); err != nil { return nil, 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 nil, 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 nil, err } dao.Commit(db, tdb) return vendorOrder, 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, orderNo string) ([]*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.created_at,a.order_status,a.channel_fee,add1.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 add1 ON a.sender_address_id = add1.id LEFT JOIN user_delivery_address add2 ON a.receive_address_id = add2.id LEFT JOIN place district ON district.code = add1.city_code LEFT JOIN place city ON city.code = add2.city_code WHERE a.user_id = ? ` param := make([]interface{}, 0, 0) param = append(param, userId) if orderNo != "" { sql = sql + `AND a.other_way_bill = ? OR a.local_way_bill = ? ` param = append(param, orderNo, orderNo) } if expressType != 0 { sql = sql + ` AND a.type = ? ` param = append(param, expressType) } if orderStatus != 0 { sql = sql + ` AND a.order_status = ? ` param = append(param, orderStatus) } sql = sql + ` ORDER BY a.created_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 }